MySQL 5.7半同步复制不能保证零丢失,仅降低丢事务风险;必须先确保主从复制稳定(Slave_IO_Running和Slave_SQL_Running均为Yes、Seconds_Behind_Master≈0),再主库装rpl_semi_sync_master并设AFTER_SYNC、从库装rpl_semi_sync_slave并重启IO线程,最后通过SHOW STATUS验证Rpl_semi_sync_master_status和Rpl_semi_sync_slave_status均为ON且clients≥1。

MySQL 5.7 的半同步复制不能保证数据零丢失,它最多能保证“最多丢一个事务”——前提是网络稳定、从库存活、ACK 及时送达。真要接近零丢失,必须用 Group Replication 或 InnoDB Cluster;半同步只是降低风险的折中方案。
确认主从复制已完全就绪,否则半同步无效
半同步是叠加在异步复制之上的机制,不是独立方案。如果主从本身不同步,装了插件也白搭。
-
SHOW SLAVE STATUS\G中Slave_IO_Running和Slave_SQL_Running必须都是Yes -
Seconds_Behind_Master应稳定为0(或极小值),不能持续波动 - 主库必须开启
log_bin,从库必须设置唯一server-id并启用log_slave_updates = 1 - 禁用
binlog-do-db或replicate-ignore-db——这类库级过滤与 GTID 冲突,也容易导致 ACK 不触发
主从分别安装对应插件,不能混用或漏装
主库和从库加载的是不同 SO 文件,装反或只装一边,状态永远是 OFF。
- 主库执行:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so' - 从库执行:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so' - 立刻验证:
SHOW PLUGINS LIKE '%semi%',两行状态都必须是ACTIVE - 查
SELECT @@plugin_dir,确认semisync_master.so(主库)和semisync_slave.so(从库)真实存在且可读 - 某些 Docker 镜像或精简版会删掉这两个文件,需手动补入
关键参数必须设对,AFTER_SYNC 是底线
默认的 AFTER_COMMIT 模式在主库崩溃时仍可能暴露已提交但未同步的事务,金融场景必须规避。
- 主库执行:
SET GLOBAL rpl_semi_sync_master_wait_point = 'AFTER_SYNC'——这是 MySQL 5.7 实现“无损”的唯一路径 - 主库设超时:
SET GLOBAL rpl_semi_sync_master_timeout = 1000(单位毫秒),别用默认100000;设太小(如100)会频繁降级,设太大(如10000)会让业务卡顿 - 从库只需:
SET GLOBAL rpl_semi_sync_slave_enabled = 1,无需改wait_point(它没这个变量) -
rpl_semi_sync_master_wait_for_slave_count默认就是1,够用;改成大于1会显著增加写入延迟,且不提升可靠性下限
从库必须重启 IO 线程,否则 ACK 通道不建立
插件装了、参数也设了,但 Rpl_semi_sync_slave_status 始终是 OFF?大概率卡在这一步。
- 从库执行:
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;——不是STOP SLAVE; START SLAVE; - 只停启
SQL_THREAD不够,ACK 通信由IO_THREAD负责,必须让它重连握手 - 若从库启用了 GTID,还需确认
log_slave_updates = ON,否则 relay log 不写 binlog,主库收不到 ACK - 防火墙要放行主从之间的
3306端口,且主库上Rpl_semi_sync_master_clients必须 >0
真正容易被忽略的点是:半同步状态必须靠 SHOW STATUS LIKE 'Rpl_semi_sync%' 动态验证,而不是只看变量是否为 ON;AFTER_SYNC 模式依赖从库及时写入 relay log,而 relay log 写入又依赖磁盘 I/O 和从库负载,一旦从库慢或卡住,主库就会超时降级——这本身就是设计的一部分,不是故障。


















