概述
故障是看得见的,副本少了一行、主库被手工修过却没有同步,则可能几周都无人发现,直到报表或客户对不上账。一致性核对把“数据是否漂移”变成定期执行、可验证的信号,而不是等事故发生后才去追查。
步骤
- 对已关闭的时间窗口计算行数与确定性内容指纹:
SELECT count(*) AS rows,
md5(string_agg(id::text || ':' || total_cents::text, ',' ORDER BY id)) AS fingerprint
FROM orders
WHERE created_at >= '2026-10-01' AND created_at < '2026-11-01';
- 在主库与副本分别执行,指纹不一致时让任务以非零状态退出并打印表名与窗口。
- 用
id % 16分桶对比,把差异定位到一个小范围,再对该桶做行级比较。 - 比较前先取主库
pg_current_wal_lsn(),等待副本pg_last_wal_replay_lsn()追平,避免把复制延迟误判为漂移。 - 在测试环境修改主库一行,确认任务能报出差异,再恢复并确认通过。
验证
健康的副本对同一窗口应返回完全相同的行数与指纹。修改一行后任务应输出类似 drift in orders: rows 12000 vs 12000 并以 exit=1 结束,同时指出具体分桶。恢复数据后再次运行应通过,且整个检查耗时在可接受范围内。
注意事项
- 指纹只能说明数据不同,不能说明原因,需要配合 binlog/WAL 或审计日志定位。
- 只有纳入哈希的列会被校验,其他列的修改不可见。
- 全表扫描代价高,应限制窗口、分桶并设置
statement_timeout,在副本上错峰执行。 - 不要比较仍在写入的开放窗口,也不要在副本未追平时下结论。
- 核对任务必须有配套 runbook,否则告警只会增加处理时间。