半同步复制不保证强一致,仅确保事务被从库接收并缓存至relay log而非落盘;mgr基于paxos实现强一致但性能下降30%–50%;选型应基于容忍不一致能力与兜底方案,而非单纯追求一致性。

半同步复制为什么常被误认为“强一致”
MySQL 半同步复制(rpl_semi_sync_master_enabled=ON)并不保证事务在从库落盘,只保证至少一个从库接收并缓存到 relay log(未 apply)。这意味着主库提交成功后,若该从库崩溃且未刷盘,故障切换时可能丢失已确认的事务——它解决的是“不丢数据”的下限,而非“读写一致”的上限。
常见错误现象:SELECT 在主库写入后立刻查从库返回旧值,或主从切换后应用报主键冲突/数据不存在。这不是 bug,而是设计使然。
- 必须配合
sync_relay_log=1+relay_log_info_repository=TABLE才能降低 relay log 丢失风险 - 从库 crash 后重启,若 relay log 损坏但 master 已 purged binlog,复制会永久中断
-
rpl_semi_sync_master_timeout设置过短(如默认 10000ms)会导致频繁退化为异步,掩盖问题而非解决
全同步复制(Group Replication)的代价在哪
MySQL Group Replication(MGR)基于 Paxos 实现多节点写集认证,真正达成事务级强一致,但性能衰减明显。它不是“更快的半同步”,而是完全不同的协调模型。
典型瓶颈场景:高并发小事务(如订单创建)、跨地域部署、从库磁盘较慢。延迟不再由网络 RTT 主导,而由最慢节点的认证+apply 耗时决定。
- 单主模式下写入吞吐通常比单机下降 30%–50%,取决于
group_replication_consistency级别(AFTER最严也最慢) - 必须关闭
autocommit或显式用START TRANSACTION,否则每个语句单独认证,开销翻倍 - 从库不可写,且
SELECT默认路由到本节点;若需读扩展,必须手动分离连接池,不能依赖传统读写分离中间件
如何判断该选半同步还是 MGR
核心判断依据不是“要不要一致性”,而是“能否容忍短暂不一致 + 是否有配套兜底能力”。很多团队上 MGR 是因为怕丢数据,结果发现日志回溯、binlog 解析、应用层幂等这些更轻量的方案反而更可控。
- 业务允许秒级延迟 + 有完善的 binlog 消费链路(如 Canal + Kafka)→ 用半同步 +
ENFORCE_GTID_CONSISTENCY=ON - 跨机房部署且要求任意节点故障后数据零丢失 → 必须用 MGR,但需压测
group_replication_message_cache_size和网络 buffer - 已有中间件(如 MyCat、ShardingSphere)且无法改造 → 半同步是唯一现实选项,MGR 的 group communication port 和流量模型不兼容
最容易被忽略的配置陷阱
无论选哪种,innodb_flush_log_at_trx_commit=1 和 sync_binlog=1 必须同时开启,否则主库自身就可能丢事务——这是所有高可用架构的地基,却被大量线上环境关闭以“提升性能”。
- 半同步下漏配
rpl_semi_sync_master_wait_point=AFTER_SYNC(默认值),会导致主库在写 binlog 后即返回,从库还没收到就 crash,造成数据空洞 - MGR 中
group_replication_member_expel_timeout设为 0(默认)会使网络抖动直接踢出节点,应设为 ≥ 10(单位秒) - 所有节点的
server_id必须全局唯一,且 MGR 要求binlog_checksum=NONE(MySQL 8.0.26+ 可设为 CRC32,但旧版本不兼容)
真正的权衡不在参数列表里,而在监控能否看清“主库提交耗时 vs 从库认证耗时 vs 应用感知延迟”这三者的分布差异。没埋点,就等于在盲调。











