半同步复制需主从插件正确安装、参数准确配置且io线程重启到位,否则rpl_semi_sync_master_status恒为off;主库装rpl_semi_sync_master,从库装rpl_semi_sync_slave,设after_sync等待点并验证状态变量。

半同步复制不是开关一开就生效,必须主从插件装对、参数设准、IO线程重启到位,否则 Rpl_semi_sync_master_status 永远是 OFF。
主库和从库必须分别安装对应插件
MySQL 半同步依赖两个独立插件:rpl_semi_sync_master(主库用)和 rpl_semi_sync_slave(从库用),不能混装。Linux 下文件名通常是 semisync_master.so 和 semisync_slave.so,macOS 是 .dylib,Windows 是 .dll。
- 先查插件目录:
SELECT @@plugin_dir,确认semisync_master.so等文件确实在该路径下 - 主库执行:
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
只设 rpl_semi_sync_master_enabled=1 但没装插件?参数会自动回退为 OFF,错误日志里还不报错——这是最常被忽略的失效原因。
从库必须重启 IO 线程才能注册为 semi-sync 客户端
插件装了、rpl_semi_sync_slave_enabled=1 也设了,但主库 Rpl_semi_sync_master_clients 仍是 0?问题大概率出在这里:从库的 IO 线程没重启,无法向主库发起 ACK 注册。
- 从库执行:
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD; - 不要用
STOP SLAVE; START SLAVE全停全启,那会中断 SQL 线程,可能引入延迟 - 重启后立即查:
SHOW STATUS LIKE 'Rpl_semi_sync_slave_status',必须返回ON
很多线上环境卡在这一步:配置写了、服务重启了,但忘了单独抖一下 IO 线程。
关键参数必须设对,尤其 rpl_semi_sync_master_wait_point
MySQL 5.7 默认 rpl_semi_sync_master_wait_point=AFTER_COMMIT,但这会导致事务提交后才等 ACK,有丢数据风险;真正实现“无损复制”的是 AFTER_SYNC 模式——事务写入 binlog 并 sync 到磁盘后,才等待从库 ACK。
- 主库设:
SET GLOBAL rpl_semi_sync_master_wait_point = 'AFTER_SYNC'; - 超时必须设合理:
SET GLOBAL rpl_semi_sync_master_timeout = 1000(单位毫秒),太小(如 100)易频繁降级,太大(如 60000)会让业务卡住 -
rpl_semi_sync_master_wait_for_slave_count默认是 1,够用;除非你明确要等多个从库,否则别改
这个 wait_point 不是可选项,而是数据安全分水岭。设错等于白配。
验证不能只看变量,要看运行时状态
SHOW VARIABLES LIKE 'rpl_semi_sync%' 只告诉你“配置开了”,不代表当前在工作。真正有效的是 SHOW STATUS 中的状态变量。
- 主库查:
SHOW STATUS LIKE 'Rpl_semi_sync_master_status'→ 必须是ON - 主库查:
SHOW STATUS LIKE 'Rpl_semi_sync_master_clients'→ 必须 ≥ 1 - 从库查:
SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'→ 必须是ON - 写一条测试数据后,再查
Rpl_semi_sync_master_yes_transactions是否 +1,比看日志更直接
半同步降级后不会自动升回,得靠从库重连或手动干预;所以监控 Rpl_semi_sync_master_no_times 和 Rpl_semi_sync_master_timeouts 这两个指标比单纯看 ON/OFF 更重要。











