阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MySQL5.7半同步复制之AFTER_SYNC/AFTER_COMMIT过程解析

127次阅读
没有评论

共计 2311 个字符,预计需要花费 6 分钟才能阅读完成。

MySQL 5.7 增强了半同步复制,rpl_semi_sync_master_wait_point 增加了 AFTER_SYNC 的值,由该参数 AFTER_SYNC/AFTER_COMMIT 两个值选择是否启用增强半同步。

mysql> SET rpl_semi_sync_master_wait_point= AFTER_SYNC;  开启了 mysql 5.7 增强半同步,5.7 默认就是开启的;
mysql> SET rpl_semi_sync_master_wait_point= AFTER_COMMIT;  5.6 的半同步方式;

当半同步模式为 AFTER_COMMIT 时:
过程分析如下:
        1 > session 发出 commit 请求
        2 > flush binlog and fsync binlog
        3 > InnoDB 引擎层 commit
        4 > 发送 binlog 到 SLAVE,等待 slave 发送 ack 确认
        5 > slave 接受 binlog 写入 relay log,刷盘完成发送 ack 确认包给 master
        6 > master 返回 commit ok 信息给 session
       
        另外 (master 等待事务 A 的 ACK 的时候宕机,此时新事务 B 在宕机之前开启):
        1> binlog 未发送到从库:
            事务 B 获取到事务 A 提交的内容,此时宕机故障切换到 slave,事务 B 获取到的内容却丢失了。事务 A commit 没有收到反馈信息 (则需要业务判断了)。
        2> binlog 已经发送给从库 :
            事务 B 获取到事务 A 提交的内容,故障切换到 salve,B 仍然获取到 A 提交的内容,没毛病。事务 A commit 没有收到反馈信息,若重新执行该事务,则相当于执行两次 A 事务 (则需要业务判断了)。

MySQL5.7 半同步复制之 AFTER_SYNC/AFTER_COMMIT 过程解析

当半同步模式为 AFTER_SYNC(5.7 版本推荐使用) 时:

过程分析如下:
          1 > session 发出 commit 请求
          2 > flush binlog and fsync binlog
            3 > 发送 binlog 到 SLAVE,等待 slave 发送 ack 确认
          4 > slave 接受 binlog 写入 relay log,刷盘完成发送 ack 确认包给 master
            5 > InnoDB 引擎层 commit
            6 > master 返回 commit ok 信息给 session

            另外 (master 等待事务 A 的 ACK 的时候宕机,此时新事务 B 在宕机之前开启):
          1> 事务 B 读取不到事务 A 的内容,因为事务 A 的 ENGINE 层还没有提交 (无损复制)

MySQL5.7 半同步复制之 AFTER_SYNC/AFTER_COMMIT 过程解析

dump thread 过程分析:
  mysql5.6 版本之前:
        1> master dump thread 发送 binlog events 给 slave 的 IO thread,等待 slave 的 ack 回包
        2> slave 接受 binlog events 写入 redo log,返回 ack 包给 master dump thread
        3> master dump thread 收到 ack 包,给 session 返回 commit ok,然后继续发送写一个事务的 binlog。

mysql5.7 之后新增 ack 线程:
        1> master dump thread 发送 binlog events 给 slave 的 IO thread,开启 ack 线程等待 slave 的 ack 回包,dump 线程继续向 slaveIO thread 发送下一个事务的 binlog。
        2> slave 接受 binlog events 写入 redo log,返回 ack 包给 master ack 线程,然后给 session 返回 commit ok。

过程总结:
Master 在收到 slave 的应答后才 Commit 事务 –after_sync(5.6 上 Master 在 commit 后,才等待 Slave 的应答 –after commit).
因此在确认事务复制到 Slave 上之前,并发的事务看不到当前事务的数据.
当 Master 出现故障时, 所有已经提交的事务都复制到了 Slave 上.
缺省采用无数据丢失的应答等待机制 after_sync。用户也可以选择使用 5.6 的应答等待机制 after_commit

设置方法:
mysql> SET rpl_semi_sync_master_wait_point= AFTER_SYNC;

 Master 接收到 N 个 slave 的应答后,才 commit 事务.
用户可以设置应答 Slave 的数量:
mysql> SET GLOBAL rpl_semi_sync_master_wait_for_slave_count= N;

总结:相对于 mysql 5.6 的 after_commit 方式,5.7 的 after_sync 的增强主要表现在保证了从库不会丢失数据,因为是 master fsync binlog 之后,也就是把 binlog 从 binlog cache 刷新到底层磁盘(binlog 文件),master 的 dump 进程就发送 binlog 给 slave,等 slave 的 ack 告诉 master 接收并刷盘成功,master 才进行 InnoDB 引擎层 commit,之后 master dump 线程继续向 slaveIO thread 发送下一个事务的 binlog, 而不用等到 master InnoDB 引擎层 commit 之后才发送,5.7 的这种增强保证了从库不会丢失数据;需要注意 innodb commit 的两阶段提交,最后一步才是 InnoDB 引擎层 commit,然后 InnoDB 引擎层 commit 之后,就认为是 commit 成功了,尽管还没有返回 commit ok 信息给 session,如果此时 crash, 那么启动后,实例恢复是需要借助 redo, 完成前滚;

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计2311字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中