核心是切完如何安全补差量:先识别不一致类型(事务丢失/gtid跳变/元数据漂移),再通过日志追平、事务补偿或工具校验(如pt-table-sync、sys_distributed_transaction)增量修复,而非盲目重搭;同时须配置binlog_checksum、read_only强制管控及元数据强同步以防复发。

主备切换后发现数据不一致,核心不是“怎么切”,而是“切完怎么补”。关键在于识别缺失范围、锁定差异来源,并用安全可控的方式把差量追平,而不是盲目重搭或跳过错误。
先确认不一致的类型和范围
不同场景下“不一致”含义不同,处理方式也不同:
- 事务级丢失:应用收到 commit ack,但新主库查不到——说明最后几条 WAL/redo 日志没传到原备库。需比对主库 last_lsn 与新主库 replay_lsn 差值(gdb_admin show replication status)。
- GTID 或 binlog position 跳变:比如 MySQL 切换后 GTID_SET 缺少某个事务号(如 5a... 少一个 gno),说明主库宕机前有事务未同步完成。此时不能直接 start slave,要先检查旧主是否曾被误写(read_only 是否开启)。
- 元数据漂移:sequence 值回退、全局锁快照错乱、MVCC 版本链断裂——这类问题常见于 GoldenDB 等分布式数据库,源于系统表弱同步。需单独校验 sys_sequence、gtid_mapping 等表。
针对性补齐策略(按严重程度排序)
不建议一上来就全量重建。优先走增量修复路径:
- 日志级追平:若主库仍可访问(即使宕机后恢复),导出切换窗口期缺失的 WAL 或 binlog 片段,在新主库上手工 apply(OpenGauss 用 pg_waldump + pg_restore;MySQL 可解析 binlog 后过滤指定 position 区间执行)。
- 事务级补偿:对已知 xid 的丢失事务,从应用日志或 binlog 解析出原始 SQL,在新主库上幂等重放(注意 insert 要加 on duplicate key update,update 要加 where 条件防误改)。
- 工具化校验与同步:MySQL 生态可用 pt-table-checksum 定位不一致的表和行,再用 pt-table-sync 生成修复语句;GoldenDB 建议查 sys_distributed_transaction 表中状态为 'prepare' 但无 commit_time 的记录,人工决议。
避免下次再出问题的关键配置
补齐只是救火,预防才是重点:
- 主库强制开启 binlog_checksum=ON,从库开启 slave_sql_verify_checksum=ON,防止日志损坏导致静默丢数据。
- GoldenDB / OpenGauss 类系统,将 sequence、gtid 映射等元数据表纳入强同步通道(如绑定 etcd 或本地 wal 持久化 prepare 状态)。
- 所有备库默认启用 read_only=ON,且在 failover 脚本中明确控制:仅新主升主瞬间才 set global read_only=OFF,避免脑裂写入。










