归档事务需绑定完整业务单元,确保订单主表、明细、支付、物流等在同事务中归档或全不归档;须支持可重入与断点续做;依赖一致性快照保障时间一致性;归档后需抽样比对、关联检查及业务规则校验。

归档事务需绑定完整业务单元
SQL归档不是简单导出旧数据,而是要确保归档前后业务语义不变。一个订单的主表、明细、支付记录、物流轨迹等,必须在同一个事务中完成归档或全部不归档。否则会出现“归档了订单但没归档明细”,导致查询时关联失败或数据断层。
建议做法:
- 归档前通过业务主键(如 order_id)查出所有关联表的数据,生成归档批次号
- 用同一事务执行:源库标记(如 update t_order set archived=1 where order_id in (...))、目标归档库插入、源库物理删除(或逻辑清理)
- 若使用分库分表,需确保跨分片的关联数据归属同一归档批次,避免拆分事务
归档过程必须支持可重入与断点续做
归档常在低峰期执行,但可能因锁表、网络抖动、OOM等原因中断。若每次失败都从头开始,不仅耗时,还可能重复归档或漏归档。
关键控制点:
- 归档任务记录状态表(task_id, batch_no, start_time, end_time, status, last_pk_processed),按主键/时间戳分片推进
- 每次归档前先查状态表,跳过已完成批次;对进行中的批次,从 last_pk_processed 继续扫描
- 归档插入前加唯一约束(如 (batch_no, source_table, pk_value)),防止重复写入
时间一致性依赖统一时钟与快照机制
归档窗口内源库持续写入,若未锁定或未使用一致性快照,可能出现“归档了t1时刻A表、t2时刻B表”,造成跨表数据不匹配。
推荐方案:
- MySQL 使用 START TRANSACTION WITH CONSISTENT SNAPSHOT 配合 SELECT ... INTO OUTFILE 或逻辑复制拉取
- PostgreSQL 使用 REPEATABLE READ 事务 + pg_dump --snapshot 或逻辑解码(logical decoding)获取一致位点
- 禁止用多个独立SELECT拼接归档数据;必须基于同一事务快照或binlog/gtid位点
归档后需验证而非仅校验行数
行数一致只是基础,不能保证字段值、关联关系、业务约束完整迁移。例如金额字段精度丢失、JSON字段截断、外键引用归档后失效等,都可能静默出错。
有效验证方式:
- 抽样比对:对每个归档批次,随机选取5~10条记录,逐字段比对源库SELECT结果与归档库SELECT结果(含NULL、空字符串、时区、精度)
- 关联完整性检查:运行 SQL 如 SELECT COUNT(*) FROM archived_order o LEFT JOIN archived_order_item i ON o.order_id = i.order_id WHERE i.order_id IS NULL,确认无孤立子记录
- 业务规则校验:如“已发货订单的归档版本中,shipping_time 必须不为空且 ≥ create_time”,用聚合SQL快速扫一遍










