必须设为after_commit才能真正防止主库崩溃时的数据丢失;after_sync虽默认但会导致幽灵事务,即客户端收到失败响应而事务已存在于从库relay log中,切换后状态不可判定。

rpl_semi_sync_master_wait_point 必须设为 AFTER_COMMIT,否则无法真正防止主库崩溃时的数据丢失。默认的 AFTER_SYNC 看似更“安全”,实则会引入幽灵事务——客户端收到失败响应,但事务已在从库 relay log 中存在,切换后状态不可判定。
插件名和 SONAME 必须严格匹配 MySQL 8.0.x 版本
MySQL 8.0.26+ 起,插件名已变更,旧写法会静默失效:
- 主库:必须用
INSTALL PLUGIN semisync_master SONAME 'semisync_master.so'(不是rpl_semi_sync_master) - 从库:必须用
INSTALL PLUGIN semisync_slave SONAME 'semisync_slave.so'(不是rpl_semi_sync_slave) -
SONAME大小写敏感,路径必须在@@plugin_dir下;执行后立刻查SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%',状态必须是ACTIVE
从库启用半同步的三个硬性条件缺一不可
只装插件、只开变量,Rpl_semi_sync_slave_status 仍会卡在 OFF:
- 显式配置
relay-log(如relay-log = relay-bin),不能依赖默认值 -
read_only = ON是强制要求,不设则插件拒绝激活(防 GTID 冲突) - 必须在 IO 线程启动前就完成插件安装和
rpl_semi_sync_slave_enabled = 1;如果主从已运行,仅SET GLOBAL不生效,必须执行STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
超时降级不是故障,但容易被误判为“一直正常”
Rpl_semi_sync_master_status 显示 ON ≠ 实际生效;真正要盯的是:
-
Rpl_semi_sync_master_no_times:累计降级次数,非零说明出过问题 -
Rpl_semi_sync_master_off_times:因超时主动关闭次数 -
rpl_semi_sync_master_timeout建议设为3000~5000(毫秒),太短易误降级,太长阻塞业务 - 降级后不会自动恢复,需下一个事务触发重试,或手动重启 IO 线程
START SLAVE 之前,必须确保 semisync_slave 插件已 INSTALL、rpl_semi_sync_slave_enabled = 1 已生效、relay-log 已显式配置、read_only = ON 已设置——四者缺一,Rpl_semi_sync_slave_status 就永远是 OFF。











