大家好,我是小耶,写功课只是为了我踩过的坑,你们别再踩了!
数据迁移做完了,最怕业务方问一句话:"数据都过来了吗?跟原来一样吗?"
你心里没底。
全量迁移时源库还在持续写入、增量同步时事务顺序可能错乱、异构数据库的日期精度可能丢失------这些问题,在POC阶段很难暴露,一上生产就变成事故。
有人说"数据一致性是迁移的底线",但底线这东西,只有出问题的时候才知道它有多低。今天从三种一致性风险场景出发,把数据一致性校验这件事彻底讲清楚。
一、为什么数据一致性这么难保证?
迁移过程中,源库不是静止的。全量迁移要几个小时甚至几天,这期间业务还在写数据。你把全量数据搬过去的时候,源库已经变了。增量同步把变更追平,但同步本身也可能出错------顺序乱了、事务断了、精度丢了。
一致性风险主要来自三个层面:
风险一:全量迁移时源库在持续写入
你导出了表A的快照,导到一半,源库的这条记录被更新了。目标库收到的是"旧版本",但源库已经变成"新版本"了。如果没有机制处理这种冲突,数据就会不一致。
风险二:增量同步的事务顺序错乱
增量同步基于日志解析(CDC),捕获的是一系列变更事件。但如果网络抖动或目标端写入延迟,事件的回放顺序可能与源库的提交顺序不一致。对于有外键依赖的表,顺序错了,数据可能根本插不进去。
风险三:异构数据类型的精度丢失
Oracle的DATE包含时分秒,MySQL的DATE只存日期;VARCHAR的字符集转换可能丢数据;NUMBER的精度映射可能四舍五入。这些差异在迁移工具的默认映射下可能被"静默"处理,校验阶段才会暴露。
二、数据一致性校验的三个层次
一致性校验不能只做一次,需要在迁移的不同阶段分别执行。
第一层:结构校验------表结构对不对
数据搬进去之前,先确认表结构、索引、约束、字符集、时区设置全对。很多数据不一致的根因,不是数据本身错了,是结构没对齐。
bash
-- 对比源库和目标库的表结构差异
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_SET_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_db'
ORDER BY TABLE_NAME, ORDINAL_POSITION;
如果在测试阶段发现字段类型映射错了,改表结构比改数据容易得多。
第二层:行数校验------数量对不对
这是最基础的校验。但"行数一样"不等于"数据一样",只能证明"没少行",不能证明"每行都对"。
bash
-- 行数校验
SELECT COUNT(*) FROM orders;
第三层:内容校验------值对不对
这才是真正的校验。常见方法有几种:
全量逐行对比:把源库和目标库的数据逐行对比。最可靠,但最慢------如果一张表有上亿行,这种校验本身就可能跑好几个小时。适合核心表,不适合全库。
分块哈希校验 :把大表按主键范围分成多个块,每块计算哈希值,两边对比。如果哈希一致,说明这块数据一样;如果不一样,再在块内逐行定位差异。MySQL 8.0的CHECKSUM TABLE只能算全表哈希,分块校验需要自己实现或用专业工具。
抽样校验:对大表随机抽取部分数据进行逐行对比。速度快,但不能覆盖全部数据。
三、校验工具的选择
自研校验脚本灵活性高,但开发工作量大,且在大数据量下的性能优化需要不少投入。市场上也有一些成熟的工具:
-
pt-table-checksum:Percona Toolkit出品,支持在线校验,对业务影响小,适合MySQL主从/迁移校验。通过在主库执行checksum查询,将结果与从库对比,能发现数据差异。
-
金仓KDC(Kingbase Data Compare):金仓迁移工具链中的数据校验组件,支持全量比对和基于MD5摘要的字段级校验,可在迁移过程中持续对比源库和目标库的数据一致性。与KDTS迁移工具和KFS同步工具协同工作,形成"评估→迁移→同步→校验"的完整闭环。
-
云厂商内置校验:阿里云DTS、腾讯云DTS等云迁移服务通常内置数据校验功能,在迁移完成后自动执行校验并生成报告。
四、校验时机的选择
校验不是"迁移完做一次",需要在迁移的不同阶段分别执行:
| 阶段 | 校验内容 | 方法 |
|---|---|---|
| 全量迁移前 | 表结构、字符集、时区 | 结构对比 |
| 全量迁移后 | 行数、关键字段哈希 | 行数校验 + 抽样校验 |
| 增量同步期间 | 定期校验点(每小时/每天) | 分块哈希校验 |
| 灰度切换前 | 全量分块哈希校验 | 全库分块哈希 |
| 切换后 | 核心业务查询结果对比 | 业务验证 |
五、发现不一致之后怎么办?
校验的目的是"发现问题",但发现问题之后怎么处理,是另一个关键问题。
处理策略一:重新同步
如果差异较小(几百行),可以手动修复或重新同步差异数据。专业迁移工具通常支持"增量补录"------只同步差异部分,不需要从头再来。
处理策略二:重新全量迁移
如果差异较大(超过5%),说明同步方案本身有问题,直接重新全量迁移比逐条修复更可靠。这也解释了为什么全量迁移阶段必须支持断点续传。
处理策略三:业务层补偿
某些差异是"可接受的"------比如时间戳差了几毫秒、统计报表不依赖精确到秒的数据。这类差异可以标记为"已知差异",不阻塞切换。但需要在切换前明确告知业务方,并获得确认。
六、总结
数据一致性校验是迁移项目的"最后一道防线"。三道防线缺一不可:
-
结构要对:表结构、索引、约束、字符集、时区------全对齐
-
数量要对:行数一致是底线,但不能只做行数校验
-
内容要对:分块哈希校验 + 抽样校验,确保"搬对了"
校验时机:全量后、增量期间、切换前------三个阶段都要做,发现问题早处理,别等到切换前才第一次校验。
工具选择:小规模项目可以自研脚本或使用开源工具(如pt-table-checksum),大规模核心系统建议采用专业迁移工具链(如金仓KDTS+KDC)的全链路校验能力。
最后记住一句话:数据搬过去了不等于搬对了。 校验是迁移中"最容易被压缩"的环节,但也是"最不能省略"的环节。
小耶在手,SQL 不愁
还有什么想了解的,欢迎留言!小耶一定知无不言言无不尽......我们下次见~