MySQL到TiDB数据库平滑迁移实战:数据同步、切换演练与回滚方案

为什么选择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/

(0)
小编小编
上一篇 3小时前
下一篇 3小时前

相关推荐