深入理解MySQL主从同步

814 阅读9分钟

1. 什么是 MySQL 主从同步

主从同步,又称为主从复制,(MySQL官方称为Replication),是指将数据从一台数据库服务器同步到多台数据库服务器。可以在单点服务的基础上扩充数据库的高可用性、可扩展性。

2. 主从同步的作用

主从同步作用如下:

  • 读写分离
  • 数据备份
  • 高可用性

2.1 读写分离

当主库压力较大时,可以将读请求转发到从库上,从而减少对主库的压力。

2.2 数据备份

主库数据冗余存储在从库节点上,减少数据丢失的风险。

2.3 高可用性

当主库出现故障、宕机时,可以快速切换到某一个从库,并将该从库提升为主库,因为数据都一样,所以不会影响系统的运行。

3. 主从同步架构

常见的主从同步架构有一主多从、双主多从。

image.png

一主多从架构:一般是主库负责所有读写请求,而从库只负责容灾恢复和冗余备份。如果做了读写分离的话,主库负责写请求,从库负责读请求,可以提升数据库性能。

双主多从架构:一般是主库1负责所有读写请求,主库2不对外提供服务,只用来容灾恢复。相比一主多从架构,双主多从架构可以减少宕机时间,更快恢复数据库可用状态。

但是双主多从运维成本更高,目前业内更多使用的是一主多从架构。

4. 主从同步原理

4.1主从同步流程

这里以MySQL默认的异步复制模式进行介绍

  1. slave 节点连接到 master 节点上,向master 节点发起 dump 请求。
  2. master 节点为每一个 sale 节点分别创建一个binlog dump 线程,用于向各个 slave 节点发送 binlog日志。
  3. salve 节点 I/O 线程把 binlog 内容写入本地的 Relay Log 文件中。
  4. Salve节点的SQL 线程读取 Relay Log 文件内容,将其解析成具体的增删改操作,重新在 slave 节点上也重做一遍。

从节点如何避免重复处理主节点数据:主节点生成bin log之前会产生一个GTID(global transactionId 全局id),并将该GTID一起写入bin log。bin log同步到从节点的rely log时也会将GTID同步过去,从节点会记录已经处理过的GTID,对于重复的不会处理。

4.2 Binlog

主从同步依赖于 binlog 的row格式进行数据同步。binlog有三种格式:

  • Statement:基于语句格式 。对应的就是主库执行的SQL语句。
  • Row:基于行格式。对应的就是主库具体行变化记录。(before__xx: before_value, xx: after_value)
  • Mixed:基于混合语句和行格式。在statement和row之间选择一种。

基于row格式的binlog的主从复制,其准确性和可靠性都是要强于statement格式的,同时这种格式下的Binlog的提供了完整的数据变更信息,可以使其应用不被局限在MySQL集群系统内,例如做binlog同步ES,binlog同步RocketMQ等。

4.3Relay log

Relay log在本质上可以认为和binlog是等同的日志文件。

Relay log的出现是为了让从库中原本的获取binlog、重放binlog解耦了,两个步骤可以异步的进行。Relay Log充当了缓冲区的作用。同时Relay Log中记录了当前复制的进度。

5. 主从同步的方式

主从同步方式分为:

  • 异步复制(默认)
  • 半同步复制
  • 全同步复制

5.1异步复制

image.png

异步复制,就是主库写完 Binlog 文件后,此时主库只会通知一下 Dump 线程发送这些新的 Binlog,然后主库就会提交commit。至于这些Binlog会不会成功发送到从库主库完全不care。

优点:异步复制性能最高。

缺点:主从数据不一致。如果主库突然挂掉从库切主后数据不完整。

5.2半同步复制

MySQL5.5 版本之后开始支持半同步复制的方式。其原理为:

客户端提交 COMMIT之后不直接将结果返回给客户端,而是等待至少有一个从库(参数可配置)收到了 Binlog,并且写入到中继日志中,再返回给客户端。

image.png

优点:提高主从之间的数据一致性。

缺点:

  • SQL响应时间增大
  • 存在幻读问题

解释下这里的幻读问题。当主库执行commit之后,虽然没有返回响应给客户端,但是其他客户端已经能够从主库上查到这次数据变更记录。但是此时从库可能还没有收到该binlog,如果此时发生切主操作,则无法再读取到该变更记录。

5.3增强半同步复制

增强半同步复制是 mysql 5.7.2 后的版本对半同步复制做的一个改进,原理上几乎是一样的,主要是解决幻读的问题。

MySQL 增加了 rpl_semi_sync_master_wait_point参数:

  • AFTER_COMMIT:主库在提交事务之后,等待接收到从库ACK之后再返回给客户端,这里其实就是上面的半同步复制。
  • AFTER_SYNC(默认值):主库在接收到从库的ACK之后再提交事务。该选项可以解决幻读问题。

下图以AFTER_SYNC为例:

image.png 优点:

  • 相比于异步复制,提升了主从的数据一致性。
  • 相比于普通的同步复制,解决了幻读问题。

缺点:

  • 相比于异步复制,sql响应时长增大。

5.4全同步复制

全同步复制,就是当主库执行完一个事务之后,要求所有的从库也都必须执行完该事务,才可以返回处理结果给客户端。

image.png

全同步复制与半同步相比,主要区别如下:

  1. 半同步复制可以配置接收到从节点ack的个数,而全同步复制需要接收到所有的从节点。
  2. 半同步复制只需要从库写入relay log 就可以返回ack响应,而全同步复制需要从库执行完relay log 后才可以返回ack相应。

优点:主从数据一致性最强。

缺点:

  • 主从同步性能很差,因为要复制到所有节点才返回响应

  • 主从同步可用性很差,任何一个从库数据库出问题,主库将直接全部hang在提交事务那里。(MySQL中,事务超过配置时间仍然不提交最终会被rollback)

最后用一张表格来总结这4种同步方式的优缺点,并给出业务上选型建议。

同步方式主要原理优点缺点选型建议
异步复制主从提交事务与同步binlog到从库完全解耦性能最好数据一致性最差对于数据一致性要求不高的业务推荐使用
半同步复制主库提交事务后,等待接收到从库的ack之后再返回ack给客户端数据一致性更高主从不一致幻读性能差基本不使用
增强半同步主库收到从库至少一个ack之后再提交事务;从库只要写入relay log就可以返回数据一致性更高主从不一致性能差(一般会损失50%左右)对于数据一致性要求高的业务推荐使用,如金融业务
全同步复制主库收到全部从库ack之后在提交事务;从库需要执行完relay log再返回数据一致性最高性能最差基本不使用

摘自mysql官网:With fully synchronous replication, when a source commits a transaction, all replicas have also committed the transaction before the source returns to the session that performed the transaction. Fully synchronous replication means failover from the source to any replica is possible at any time. The drawback of fully synchronous replication is that there might be a lot of delay to complete a transaction. Semisynchronous replication falls between asynchronous and fully synchronous replication. The source waits until at least one replica has received and logged the events (the required number of replicas is configurable), and then commits the transaction. The source does not wait for all replicas to acknowledge receipt, and it requires only an acknowledgement from the replicas, not that the events have been fully executed and committed on the replica side. Semisynchronous replication therefore guarantees that if the source crashes, all the transactions that it has committed have been transmitted to at least one replica. Compared to asynchronous replication, semisynchronous replication provides improved data integrity, because when a commit returns successfully, it is known that the data exists in at least two places. Until a semisynchronous source receives acknowledgment from the required number of replicas, the transaction is on hold and not committed.

6.主从同步延迟原因以及解决方案

6.1主从同步延迟原因

与数据同步有关的时间点主要包括以下三个:

  1. 主库 A 执行完成一个事务,写入 binlog,我们把这个时刻记为 T1。
  2. 之后传给备库 B,我们把备库 B 接收完这个 binlog 的时刻记为 T2.
  3. 备库 B 执行完成这个事务,我们把这个时刻记为 T3。

所谓主从延迟,就是同一个事务,在备库执行完成的时间和主库完成的时间(binlog 里面有一个时间字段记录主库的写入时间)的差值,也就是 T3-T1。

对应上面的时间点,可以得到主从同步延迟的原因:

  1. 网络延迟:当主库的 Bin Log 文件往从库上发送时,可能产生网络延迟。
  2. 从库机器的性能较差:主库负责所有读写请求,从库只用来备份,会用性能较差的机器,执行时间自然较慢。
  3. 从库压力更大:读写分离后,主库负责写请求,从库负责读请求。互联网应用一般读请求更多,所以从库读压力更大,占用更多 CPU 资源
  4. 主库有大事务:当主库上有个大事务需要执行 5 分钟,把 Bin Log 文件发送到从库,从库至少也需要执行 5 分钟,所以这时候从库就出现了 5 分钟的延迟。

6.2 主从同步延迟的解决方案?

  1. 网络延迟:联系运维或者云服务提供商解决。
  2. 从库机器性能较差: 把从库换成跟主库同等规格的机器。
  3. 从库压力更大:多搞几台从库,分担读请求压力。
  4. 主库有大事务:把大事务分割成小事务执行,大事务不但会产生从库延迟,还可能产生死锁,降低数据库并发性能,所以尽量少用大事务。

7. 参考资料