mysql 5.7半同步复制仅保证至少一个从库写入relay log,不保证事务执行、无延迟或防丢数据,需group replication实现强一致性;其依赖稳定异步复制基础,主从配置、插件安装、参数设置(如after_sync)、状态验证缺一不可。

MySQL 5.7 的半同步复制不能保证强一致性,它只承诺“至少一个从库已写入 relay log”,不保证事务已执行、不保证从库无延迟、也不防止单点故障时主库丢数据。如果你真需要强一致性,该上 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 不触发
插件安装必须分主从、查状态、重启线程
MySQL 5.7 自带插件文件,但默认不加载;而且主库和从库用的 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,不是DISABLED也不是空 - 从库装完后必须执行:
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;——仅START SLAVE不够,I/O 线程不重连不会激活 ACK 通道 - 检查
SELECT @@plugin_dir;,确认semisync_master.so和semisync_slave.so真实存在且权限可读
关键参数必须设对,尤其是 wait_point 和 timeout
光开 rpl_semi_sync_master_enabled=1 远不够。默认的 AFTER_COMMIT 模式在主库 crash 时仍可能丢事务;而超时设错会导致频繁降级或卡死。
- 主库必须设:
SET GLOBAL rpl_semi_sync_master_wait_point = 'AFTER_SYNC';——这是 MySQL 5.7 实现“无损复制”的唯一路径 -
rpl_semi_sync_master_timeout建议设为3000~5000(毫秒),别用默认100000;设太小(如100)会频繁降级为异步,设太大(如10000)会让业务明显卡顿 - 从库只需启用:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;,无需改wait_point(它没这个变量) - 别乱动
rpl_semi_sync_master_wait_for_slave_count,默认1就够;设成2以上,只要一个从库掉线,主库就全卡住
验证不能只看变量,要盯运行时状态和客户端行为
很多人查 SHOW VARIABLES LIKE 'rpl_semi_sync%' 全是 ON 就以为成功了,其实 Rpl_semi_sync_master_status 才是真实开关。
- 主库执行:
SHOW STATUS LIKE 'Rpl_semi_sync%';,重点看:
–Rpl_semi_sync_master_status必须是ON(不是变量值,是运行时状态)
–Rpl_semi_sync_master_clients≥1
–Rpl_semi_sync_master_yes_tx应随写入递增 - 从库执行:
SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';,值必须是ON - 手动测试写入:
INSERT INTO test.t1 VALUES (NOW());,然后立刻在从库查是否可见;若延迟明显或不一致,先查网络、防火墙、max_allowed_packet是否过小 - 模拟从库断网:主库会自动降级(
Rpl_semi_sync_master_status变OFF),恢复后需等几秒才会重新升回ON——这不是 bug,是设计行为
最容易被忽略的是:半同步只管“relay log 落盘”,不管 SQL 线程是否执行完毕;从库 read_only=1 也不拦 SUPER 用户写入;真要防误操作,得配 super_read_only=1。还有,GTID 模式下必须用 MASTER_AUTO_POSITION = 1,否则 CHANGE MASTER TO 直接报错。











