MySQL主从全同步复制不能做到强一致;原生semi-sync仅保证relay log落盘,不保证执行与可见性,强一致需MGR或Galera等共识协议方案。

MySQL主从全同步复制到底能不能做到强一致
不能。原生 MySQL 的 semi-sync replication 不是全同步,只是“至少一个从库收到并写入 relay log 后主库才返回成功”,不保证已执行、不保证数据可见,更不保证事务原子性跨节点生效。真要强一致,必须用 Group Replication(MGR)或 Galera Cluster 这类基于共识协议的方案。
为什么 semi-sync 不等于强一致
常见错误现象:开了 rpl_semi_sync_master_enabled=ON 和 rpl_semi_sync_slave_enabled=ON,但主库 crash 后从库仍丢事务——因为 semi-sync 只确认“接收并落盘 relay log”,没等 apply 完成。主库提交返回成功时,从库可能还在解析 SQL、甚至还没开始执行。
-
semi_sync_timeout超时后自动退化为异步,配置里不显式处理就等于没开 - 从库
relay_log_recovery=OFF时,重启后可能跳过未 apply 的 relay 日志 - 主库 binlog 写入和 semi-sync 确认之间存在微小窗口,崩溃在此刻发生就会丢失
- MGR 的
group_replication_consistency=AFTER或BEFORE_AND_AFTER才真正阻塞提交直到多数派确认执行完成
用 MGR 搭建最小可行强一致集群
场景:3 节点集群,要求任意单点故障不丢事务、读写都看到一致状态。关键不是加参数,而是理解哪些配置动了会直接破坏一致性边界。
- 必须设
group_replication_group_name为合法 UUID,否则节点拒绝加入 -
group_replication_start_on_boot=OFF—— 启动时不自动启 group,避免因网络未就绪导致脑裂 -
group_replication_consistency=AFTER是底线,需要强读写顺序时改BEFORE_AND_AFTER,但会明显拖慢写入 - 不要混用
binlog_format=STATEMENT,MGR 强制要求ROW - 示例启动命令:
START GROUP_REPLICATION;
,不是START SLAVE,后者会报错
强一致代价在哪,什么情况下其实没必要
性能损耗真实存在:MGR 写入延迟通常比半同步高 2–5 倍,尤其跨机房部署时 RTT 放大效应明显。很多所谓“强一致需求”,实际只是怕主从延迟导致业务查到旧数据,这种完全可以用 read-after-write consistency 策略在应用层兜底,比如把刚写入的记录 ID 带上,后续读强制打到主库或加 SELECT ... FOR UPDATE 触发主库读。
最容易被忽略的一点:即使上了 MGR,如果应用没关掉 auto-commit、没正确处理 ER_GROUP_REPLICATION_CONSISTENCY_ERROR 错误,或者把事务拆太碎(每个 update 都单独 commit),强一致机制根本起不到作用。










