半同步复制无法实现金融级零丢失,仅能保证最多丢一个事务;真要接近零丢失,必须叠加GTID、AFTER_SYNC模式、超低超时(≤1000ms)、至少两个从库ACK等硬性条件,且MySQL版本需≥5.7。

不能靠半同步复制实现“金融级零丢失”——它最多保证“最多丢一个事务”,且依赖网络稳定性和从库可靠性。真要接近零丢失,必须叠加 GTID、AFTER_SYNC 模式、超低超时、至少两个从库 ACK 等硬性条件。
确认 MySQL 版本与插件支持是否到位
MySQL 5.5 起才内置半同步插件,但真正可用的生产级保障得从 5.7 开始(AFTER_SYNC 模式 + 独立 ACK 接收线程)。8.0 更稳,但注意:5.6 及更早默认是 AFTER_COMMIT,主库崩溃时可能暴露已提交但未同步的事务,金融场景必须规避。
先验证动态加载能力:
SHOW VARIABLES LIKE '%have_dynamic_loading%';
返回 YES 才能继续。若为 NO,需在启动参数加 --plugin-load-add=semisync_master.so 并重启。
- 检查插件文件是否存在:
/usr/lib64/mysql/plugin/semisync_master.so(路径因安装方式而异) - MySQL 8.0.23+ 默认禁用
plugin_load,必须显式配置plugin_load_add - 二进制包通常自带插件;源码编译需确认编译时启用了
-DWITH_SEMI_SYNC=ON
必须启用 AFTER_SYNC 模式并设 rpl_semi_sync_master_timeout ≤ 1000
AFTER_SYNC 是金融级配置的底线:主库把事务写入 binlog 并收到至少一个从库的 relay log 写入确认后,才提交事务。这样即使主库瞬间宕机,已确认的事务一定在从库 relay log 里,可完整恢复。
设置方式(主库执行):
SET GLOBAL rpl_semi_sync_master_enabled = 1;<br>SET GLOBAL rpl_semi_sync_master_timeout = 1000;<br>SET GLOBAL rpl_semi_sync_master_wait_for_slave_count = 2;
关键点:
-
rpl_semi_sync_master_timeout = 1000(1 秒),不是默认 10 秒——超时即降级为异步,时间越长,业务阻塞风险越高 -
rpl_semi_sync_master_wait_for_slave_count = 2强制等待两个从库 ACK,单点故障不触发降级 - 该模式仅在 MySQL 5.7+ 支持,5.6 不识别
rpl_semi_sync_master_wait_point参数
从库必须开启 rpl_semi_sync_slave_enabled 且 IO 线程正常运行
只装插件不启用等于没配。从库上执行:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';<br>SET GLOBAL rpl_semi_sync_slave_enabled = 1;
但注意:启用后必须重启 IO 线程才能生效:
STOP SLAVE IO_THREAD;<br>START SLAVE IO_THREAD;
常见坑:
-
SHOW SLAVE STATUS\G中Seconds_Behind_Master为NULL或负数?说明 IO 线程没真跑起来,半同步不会触发 - 从库
read_only = 1必须设,否则应用误写从库会破坏一致性 - GTID 模式下,从库
enforce_gtid_consistency = ON和gtid_mode = ON缺一不可,否则半同步可能静默失效
验证是否真在半同步状态,而非“假启用”
很多配置看似成功,实际因网络、权限、插件加载顺序等问题,rpl_semi_sync_master_status 仍为 OFF。每台机器都要查:
SHOW VARIABLES LIKE 'rpl_semi_sync%';<br>SHOW STATUS LIKE 'Rpl_semi_sync%';
重点关注:
-
Rpl_semi_sync_master_status=ON(主库) -
Rpl_semi_sync_slave_status=ON(从库) -
Rpl_semi_sync_master_yes_tx值应随写入持续增长,Rpl_semi_sync_master_no_tx应为 0 或极低 - 若
Rpl_semi_sync_master_no_tx持续上升,说明频繁超时降级,网络或从库 I/O 已成瓶颈
最后提醒:半同步不解决从库 SQL 线程延迟问题。它只管“binlog 到 relay log”,不管“relay log 是否已执行”。金融系统必须监控 Seconds_Behind_Master,并搭配 pt-heartbeat 做秒级延迟探测——否则你以为数据已落盘,其实还在 relay log 里排队。


















