分布式数据库不支持全局单调auto_increment,LAST_INSERT_ID()等依赖可能出错;需检查并替换不兼容SQL、外键、事务及字符集行为。

检查 auto_increment 主键是否被业务强依赖
分布式数据库(如 TiDB、OceanBase、Vitess)多数不支持全局单调递增的 auto_increment,而是用分段/时间戳+节点ID等方式生成主键。如果业务代码里写了类似 INSERT ...; SELECT LAST_INSERT_ID() 后立刻做关联查询或幂等判断,很可能出错——因为新主键可能跳变、非连续,甚至在跨节点写入时出现短暂乱序。
实操建议:
- 搜索代码库中所有
LAST_INSERT_ID()、@@IDENTITY、mysql_insert_id()等调用,确认是否用于逻辑校验或下游通知 - 检查是否假设主键“随时间递增”来实现分页(如
WHERE id > ? ORDER BY id LIMIT 10),这在分布式下可能漏数据 - 若必须保留自增语义,可改用
BIGINT+ 分布式 ID 生成器(如snowflake),但需改造插入逻辑,不能依赖 MySQL 的AUTO_INCREMENT行为
识别并替换不兼容的 SQL 模式和函数
MySQL 的 GROUP_CONCAT、JSON_EXTRACT、INSERT ... ON DUPLICATE KEY UPDATE 在不同分布式数据库中支持程度差异很大。比如 TiDB 5.4+ 才完整支持 ON DUPLICATE KEY UPDATE,而某些分库中间件(如 ShardingSphere)会直接拒绝该语法;SELECT ... FOR UPDATE 在跨分片场景下可能降级为全表锁或报错 Unsupported operation。
实操建议:
- 用
mysqldump --no-data导出建表语句,逐行检查ENGINE=InnoDB是否被替换为对应分布式库要求的引擎(如 TiDB 不认ENGINE,OceanBase 要求ENGINE = InnoDB但实际走自己的存储层) - grep 项目 SQL 文件中的
GROUP_CONCAT、DATE_ADD(NOW(), INTERVAL ...)、IFNULL等,确认目标库是否支持相同参数行为(例如 TiDB 的NOW()默认不带微秒,MySQL 可能有) - 把
INSERT ... ON DUPLICATE KEY UPDATE拆成先SELECT再INSERT/UPDATE,或改用REPLACE INTO(注意它会触发 DELETE+INSERT,影响自增 ID 和触发器)
评估外键与事务边界是否匹配分片策略
绝大多数分布式数据库不支持跨分片外键约束(foreign key),也不支持跨分片两阶段提交(2PC)的强一致性事务。如果你的表 A 和表 B 通过 user_id 关联,但按 user_id 分片后分别落在不同节点,那 ALTER TABLE B ADD FOREIGN KEY (user_id) REFERENCES A(user_id) 会失败,或者被静默忽略。
实操建议:
- 导出所有
SHOW CREATE TABLE结果,提取含FOREIGN KEY的建表语句,标记哪些外键涉及跨分片字段(即关联字段不是分片键本身) - 检查事务中是否同时更新多个分片的表(如转账:扣 A 用户余额 + 增 B 用户余额),这类事务在分布式库中只能是最终一致,需补监控和对账逻辑
- 把外键约束从 DDL 层移到应用层校验,或改用冗余字段(如在订单表存用户昵称)减少实时 JOIN 需求
验证字符集与排序规则的实际行为差异
MySQL 的 utf8mb4_unicode_ci 是大小写不敏感、口音不敏感的排序规则,但 TiDB 默认使用 utf8mb4_bin,OceanBase 默认用 utf8mb4_general_ci,排序和比较结果可能不同。比如 SELECT * FROM user WHERE name = 'Alice' 在 MySQL 中能命中 'alice',但在 TiDB 的 bin 规则下就查不到。
实操建议:
- 运行
SHOW VARIABLES LIKE 'collation%'对比源库与目标库的collation_server、collation_database,重点看是否一致 - 对关键业务字段(如登录名、邮箱、商品标题)执行测试查询:
SELECT name FROM t WHERE name COLLATE utf8mb4_unicode_ci = 'xxx',确认目标库是否支持显式指定 collation - 建表时显式声明
COLLATE utf8mb4_unicode_ci(如果目标库支持),避免依赖默认值;不推荐全局改 server 级 collation,容易引发隐式转换性能问题
真正卡住迁移的,往往不是大表同步本身,而是某张日志表用了 TEXT 字段加全文索引,而目标库根本不支持分布式全文检索——这种细节得一张表一张表过,不能靠“基本兼容”蒙混过关。


















