跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何解决MySQL在主从架构下的事务不一致_配置rpl_semi_sync_master_wait_point

必须设为AFTER_SYNC才能防丢数据:主库先fsync binlog再等从库relay log落盘后才提交事务;AFTER_COMMIT则先提交再发binlog,主库宕机时已提交事务仍可能丢失。 必须设为
AFTER_SYNC
,否则半同步不防丢数据。 默认值虽已是
AFTER_SYNC
(MySQL 5.7+),但升级、重装或从旧版本迁移后常被忽略,导致实际运行在
AFTER_COMMIT
模式下——主库宕机时已提交事务仍可能丢失。 为什么
AFTER_SYNC
才算真正“无损” 关键区别不在“等不等 ACK”,而在“提交时机”:
AFTER_SYNC
:主库写完 binlog 并
fsync
到磁盘 → 等至少一个从库写入 relay log 并
fsync
→ 再提交事务到 InnoDB(即打上
COMMITTED
标签)→ 客户端才收到成功响应
AFTER_COMMIT
:主库先提交事务到 InnoDB → 再发 binlog → 再等 ACK → 若此时主库 crash,事务已提交但 binlog 还没发完,从库收不到,数据就丢了 换句话说:
AFTER_SYNC
把“客户端看到数据”和“数据已安全落盘到至少一个从库”严格对齐;
AFTER_COMMIT
只保证“主库自己认为完成了”,不保证别人能拿到。 如何确认并强制生效
rpl_semi_sync_master_wait_point
该变量是会话级只读变量,不能用
SET SESSION
修改,必须用
SET GLOBAL
,且仅对后续新事务生效:
SET GLOBAL rpl_semi_sync_source_wait_point = 'AFTER_SYNC';
验证是否生效: MySQL(Linux) MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。 下载 查当前值:
SELECT @@rpl_semi_sync_source_wait_point;
(注意 MySQL 8.0+ 中变量名含
source
,不是
master
) 查半同步状态:
SHOW STATUS LIKE 'Rpl_semi_sync%';
关注
Rpl_semi_sync_source_status
是否为
ON
,以及
Rpl_semi_sync_source_clients
是否 ≥1 检查从库是否真在接收:在从库执行
SHOW SLAVE STATUS\G
,确认
Seconds_Behind_Master
非 NULL 且
Slave_SQL_Running
为
Yes
⚠️ 注意:该设置不持久化,MySQL 重启后失效。需写入配置文件(如
my.cnf
)的
[mysqld]
段:
rpl_semi_sync_source_wait_point=AFTER_SYNC
常见踩坑点:你以为启用了,其实没生效 以下情况会导致
AFTER_SYNC
形同虚设: 主库插件未启用:
INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';
(8.0+)或
semisync_master.so
(5.7) 从库插件未启用或未开启:
INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so';
+
SET GLOBAL rpl_semi_sync_replica_enabled = ON;
网络超时后自动降级为异步:
rpl_semi_sync_source_timeout
默认 10s,超时后主库继续提交,但不再等 ACK —— 此时
Rpl_semi_sync_source_status
变为
OFF
,需监控告警 主库双 1 未配齐:
sync_binlog = 1
和
innodb_flush_log_at_trx_commit = 1
缺一不可;否则 binlog 或 redo log 可能只在 OS cache,crash 后丢失 真正难的不是设这个参数,而是确保整个链路:主库 binlog 落盘 → 网络可靠 → 从库 relay log 落盘 → 主库收到 ACK → 事务才提交。任何一个环节松动,
AFTER_SYNC
就守不住一致性边界。

相关文章