引言
在 MySQL 的主从复制架构中,rpl_semi_sync_master_wait_point 参数控制着半同步复制(Semi-Synchronous Replication)的等待时机,其可选值为 AFTER_COMMIT 和 AFTER_SYNC。
这两个选项看似微小,却深刻影响着事务的持久性语义、数据一致性保障以及系统性能表现。自 MySQL 5.7 起默认采用 AFTER_SYNC,这一变更是对数据安全模型的重要演进。
MySQL 的半同步复制功能 不是内建默认开启的 ,而是通过 可加载插件(plugin) 实现的。只有在以下两个条件都满足时,相关系统变量(如 rpl_semi_sync_master_wait_point、rpl_semi_sync_master_enabled 等)才会出现在 SHOW VARIABLES 的输出中:
- 插件已安装 (通过
INSTALL PLUGIN或配置文件加载)(SHOW PLUGINS; 命令能查看到rpl_semi_sync_master插件) - MySQL 实例是主库(Master)角色
如果从未显式启用半同步复制,这些变量就根本不会注册到系统变量列表中,因此查询返回空集。
一、核心机制对比:AFTER COMMIT vs AFTER SYNC
1. 日志写入与事务提交流程
在 InnoDB + binlog 的两阶段提交(2PC)模型中,事务提交涉及以下关键步骤:
- Prepare 阶段:写入 redo log(状态为 PREPARE)
- Commit 阶段 :
- 写入 binlog
- 写入 redo log(状态为 COMMIT)
- 释放行锁、返回客户端成功
rpl_semi_sync_master_wait_point 决定了 何时通知从库"事务已可复制",进而触发主库是否等待 ACK。
2. AFTER COMMIT(旧模式)
- 主库在 完成自身事务提交(即 redo log 和 binlog 均落盘)后,才向从库发送 binlog。
- 半同步等待点位于 事务已对本地客户端可见之后。
- 若此时主库崩溃,而从库尚未收到 binlog,则可能出现 "幻读"或"数据丢失":客户端已收到成功响应,但备库无此事务。

3. AFTER SYNC(新模式,默认)
- 主库在 binlog 写入并 sync 到磁盘后、但尚未提交 InnoDB 事务前,就将 binlog 发送给从库。
- 半同步等待点位于 InnoDB commit 之前(在写入最终的 redo log (COMMIT record) 之前)。
- 只有在收到至少一个从库的 ACK ( Acknowledgement,确认应答)后,主库才完成 InnoDB 提交并向客户端返回成功。
- 此模式确保:若客户端收到成功,则该事务必定存在于至少两个节点(主+从),满足更强的一致性。

关键区别:AFTER SYNC 将"对外可见"延迟到半同步确认之后,而 AFTER COMMIT 先让本地事务生效再通知从库。
二、影响维度对比
| 维度 | AFTER COMMIT | AFTER SYNC |
|---|---|---|
| 事务持久性 | 仅保证主库本地持久(若主库 crash 且未同步到从库,数据可能丢失) | 保证"至少两副本"持久(主+至少一个从),更强 Durability |
| 主从一致性 | 可能出现主有从无(客户端已提交但从未收到) | 主从强一致(客户端成功 ⇨ 从库必有) |
| 性能开销 | 较低(提交快,等待在后台) | 略高(提交需等待网络 ACK) |
| 故障恢复行为 | 主库 crash 后,若 binlog 已写但未传从库,可能需人工干预 | 主从数据一致,自动 failover 更安全 |
| 适用场景 | 对性能极度敏感、容忍短暂不一致的场景 | 金融、支付、核心交易等强一致性要求场景 |
三、在半同步复制中的实际表现
-
AFTER COMMIT:
- 客户端可能看到"成功",但该事务未被任何从库接收。
- 若主库立即宕机,切换到从库会导致 数据丢失(称为 "phantom transaction" 问题)。
- 不符合 CAP (Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性))中的 CP 模型。
-
AFTER SYNC:
- 实现了 "无损半同步复制"(Lossless Semi-Sync Replication)。
- 即使主库宕机,已提交事务必然存在于某个从库,支持安全故障转移。
- 是 MySQL 5.7+ 默认值,也是现代高可用架构的推荐配置。
注意:即使使用
AFTER_SYNC,仍需配合sync_binlog=1和innodb_flush_log_at_trx_commit=1才能保证完整持久性。
四、配置建议与典型场景
推荐配置(强一致性场景):
ini
rpl_semi_sync_master_wait_point = AFTER_SYNC
rpl_semi_sync_master_enabled = ON
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
适用场景分析:
-
AFTER SYNC:
- 银行交易系统
- 订单/支付核心链路
- 要求 RPO ≈ 0 的业务
-
AFTER COMMIT(谨慎使用):
- 日志类、监控类非关键数据
- 性能优先、可接受秒级数据丢失的场景
- 旧系统兼容性需求(不推荐新项目使用)
五、面试题
-
Q:MySQL 半同步复制中 AFTER COMMIT 和 AFTER SYNC 的核心区别是什么?
A:AFTER COMMIT 在本地事务提交后才等待从库 ACK,可能导致主有从无;AFTER SYNC 在本地提交前等待 ACK,确保客户端成功时事务已在至少两个节点持久化。 -
Q:为什么 MySQL 5.7 将默认值从 AFTER COMMIT 改为 AFTER SYNC?
A:为解决"幻读事务"问题,提供无损半同步复制,增强数据安全性,避免主从切换时的数据丢失。 -
Q:使用 AFTER SYNC 是否一定能保证零数据丢失?
A :否。还需配合sync_binlog=1和innodb_flush_log_at_trx_commit=1,否则日志可能仅在 OS 缓存中,断电仍会丢失。 -
Q:AFTER SYNC 模式下,若从库全部宕机,主库会怎样?
A :主库会在等待超时(由rpl_semi_sync_master_timeout控制,默认 10 秒)后自动降级为异步复制,保证可用性。 -
Q:如何验证当前半同步复制的 wait point 设置?
A :执行SHOW VARIABLES LIKE 'rpl_semi_sync_master_wait_point';查看当前值。