几句话概括,MySQL 半同步中,after_commit 与 after_sync 有什么区别
MySQL 半同步的 after_sync 和 after_commit 差别就是:主库在事务提交链路的哪个位置等待从库 ACK。AFTER_SYNC:
- 主库 prepare 事务
- 写 binlog,并 fsync 到磁盘
- 把 binlog event 发给从库
- 等至少一个半同步从库确认:已写入并刷盘 relay log
- 主库再 commit 到存储引擎
- 返回客户端成功
特点:更安全。客户端看到 commit 成功时,事务已经至少存在于主库和一个从库的持久化日志中。并且在 ACK 前事务还没在主库存储引擎提交,所以其他客户端也看不到这个事务。MySQL 5.7 文档里 AFTER_SYNC 是默认值。
AFTER_COMMIT:
- 主库 prepare 事务
- 写 binlog,并 fsync 到磁盘
- 主库先 commit 到存储引擎
- 再等待从库 ACK
- 收到 ACK 后返回客户端成功
特点:风险窗口更大。事务已经在主库提交后,才等从库 ACK;所以在“主库已提交但从库还没 ACK”的窗口里,其他客户端可能已经读到这笔数据。如果此时主库崩溃并切到一个没收到该事务的从库,就可能出现“别的客户端曾经看到过的数据,在新主上没了”。
一句话记忆:
- AFTER_SYNC:先等从库收到并刷盘,再主库提交,更偏一致性/无损切换。
- AFTER_COMMIT:主库先提交,再等从库收到并刷盘,可见性更早,但故障切换风险更高。
注意:半同步的 ACK 只表示从库已经把事务事件写入并刷盘到 relay log,不表示从库已经执行并提交了这个事务。参考 MySQL 官方文档:
Semisynchronous Replication
