tidb 兼容绝大多数 mysql sql,但需预检不兼容点:用 tiup dmctl check-task 扫描语法,重点处理临时表、特定 ddl、字符集排序规则及 json 函数差异,并拆分批量 ddl 操作。

绝大多数 MySQL 5.7/8.0 的 SQL 能直接在 TiDB 上运行,但关键在于识别并处理那不到 5% 的“不兼容点”——不是靠试错,而是靠预检 + 场景化适配。
用 tiup dmctl check-task 做迁移前语法扫描
这个命令会加载你的 MySQL 慢日志或 DDL 文件,自动标出 TiDB 不支持的语法结构。它比人工 grep 更可靠,因为会结合上下文判断(比如 CREATE TABLE ... AS SELECT 在 TiDB 中完全不支持,但工具能准确定位到具体语句行)。
- 必须提前导出线上执行过的全部 DDL 和高频慢 SQL(尤其含
INSERT ON DUPLICATE KEY UPDATE、REPLACE INTO的语句) - 注意:
check-task不检查存储过程和触发器——这两类对象 TiDB 6.x 仍明确不支持,需业务层重写 - 输出中若出现
unsupported syntax: CREATE TEMPORARY TABLE,说明有临时表逻辑,得改造成普通表 + 生命周期管理
重点盯住这三类 MySQL 特有语法
TiDB 兼容的是“行为语义”,不是“字面语法”。以下写法看似一样,实际执行效果可能不同:
-
AUTO_INCREMENT:TiDB 支持,但多个 TiDB server 分配的 ID 不连续;混用显式插入值和自增会导致Duplicate entry错误 -
SELECT ... FOR UPDATE:仅在开启悲观事务模式(SET tidb_txn_mode = 'pessimistic')后才等效于 MySQL;默认乐观事务下该语句无锁 -
JSON_CONTAINS等 JSON 函数:TiDB 6.5+ 支持大部分,但JSON_TABLE()和 MySQL 8.0 新增的路径操作符(如**)仍不支持
字符集与排序规则不能只看 utf8mb4
虽然都用 utf8mb4,但 TiDB 默认使用 utf8mb4_bin 排序规则,而 MySQL 5.7 默认是 utf8mb4_general_ci。这意味着:
-
WHERE name = 'Alice'在大小写敏感场景下结果可能不同 - 索引失效风险:如果应用依赖
_ci规则做模糊匹配,迁移到 TiDB 后需显式加COLLATE utf8mb4_general_ci - 建表时最好统一指定:
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci(推荐,更接近 MySQL 行为)
DDL 批量操作必须拆开执行
TiDB 不支持一条 ALTER TABLE 里同时增列、改列、删列。例如这条 MySQL 常见语句:
ALTER TABLE orders ADD COLUMN remark VARCHAR(255), MODIFY amount DECIMAL(12,2), DROP COLUMN old_flag;
在 TiDB 中会报错 Unsupported multi-schema-change。必须拆成三条独立语句,且每条之间要等 ADMIN SHOW DDL JOBS 显示完成再执行下一条。
最容易被忽略的是:某些 ORM 自动生成的 DDL(如 Django 的 makemigrations)会默认合并操作,需手动拆解或配置 ORM 关闭合并行为。











