为什么选择TiDB作为MySQL迁移目标
TiDB兼容MySQL协议,应用层代码改动极小,同时提供水平扩展、HTAP混合负载和自动分片能力。对于面临单机MySQL性能瓶颈的团队,TiDB是最自然的演进路径——不用重写SQL,不用切换驱动,甚至ORM框架无感知。但”兼容”不等于”完全一致”,迁移过程中需要关注语法差异、字符集、自增ID等细节。
迁移前评估:兼容性检查清单
迁移前务必完成以下检查:
# 1. 检查存储引擎
# TiDB不支持MyISAM,需确认所有表为InnoDB
SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE
FROM information_schema.TABLES
WHERE ENGINE != 'InnoDB' AND TABLE_SCHEMA NOT IN ('mysql','sys','information_schema');
# 2. 检查自增列使用
# TiDB自增ID不连续(AUTO_ID_CACHE机制),业务不能依赖ID连续性
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME
FROM information_schema.COLUMNS
WHERE EXTRA LIKE '%auto_increment%'
AND TABLE_SCHEMA NOT IN ('mysql','sys');
# 3. 检查存储过程和触发器
# TiDB不支持存储过程、触发器、自定义函数
SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = 'your_db';
# 4. 检查外键约束
# TiDB默认不启用外键检查
SELECT TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME
FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';
如果发现存储过程或触发器,需要在应用层重写等价逻辑。自增ID依赖需要改为分布式ID生成(Snowflake等)。
数据全量迁移:Dumpling + TiDB Lightning
小数据量(<100GB)用Dumpling导出+Lightning导入,速度快且操作简单:
# Step 1: Dumpling导出MySQL数据
./dumpling -h mysql-host -P 3306 -u root -p 'password' -t 8 \ # 8线程导出
-F 256MB \ # 单文件256MB
-o /data/mysql_dump/ --database db_production
# Step 2: TiDB Lightning导入
./tidb-lightning --config lightning.toml
# lightning.toml 核心配置
[lightning]
level = "info"
check-requirements = true
[tikv-importer]
backend = "local" # local模式性能最高
sorted-kv-dir = "/data/sorted_kv"
[mydumper]
data-source-dir = "/data/mysql_dump"
[checkpoint]
enable = true # 断点续传
大数据量(>100GB)推荐使用local backend模式,Lightning直接写SST文件绕过TiDB事务层,导入速度可达500GB/hour。
增量数据同步:DM持续复制
全量迁移后,需要增量同步MySQL的binlog到TiDB,保持数据一致直到切换时刻:
# DM task配置文件
name: "mysql-to-tidb-sync"
task-mode: "all" # all=全量+增量
source-config:
source-id: "mysql-prod"
enable-gtid: true # 启用GTID确保一致性
target-config:
host: "tidb-host"
port: 4000
user: "root"
password: ""
mysql-instances:
- source-id: "mysql-prod"
block-allow-list: "bw-list"
block-allow-list:
bw-list:
do-dbs: ["db_production"]
ignore-tables:
- db_production.log_table_* # 忽略日志表
启动同步任务并监控延迟:
# 启动任务
./dmctl start-task task.yaml
# 检查同步状态
./dmctl query-status mysql-to-tidb-sync
# 输出示例:
# SOURCE: mysql-prod
# STATUS: Running
# SYNCED: 0s ← 延迟为0表示已追平
同步延迟稳定在1秒以内时,可以进入切换准备阶段。
数据一致性校验
切换前必须做全量数据校验,确保MySQL和TiDB数据完全一致:
# 使用sync-diff-inspector
./sync-diff-inspector --config diff.toml
# diff.toml
[data-sources]
[data-sources.mysql]
host = "mysql-host"
port = 3306
[data-sources.tidb]
host = "tidb-host"
port = 4000
[task]
output-dir = "/data/diff_result"
source = "mysql"
target = "tidb"
# 抽样校验大表(全量校验耗时太长)
[task.table-rules]
[task.table-rules.big-table]
schema = "db_production"
table = "orders"
sample = 1000 # 每千行抽一行校验
校验结果会输出到diff_result目录,包含不一致的数据行和修复SQL。发现不一致需要排查原因后修复并重新校验。
灰度切换与回滚方案
切换流程分三步走:
# Phase 1: 双写验证(1-2天)
# 应用层同时写MySQL和TiDB,读仍走MySQL
# 对比双写后的数据一致性
# Phase 2: 读流量灰度切换
# 10%读流量 → TiDB,观察1小时
# 50%读流量 → TiDB,观察2小时
# 100%读流量 → TiDB
# Phase 3: 写流量切换
# 停止DM同步,所有读写切到TiDB
# 保留MySQL为只读模式7天作为回滚保障
回滚触发条件和操作:
# 回滚触发条件:
# - TiDB查询错误率 > 1%
# - 关键业务查询延迟 > MySQL 3倍
# - 数据不一致且无法快速修复
# 回滚步骤:
# 1. 修改应用配置指向MySQL
# 2. 用sync-diff-inspector反向校验差异数据
# 3. 将TiDB上增量数据导出导入MySQL
# 4. 恢复MySQL读写模式
# 5. 全链路验证
MySQL到TiDB的迁移核心在于:迁移前做足兼容性检查,迁移中保持增量同步和数据校验,切换时灰度推进并保留回滚通道。兼容MySQL协议降低了迁移门槛,但不等于零成本迁移——存储过程、自增ID、存储引擎差异都需要逐一排查处理。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/mysql-dao-tidb-shu-ju-ku-ping-hua-qian-yi-shi-zhan-shu-ju/