
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