必须手动执行set global rpl_semi_sync_master_wait_point = 'after_sync',因其虽默认值为after_sync,但仅在插件active且rpl_semi_sync_master_enabled=1后才生效;跳过该命令会导致部分环境回退到旧行为,无法实现无损复制。

MySQL 5.7 的半同步复制性能瓶颈通常不在插件本身,而在于 wait_point 选择、超时设置、IO 线程重载时机和网络确认链路是否真正打通——配错一个参数,它就退化成“假半同步”,写入变慢却没换来可靠性提升。
为什么 SET GLOBAL rpl_semi_sync_master_wait_point = 'AFTER_SYNC' 必须手动执行
AFTER_SYNC 是 MySQL 5.7 实现无损复制的唯一路径,但它的生效不依赖配置文件默认值,也不随插件加载自动激活。官方文档明确说明:该变量默认值虽为 AFTER_SYNC,但仅当 rpl_semi_sync_master_enabled = 1 且插件已 ACTIVE 后,该值才参与决策;若你跳过显式 SET GLOBAL,某些版本(如部分 Docker 镜像或 RPM 包)会回退到旧行为或未初始化状态。
- 必须在主库执行:
SET GLOBAL rpl_semi_sync_master_wait_point = 'AFTER_SYNC'; - 不要只写进
my.cnf就以为万事大吉——MySQL 启动时不解析这个变量的字符串值,只认运行时设定 - 验证是否生效:
SELECT @@rpl_semi_sync_master_wait_point;返回值必须是AFTER_SYNC,不是空、不是AFTER_COMMIT
如何避免 rpl_semi_sync_master_timeout 导致主库卡顿
超时值设得过大,主库会在无响应从库上死等;设得太小,又频繁降级为异步,失去半同步意义。10000 毫秒(10 秒)是生产环境较稳妥的平衡点,但需结合真实网络 RTT 调整。
- 先用
ping和mysqladmin ping测主从间平均延迟,再设 timeout 为该值的 3–5 倍 - 绝对不要设为
0(无限等待)或100000(默认 100 秒),否则单个从库抖动就会拖垮整个主库写入 - 降级后主库不会报错,但
Rpl_semi_sync_master_status会短暂变为OFF,需监控该状态变化频率 - 该参数必须动态执行:
SET GLOBAL rpl_semi_sync_master_timeout = 10000;,仅写配置不生效
从库 STOP SLAVE IO_THREAD; START SLAVE IO_THREAD; 不是可选步骤
很多团队配置完插件和参数后,Rpl_semi_sync_slave_status 一直是 OFF,根本原因是 ACK 通信通道没重建。半同步的握手发生在 IO 线程启动瞬间,只重启 SQL 线程或全停全启(STOP SLAVE; START SLAVE;)都不触发新连接。
- 从库必须执行:
STOP SLAVE IO_THREAD;→ 等 2 秒 →START SLAVE IO_THREAD; - 执行后立刻查:
SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';应返回ON - 如果仍是
OFF,检查从库是否启用了log_slave_updates = 1(GTID 场景下必须开启,否则 relay log 不生成 binlog,主库收不到 ACK) - 确认从库
relay_log_info_repository = 'TABLE'(推荐),避免文件型 info 与半同步状态不同步
为什么 SHOW PLUGINS 状态为 DISABLED 或查不到插件
插件未加载成功是最常被忽略的前置失败点。MySQL 5.7 官方二进制包自带 semisync_master.so 和 semisync_slave.so,但精简版、容器镜像或自编译版本常删掉它们,导致 INSTALL PLUGIN 报错 “Can’t open shared library”。
- 先查路径:
SELECT @@plugin_dir;,进入该目录确认两个 so 文件存在且权限为rw-r--r-- - 主库执行:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; - 从库执行:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; - 立即验证:
SHOW PLUGINS LIKE '%semi%';,两行Status列必须是ACTIVE,不是DISABLED,也不是空行 - 若提示 “Function 'rpl_semi_sync_master' already exists”,说明插件已装但状态异常,先
UNINSTALL PLUGIN rpl_semi_sync_master;再重装
真正难调的从来不是参数列表,而是确认每一层——插件文件是否存在、状态是否 ACTIVE、变量是否 SET GLOBAL 生效、IO 线程是否重载、网络 ACK 是否能穿透防火墙——缺一环,Rpl_semi_sync_master_clients 就永远是 0。











