概述
MySQL 的高可用主要通过主从复制来实现,同时在主从复制的基础上可以构建一个 MySQL 集群,来实现 MySQL 的读写分离,以实现 MySQL 的高并发操作
MySQL 主从复制主要解决的问题:
- 数据热备:可以实时将主库的数据通过复制的方式备份到另外一个从库中,如果主库发生意外,数据丢失,则可以使用从库的数据提供服务
- 读写分离:对于更新频繁的表,由于 MySQL 更新数据时需要锁表,所以当有其他更新语句或者数据读取语句到来时就需要等待锁,性能低下。这时可以将写操作都在主库上执行,数据的查询操作在从库上执行,降低主库压力
- 负载均衡:可以将数据以副本的形式复制到其他多个数据库上,将数据查询请求负载均衡到其他多个数据库上,避免单库数据过多,压力过大
- 高可用:可以以双主复制的方式实现数据相互备份,在一个数据库发生故障后可立即切换到另一个数据库上
复制类型
- STATEMENT:把主数据库执行的 sql 复制到从数据库,是默认类型
- ROW:直接把数据行复制过去
- MIXED:默认复制 sql 语句,如果发现无法精确复制,就会复制行数据
工作过程
- 主库数据更新,写入二进制日志文件
- 从库监听到主库的二进制日志文件发生改变,开启 I/O 线程向主库请求二进制日志记录;
- 主库为每个 I/O 线程开启 dump 线程,向从库发送二进制日志记录
- 从库的 I/O 线程将主库的二进制日志记录保存到本地的中继日志
- 从库启动 SQL 线程从中继日志读取二进制日志记录,在本地重新执行,使数据和主库保持一致
- I/O 线程和 SQL 线程进入睡眠状态,等待下一次被唤醒
同步类型
- 异步复制:主库执行完事务,立即将结果返回客户端,并不关心从库是否已经接收并处理。此时如果主库挂掉,而从库又未完成同步,会导致数据不一致,MySQL 默认采用此类型
- 全同步复制:主库执行完事务,所有的从库也都执行了该事务,完成数据同步,才将结果返回客户端,性能会收到一定影响
- 半同步复制:在异步复制的基础上,确保主库返回结果前,至少有一个从库已经收到该事务并记录到中继日志,但并不保证执行
主从复制的模式
一主一从模式:一个主库对应一个从库,主库的数据实时同步到从库。一般线上都以一主一从模式为主,客户端的读写都在主库上,从库用于数据备份。有时为了减小主库的压力,可以将部分对数据实时性要求不高的读操作在从库上执行。当主库出现故障时,需要手动将从库切换为主库对外提供服务
双主模式:两个库都是主库,这两个主库日志互备。假设两个库分别为 A 和 B,则在 A 库上变更的数据会实时同步到 B 库,在 B 库上变更的数据也会实时同步到 A 库,两个库对外提供的读写能力和数据的一致性都是对等的。在任何一个库发生故障后,另一个库仍然能继续为客户端提供读写服务
一主多从:一个主库,多个从库,通常通过多个从库来缓解高并发查询的压力
多主一从:一个备库从多个主库上同步数据,一般用于将多个节点的数据进行汇总分析
级联复制:主库先将数据同步到一个从库,再将该从库的数据同步到其他多个从库。它的好处是如果有很多从库从主库同步数据,则会增加主库的压力,可能会影响数据插入效率。可以先将主库的数据同步到一个从库,再通过该从库将数据进行多副本备份,降低主库的压力,同时某个从库的数据同步出错也不会影响整个集群的使用
MySQL 双主模式的循环复制问题指的是 A 库上执行更新,会同步到 B 库,B 库在同步完成后,也会同步给 A 库,这时会造成循环复制。MySQL 通过 server-id 解决循环复制问题:
- 业务逻辑在 A 库执行更新,会生成带有 A 库的 server-id 的 binary-log
- B 库在接收到 A 库发过来的 binary-log 并执行完成后,也会生成带有 A 库的 server-id 的 binary-log
- A 库在接收到 binary-log 后,如果发现 server-id 是自己的则丢掉,此次的数据变更同步完成