一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何验证MySQL数据迁移后的前后数据一致性和完整性?

时间:2026-08-11 08:12:49 编辑:袖梨 来源:一聚教程网

迁移后第一件事是执行COUNT(*)和COUNT(DISTINCT id)比对,可快速暴露主键NULL、过滤条件遗漏等问题;大表必须用pt-table-checksum分块校验,需确保连接主库、ROW格式binlog、有主键、从库同步正常。

直接比对行数和主键去重数最省事,但别只信这个

迁移后第一件事不是跑哈希,而是执行 COUNT(*)COUNT(DISTINCT id)。很多问题在这一步就暴露了:比如目标库因字符集不兼容把某几条记录写成 NULL 导致主键冲突被跳过,或者迁移脚本漏掉了 WHERE is_deleted = 0 条件,结果行数对得上但数据残缺。

注意三点:

  1. COUNT(*) 必须在相同过滤条件下执行——如果源库导出时加了 WHERE created_at >= '2024-01-01',目标库也要查同一范围
  2. 对无主键表,COUNT(DISTINCT ...) 会失效,改用业务唯一字段(如订单号)或组合字段(如 user_id, order_time
  3. 某些 ORM 或中间件会在 INSERT 时自动补默认值,导致目标库多出几行;反过来,源库的 TINYINT(1) 被目标库映射为 BOOLEAN 后可能丢精度,COUNT 看不出差异

用 CHECKSUM TABLE 快速扫一遍小表,但千万避开浮点字段

CHECKSUM TABLE 是 MySQL 内置命令,适合单表行数 ≤ 500 万的场景。它计算的是整表数据页的 CRC32 值,快、轻量、不用额外工具。

但它有硬伤:

  1. 遇到 FLOATDOUBLE 字段,不同版本 MySQL 对二进制表示的处理可能不同,哪怕值一样,校验和也会变——这时必须跳过该表,改用逻辑字段拼接哈希
  2. 命令会加读锁,大表执行期间会阻塞查询,务必在低峰期操作,或先连从库验证
  3. 它只校验数据行,不包含索引、AUTO_INCREMENT 值、外键约束,结构差异要另查 SHOW CREATE TABLE

大表必须用 pt-table-checksum 分块校验,否则根本跑不完

单表超千万行时,CHECKSUM TABLE 和手写 MD5(CONCAT(...)) 都会内存溢出或锁表太久。pt-table-checksum 的核心价值是分块 + 复制流 + 事务快照,能准确定位到哪几行不一致。

启动前确认四件事:

  1. 连接的是源库(主库),且 binlog_format = ROW,否则工具无法生成可靠校验点
  2. 校验用户要有 SELECTPROCESSSUPER 权限,以及对 percona.checksums 表的写权限
  3. 每张待校验表必须有主键或非空唯一索引——没主键的表会被跳过,得手动抽样核对
  4. 目标库不能处于 SQL_THREAD 停止状态,Seconds_Behind_Master 应尽量接近 0

最小安全命令示例:

pt-table-checksum --host=master_ip --user=check_user --password=xxx --databases=mydb --replicate=percona.checksums --chunk-size=1000 --ignore-databases="information_schema,mysql"

抽样比对字段值时,COALESCE 和显式字段列表不能少

全字段拼接 MD5(CONCAT(*)) 是陷阱。NULL 值、空格、时区转换、字符集隐式截断(比如 emoji 在 utf8 下变 ?)都会让哈希值不同,但实际业务可能完全不受影响。

正确做法是:

  1. 只选业务强依赖字段,比如订单表重点比 order_noamountstatuscreated_at
  2. COALESCE(field, '') 统一 NULL 处理,避免因 NULL 参与拼接导致哈希错乱
  3. 按主键分段抽样:头部(ORDER BY id LIMIT 100)、中部(LIMIT 100000, 100)、尾部(ORDER BY id DESC LIMIT 100),覆盖不同数据分布
  4. 时间字段务必用 CONVERT_TZ(created_at, '+00:00', '+08:00') 显式转成统一时区再比,否则源库 UTC、目标库 CST 会导致值差 8 小时

真正容易被忽略的,是那些“看起来一样”的字段:DECIMAL 精度丢失、JSON 字段键顺序不同、TEXT 字段末尾空格是否保留——这些差异不会影响 COUNTCHECKSUM TABLE,但会让业务逻辑出错。

热门栏目