MySQL半同步复制需按版本正确安装插件:5.7用rpl_semi_sync_master/slave,8.0+用semisync_master/slave;降级静默发生,须监控Rpl_semi_sync_master_no_times等状态变量,并结合GTID与刷盘策略保障数据安全。

半同步复制插件名和安装命令写错就白忙
MySQL 半同步不是默认开启的,必须手动装插件,而且插件名在不同版本里还不一样。5.7 用 rpl_semi_sync_master 和 rpl_semi_sync_slave,8.0 起改成了 semisync_master 和 semisync_slave。装错名字会返回 Unknown plugin,但错误不明显,容易卡在“以为装上了”。
- 先查当前版本:
SELECT VERSION(); - 5.7 安装主库插件:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; - 8.0+ 改用:
INSTALL PLUGIN semisync_master SONAME 'semisync_master.so'; - 从库同理,注意插件名和 SO 文件名要匹配(Linux 是
.so,macOS 是.dylib) - 装完立刻查:
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%';,状态必须是ACTIVE
超时降级后复制变成异步,但 SHOW SLAVE STATUS 看不出异常
半同步的核心机制是:主库等至少一个从库 ACK 后才返回成功;等不到就超时降级为异步。这个降级是静默发生的,SHOW SLAVE STATUS 里的 Seconds_Behind_Master 和 Slave_IO_Running 全都正常,根本看不出已经退化了。
- 关键指标在主库查:
SHOW STATUS LIKE 'Rpl_semi_sync%';,重点关注Rpl_semi_sync_master_status(是否启用)、Rpl_semi_sync_master_no_times(降级次数)、Rpl_semi_sync_master_off_times(因超时关闭的次数) -
rpl_semi_sync_master_timeout默认是 10000 毫秒(10 秒),太长会导致主库长时间阻塞;设太短(比如 100ms)又容易误降级——得结合网络 RTT 和从库负载调,建议先设成 2000~5000 - 降级后不会自动恢复半同步,必须等下一个事务触发重试(或重启 IO 线程),所以监控不能只盯
master_status,得持续看no_times是否持续增长
半同步 + GTID 搭配时,从库开启 semi-sync 的时机很关键
如果主从已启用 GTID,但你在从库上先启动 IO 线程、再装插件并启用半同步,会出现 The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1 成功,但始终无法进入半同步状态——因为半同步握手发生在连接建立初期,插件没就位就错过了。
- 正确顺序:从库先装插件 → 设置
rpl_semi_sync_slave_enabled = ON→ 再执行START SLAVE IO_THREAD - 验证是否生效:在从库执行
SELECT @@rpl_semi_sync_slave_enabled;必须返回ON,且主库的Rpl_semi_sync_master_clients数值应增加 1 - 如果已经 START SLAVE 了,别 reload,直接停 IO 线程再启:
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;,强制重新握手
无损复制 ≠ 绝对不丢数据,主库 crash 时仍有边界情况
所谓“无损”,是指主库提交事务前确保至少一个从库已刷盘 relay log。但这个保证依赖两个前提:从库确实收到了 binlog、并且从库自己没 crash。一旦主库在等待 ACK 过程中突然宕机,而那个唯一 ACK 的从库也刚好在刷盘途中掉电,数据就丢了。
- 真正防丢要组合:半同步 + 从库
sync_relay_log = 1+relay_log_info_repository = TABLE(避免 relay-log.info 文件丢失位置) - 主库端还要开
sync_binlog = 1和innodb_flush_log_at_trx_commit = 1,否则 binlog 或 redo 日志没落盘,半同步也没意义 - 不要迷信“半同步=高可用”,它只解决单点写入的数据安全,不解决脑裂、网络分区或从库延迟过大导致的 failover 数据不一致问题
半同步真正的复杂点不在装插件,而在降级行为不可见、恢复逻辑不自动、以及和 GTID/刷盘策略的耦合细节。线上开之前,一定拿模拟网络延迟工具(如 tc)压测超时与恢复路径,而不是只看 status 变绿就放心。










