半同步复制在mysql 8.0中需主从分别安装对应插件(主库rpl_semi_sync_master/源端rpl_semi_sync_source,从库rpl_semi_sync_slave/副本端rpl_semi_sync_replica),启用参数并配置relay-log和read_only,缺一不可;仅改参数或只装一边插件,复制仍为异步。

半同步复制在 MySQL 8.0 中不是开箱即用的,必须手动加载插件、配置参数、并验证 ACK 机制是否真正生效;跳过任一环节,rpl_semi_sync_master_enabled 看似为 ON,实际仍走异步路径。
确认半同步插件已正确加载并启用
MySQL 8.0 默认不加载半同步插件,且插件名和参数名相比 5.7 有变化:主库用 semisync_master,从库用 semisync_slave(不是旧版的 semisync_master_plugin)。插件未加载或加载失败时,SHOW VARIABLES LIKE '%semi%' 会返回空,但不会报错。
实操建议:
- 主库执行:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';(Linux)或'semisync_master.dll'(Windows) - 从库执行:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; - 立即检查:
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'rpl_semi%';—— 必须看到ACTIVE - 加载后仍需显式启用:
SET GLOBAL rpl_semi_sync_master_enabled = ON;和SET GLOBAL rpl_semi_sync_slave_enabled = ON;
主从参数必须成对匹配,否则半同步自动退化
半同步不是“只要主库开了就行”的开关。它依赖主从两端的协同:主库发出事务后等待 ACK,而 ACK 只有从库成功写入 relay_log 并刷盘后才发出。若从库未启用插件、或 rpl_semi_sync_slave_enabled 为 OFF,主库会在超时后 silently 切回异步模式,SHOW STATUS LIKE 'Rpl_semi_sync%' 中的 Rpl_semi_sync_master_status 会变为 OFF,但 rpl_semi_sync_master_enabled 仍显示 ON —— 这是最容易被忽略的“假启用”。
关键参数组合:
- 主库必须设:
rpl_semi_sync_master_timeout = 10000(单位毫秒,建议 10s 起步,太小易频繁退化) - 从库必须设:
relay_log_recovery = ON(崩溃恢复时自动重建 relay log,否则重启后半同步无法继续) - 主从都应设:
binlog_format = ROW(语句级复制在半同步下可能因从库函数/时间差异导致数据不一致)
验证是否真走半同步,不能只看 SHOW SLAVE STATUS
SHOW SLAVE STATUS 只反映 IO/SQL 线程状态,完全不体现半同步行为。真正判断依据是状态变量:
- 主库查:
SHOW STATUS LIKE 'Rpl_semi_sync_master_status';—— 必须为ON(注意不是enabled变量) - 主库查:
SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx';和Rpl_semi_sync_master_no_tx—— 前者应持续增长,后者长期为 0 或极低 - 从库查:
SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';—— 必须为ON,且Rpl_semi_sync_slave_delayed_tx不应持续上升
一个快速验证法:在主库执行 BEGIN; INSERT INTO test.t1 VALUES (1); COMMIT;,然后立刻在从库查 SELECT COUNT(*) FROM test.t1;;再立刻回到主库查 SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx';。如果两次查询间隔内该值加了 1,基本可确认本次事务走了半同步路径。
GTID 与半同步可以共存,但配置顺序不能错
想用 GTID 简化故障切换,又需要半同步保障数据安全?可以。但 MySQL 8.0 要求:必须先开启 GTID(enforce_gtid_consistency = ON + gtid_mode = ON),再加载半同步插件并启用。反过来操作会导致插件加载失败或复制中断。
GTID 模式下 CHANGE MASTER TO 的写法也不同:
- 不用指定
MASTER_LOG_FILE和MASTER_LOG_POS - 必须加
MASTER_AUTO_POSITION = 1 - 例如:
CHANGE MASTER TO MASTER_HOST='192.168.1.10', MASTER_USER='repl', MASTER_PASSWORD='xxx', MASTER_PORT=3306, MASTER_AUTO_POSITION = 1;
GTID + 半同步的组合虽强,但一旦网络抖动导致从库 ACK 超时,主库会阻塞后续事务,此时 innodb_lock_wait_timeout 和应用层超时设置就变得非常关键——这点常被低估。











