rpo≈0在mysql中必须依赖after_sync半同步复制+sync_binlog=1、innodb_flush_logs_at_trx_commit=1等参数协同实现,因mysqldump/xtrabackup仅为时间点快照,无法覆盖备份间隔内事务;after_sync确保客户端收到成功响应时binlog已刷盘至至少一个从库磁盘。

RPO接近于0在MySQL生产环境里,不能靠“备份做得勤”来实现,必须让binlog在主库提交事务前,已落盘到至少一个从库的磁盘上——否则任何备份都只是快照,中间窗口永远存在。
为什么mysqldump或xtrabackup本身达不到RPO≈0
逻辑备份和物理备份都是时间点快照,无论10秒一备还是1分钟一备,两次备份之间的事务只要没被binlog同步出去,就可能丢失。
-
mysqldump执行期间新写入的数据不会包含在导出文件中; -
xtrabackup能保证备份时刻InnoDB页一致性,但不捕获之后的任何变更; - 备份工具不参与事务提交流程,无法绑定“客户端收到成功响应”和“日志已刷盘到从库”这两个事件。
AFTER_SYNC半同步是RPO≈0的硬性前提
只有rpl_semi_sync_source_wait_point = 'AFTER_SYNC'模式,才能确保主库在InnoDB commit前,等待至少一个从库将接收到的binlog写入并fsync到relay log文件。
- 必须显式执行:
SET GLOBAL rpl_semi_sync_source_wait_point = 'AFTER_SYNC'; - 仅安装插件不够:需确认
plugin_load_add加载了semisync_source.so和semisync_replica.so; - 从库IO线程要重启才生效(旧连接不感知新wait_point);
-
rpl_semi_sync_source_timeout建议设为10000(10秒),太小易降级为异步,太大则阻塞业务。
配套参数缺一不可,否则AFTER_SYNC形同虚设
就算设置了AFTER_SYNC,如果底层日志没真正落盘,依然可能丢数据。关键参数必须协同生效:
-
sync_binlog = 1:每次事务提交都强制fsyncbinlog文件; -
innodb_flush_logs_at_trx_commit = 1:确保redo log同步刷盘; - 从库必须启用
relay_log_info_repository = 'TABLE'和master_info_repository = 'TABLE',避免relay log元数据损坏导致复制中断; - 网络延迟要稳定且低(建议RTT
实际部署中最容易被忽略的三个点
很多团队调好了AFTER_SYNC就以为万事大吉,结果故障时仍丢数据——问题常出在这些细节:
- 主库
binlog_format不是ROW:语句级复制在从库重放时可能因非确定性函数、临时表等导致不一致; - 从库
read_only = 1没配或被绕过:人为写入或应用直连从库会破坏数据一致性; - 没有监控
rpl_semi_sync_source_status和rpl_semi_sync_replica_status:一旦半同步失效,系统不会报警,只会静默退化为异步。











