0
0
0
0
博客/.../

多个MySQL实例合库迁移时,怎样处理主键冲突和表结构差异?

 老门menmen  发表于  2026-08-20

多个 MySQL 实例跑着同样的业务 schema,可能是按租户分的、按地域分的、或者历史上分库分表后遗留的。现在要合到一个分布式数据库里,两个问题马上浮出水面:主键冲突怎么办?表结构不一样怎么办?

这两个问题处理不好,迁移后的数据质量和应用兼容性都会出问题。

主键冲突:合库的第一道坎

多个实例各自维护自增主键,ID 一定会重复。实例 A 的用户 ID=1 和实例 B 的用户 ID=1 指向不同的用户,直接合并就会冲突。

方案一:ID 重写

给每个源实例分配一个唯一的 ID 段前缀,在迁移过程中重写所有主键和外键。比如实例 A 的 ID 加 10000000 前缀,实例 B 加 20000000 前缀。

优点: 逻辑清晰,合并后 ID 不会冲突。缺点: 需要重写所有外键关联,工作量大且容易遗漏。如果有跨实例的关联数据,还需要处理引用关系的更新。

方案二:替换为分布式 ID

放弃原有自增主键,迁移时统一生成新的分布式唯一 ID(如 UUID 或雪花 ID)。

优点: 彻底解决冲突问题,不需要分段管理。缺点: 所有引用这些主键的地方都要同步更新,包括缓存、日志、外部系统中的 ID。如果 ID 被其他系统持久化了,改起来代价很大。

方案三:复合主键

在原主键基础上增加一个实例标识字段,组成复合主键。比如 (instance_id, user_id)。

优点: 不需要重写 ID,迁移简单。缺点: 改变了主键结构,应用层的查询逻辑需要适配,所有按原单字段主键查询的地方都要改。

实际选择

三种方案没有绝对的好坏,取决于业务中 ID 的使用范围:

  • 如果 ID 只在数据库内部使用,方案一或方案二都可以
  • 如果 ID 被外部系统广泛引用(比如给前端展示、给第三方对接),方案二的改造成本最高
  • 如果表之间有大量外键关联,方案三的改造量相对可控

表结构差异:看似相同实则不同

多个实例运行久了,表结构往往会逐渐分化。可能是某个实例加了索引、改了字段长度、或者多了几张新表。

差异的常见来源

  • 索引差异: 某个实例为了优化特定查询加了索引,其他实例没有
  • 字段差异: 字段长度、默认值、NOT NULL 约束在不同实例间不一致
  • 表级差异: 某个实例多了几张业务表,或者某些表在某些实例上根本没用
  • 字符集差异: 不同实例的默认字符集可能不同,导致同名字段的实际存储编码不同

处理策略

第一步,做一次全量 schema 对比。 用工具(如 pt-table-diff、mysqldiff 或自研脚本)对比所有实例的 DDL,输出差异清单。这一步不能跳过,靠人工比对在表多了之后根本不现实。

第二步,确定目标 schema。 以哪个实例为准?还是取并集?通常建议以最完整的实例为基础,把其他实例的差异逐个合并进来。

第三步,处理冲突。 同一个字段在不同实例中定义不同时(比如一个是 VARCHAR(100),一个是 VARCHAR(255)),取大的那个。索引差异取并集——多出来的索引可以事后评估是否需要保留。

第四步,迁移前统一源 schema。 在正式迁移前,先把所有源实例的 schema 更新到一致状态。这比迁移后再处理结构差异要简单得多。

数据层面的额外问题

数据去重

多个实例可能存在需要去重的数据。比如同一个用户在不同实例中各有一条记录(用户注册时选了不同实例),合并时需要识别并去重。去重规则需要业务方参与定义。

数据一致性

迁移过程中,源实例仍然在接收写入。需要用增量同步工具(如 MySQL 的 binlog 同步)保证迁移窗口内的数据一致性。多个源同时增量同步到同一个目标,同步工具需要支持多源合并。

迁移顺序

如果实例之间有数据依赖(比如订单实例依赖用户实例的数据),需要按依赖顺序迁移,先迁移被依赖的表。

TiDB 在 MySQL 合库迁移中的对应能力

TiDB 兼容 MySQL 协议,天然适合多个 MySQL 实例合并到一个 TiDB 集群。TiDB 的 DM 工具支持多个 MySQL 源同时同步到同一个 TiDB 集群,可以直接处理多源增量同步。对于主键冲突,TiDB 支持 AUTO_RANDOM 特性来生成分布式唯一 ID,避免写入热点。建议在合库迁移前用 DM 工具做一轮小规模 POC,验证多源同步和主键处理策略。

如果你正在规划多个 MySQL 实例的合库迁移,建议先做一次全量 schema 对比和主键使用范围评估,再结合目标数据库的多源同步能力确定迁移方案。

0
0
0
0

版权声明:本文为 TiDB 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
暂无评论