半同步复制不能防止所有数据丢失但能显著降低未同步事务丢失概率;需按MySQL版本正确安装插件、重启IO线程、确认状态为ON,并设rpl_semi_sync_master_wait_point=AFTER_SYNC才真正安全。

半同步复制不能防止所有数据丢失,但能显著降低主库宕机时未同步事务丢失的概率;最常见配置失败原因是插件名与 MySQL 版本不匹配,或从库未重启 IO 线程。
MySQL 8.0.26+ 必须用新插件名 rpl_semi_sync_source 和 rpl_semi_sync_replica
混用旧名(rpl_semi_sync_master/rpl_semi_sync_slave)会导致插件加载失败、状态始终为 OFF。8.0.26 起这两个旧名已被废弃,且对应 SO 文件名也变了:
- MySQL 8.0.26 及以上:用
INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so'和INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so' - MySQL 5.7–8.0.25:仍用
rpl_semi_sync_master/rpl_semi_sync_slave+semisync_master.so/semisync_slave.so - 执行
SHOW PLUGINS LIKE '%semi%'后,确认Status列为ACTIVE,且Type为SEMISYNCHRONOUS_REPLICATION
从库启用后必须重启 IO 线程,否则 rpl_semi_sync_replica_enabled = 1 不生效
仅执行 SET GLOBAL rpl_semi_sync_replica_enabled = 1 是无效的——插件在从库上依赖 IO 线程启动时加载。不重启线程,等于没启用:
- 在从库执行:
STOP SLAVE IO_THREAD;然后START SLAVE IO_THREAD; - 之后检查
SHOW STATUS LIKE 'Rpl_semi_sync_replica_status',返回ON才算真正激活 - 若仍为
OFF,优先排查:插件名/SONAME 错、semisync_*.so文件缺失、主从间防火墙未放行 3306 的 ACK 包(不是只开 TCP 连接,还要允许响应包)
rpl_semi_sync_master_wait_point 决定一致性强度:选 AFTER_SYNC 才真安全
MySQL 5.7+ 默认是 AFTER_SYNC 模式,但如果你是从老版本升级或手动配置,务必确认该参数值:
-
SELECT @@rpl_semi_sync_master_wait_point;应返回AFTER_SYNC -
AFTER_COMMIT(5.6 默认)有致命缺陷:InnoDB 提交已完成,binlog 却还没发出去或没被 ACK,此时主库宕机就会丢数据 -
AFTER_SYNC要求 binlog 先刷盘、再等 ACK、最后才提交 InnoDB,只要客户端收到“成功”,binlog 就已落盘且从库已接收,崩溃恢复也能补全 - 可通过
SET GLOBAL rpl_semi_sync_master_wait_point = 'AFTER_SYNC';动态调整(需主库 SUPER 权限)
真正容易被忽略的是网络层细节:半同步对 ACK 包延迟极其敏感,超时(默认 10 秒)即自动降级为异步。很多“配置好了却还是丢数据”的案例,其实压根没进半同步流程——因为网络丢 ACK、防火墙拦截回包、或从库 relay log 目录磁盘满导致写入失败,这些都不会报错,只会静默退回到异步模式。


















