CHECKSUM TABLE 是 MySQL 中最轻量的单表一致性校验方式,仅适用于 MyISAM 表;InnoDB 表在 5.7+ 默认 strict_crc32 下返回 NULL,且不校验元数据与索引,执行时会锁表。
MySQL 用 CHECKSUM TABLE 快速验证整表一致性
对单表做迁移后校验,checksum table 是最轻量、最直接的方式。它不依赖主键或排序,直接基于存储引擎内部行数据计算 32 位整数校验和,适合快速判断「物理内容是否完全一致」。
常见错误现象:CHECKSUM TABLE 返回 NULL —— 多半是表用了 InnoDB 且开启了 innodb_checksum_algorithm=strict_crc32(5.7+ 默认),此时该命令不支持;换成 MyISAM 表或降级算法才能用。
- 只适用于
MyISAM表,InnoDB表在多数现代版本中返回NULL或报错 - 不校验元数据(如列顺序、字符集)、不校验索引结构,只比对行数据块原始字节
- 执行时会锁表(尤其大表),生产环境慎用;建议在从库或低峰期运行
- 示例:
CHECKSUM TABLE user_info;→ 返回类似3847291034的整数,两边对比即可
PostgreSQL 用 md5(string_agg(...)) 按行聚合校验
PG 没有内置表级 checksum 命令,但可以用 string_agg + md5 构造确定性哈希:把每行转成统一格式字符串再拼接,最后算 MD5。关键在于「格式必须稳定」——字段顺序、NULL 表示、类型转换都不能变。
容易踩的坑:直接 SELECT md5(*) 报错;用 row_to_json 会因字段顺序/键名大小写/浮点精度导致哈希不一致;ORDER BY 缺失则结果不可重现。
- 必须显式列出所有列,并用
COALESCE(col::text, 'NULL')统一 NULL 表示 - 数值类字段建议转
::text,避免1.0和1被视为不同 - 必须加
ORDER BY(推荐主键或唯一索引列),否则聚合顺序随机 - 示例:
SELECT md5(string_agg(t::text, E'\n')) FROM (SELECT id, COALESCE(name, 'NULL'), age::text FROM user_info ORDER BY id) t;
跨数据库或超大表:用 pt-table-checksum 分块校验
当源目标库类型不同(比如 MySQL → ClickHouse),或单表超 10GB,全表拉取再哈希会 OOM 或超时。pt-table-checksum(Percona Toolkit)能自动分块、并行、断点续校验,且生成可复现的 chunk-level checksum 结果表。
典型失败场景:主从延迟高时校验结果漂移;目标库无对应表结构导致 SQL 执行失败;时间戳字段未设为 NOT NULL 引发分块边界错乱。
- 必须确保源库开启 binlog,且
binlog_format = ROW - 目标库需提前建好同名空表,字段类型兼容(如 MySQL
DATETIME对应 PGTIMESTAMP WITHOUT TIME ZONE) - 用
--chunk-size控制单次扫描行数(建议 1000–10000),避免长事务阻塞 - 校验后查
percona.checksums表,diff_cnt > 0即表示该 chunk 数据不一致
导出 CSV 后本地算 checksum:小心换行与编码陷阱
如果只能导出 CSV 再比对(例如云数据库不开放直连),别直接 md5sum data.csv —— 导出工具默认加 BOM、字段含换行符、Windows 换行符 \r\n 都会让哈希失效。
真实问题:MySQL mysqldump --tab 输出的文件,字段间是 tab,但文本内换行没转义;Python pandas to_csv 默认 line_terminator='\n',而 Excel 打开显示正常,实际内容已污染。
- 导出时强制指定编码:
mysqldump --default-character-set=utf8mb4,避免 BOM - 用
sed 's/\r$//'清理 Windows 换行,再用tr '\n' '\n' | md5sum(确保换行符统一) - 字段含换行或逗号?改用 TSV(tab 分隔),并用
awk -F'\t' '{print $0}'重输出保证格式干净 - 更稳的做法:导出为 JSON Lines(每行一个 JSON 对象),再
jq -c . | md5sum
真正麻烦的不是算哈希,而是让两套环境下的「同一行数据」在序列化时产生完全相同的字节流。字段顺序、NULL 处理、时区、浮点精度、换行符——任何一个环节没对齐,checksum 就只是个安慰数字。










