Skip to content

TiDB 从 MySQL 迁移指南

TiDB 兼容 MySQL 协议和语法,支持从 MySQL 数据库迁移数据。本文档介绍从 MySQL 迁移到 TiDB 的完整流程,包括迁移规划、工具选择、迁移步骤和最佳实践。

迁移前准备

1. 评估迁移复杂度

在开始迁移前,需要评估迁移的复杂度:

  • 数据量:评估数据库的大小,确定迁移时间和资源需求
  • 表结构:检查 MySQL 表结构,确认是否兼容 TiDB
  • SQL 语法:检查应用使用的 SQL 语句,确认是否兼容 TiDB
  • 业务影响:评估迁移对业务的影响,确定迁移窗口

2. 环境准备

  • TiDB 集群:部署目标 TiDB 集群,确保版本兼容
  • 迁移工具:准备迁移工具,如 Dumpling + TiDB Lightning、DM(Data Migration)等
  • 测试环境:建立测试环境,验证迁移过程和结果
  • 监控系统:部署监控系统,监控迁移过程和集群状态

3. 兼容性检查

表结构兼容性

sql
-- 检查 MySQL 表结构
SHOW CREATE TABLE <table-name>;

-- 检查外键约束
SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME IS NOT NULL;

-- 检查触发器
SHOW TRIGGERS;

-- 检查存储过程和函数
SHOW PROCEDURE STATUS;
SHOW FUNCTION STATUS;

SQL 语法兼容性

  • TiDB 兼容大部分 MySQL 5.7 和 8.0 的 SQL 语法
  • 不支持的特性包括:存储过程、函数、触发器、外键约束(支持语法,但不强制执行)等
  • 建议使用 TiDB 提供的兼容性检查工具检查 SQL 兼容性

迁移工具选择

1. Dumpling + TiDB Lightning

适合全量迁移,适用于数据量较大的场景:

  • Dumpling:从 MySQL 导出数据,支持多种格式(SQL、CSV 等)
  • TiDB Lightning:快速导入数据到 TiDB,支持并行导入

2. DM(Data Migration)

适合全量 + 增量迁移,支持复杂场景:

  • 支持分库分表迁移
  • 支持增量数据同步
  • 支持数据过滤和转换
  • 支持迁移任务监控和管理

3. MySQL 官方工具

  • mysqldump:适用于小型数据库迁移
  • mysqlpump:MySQL 5.7+ 提供,支持并行导出
  • replication:使用 MySQL 主从复制机制迁移

迁移步骤

1. 使用 Dumpling + TiDB Lightning 迁移

1.1 全量导出 MySQL 数据

bash
# 使用 Dumpling 导出 MySQL 数据
./dumpling \
  -h <mysql-host> \
  -P <mysql-port> \
  -u <mysql-user> \
  -p <mysql-password> \
  --output-dir /path/to/backup \
  --format sql \
  --threads 16 \
  --rows 100000

1.2 导入数据到 TiDB

bash
# 配置 TiDB Lightning
cat > lightning.toml << EOF
[lightning]
# 日志级别
level = "info"
# 后端模式,local 适合导入大量数据
tnd-mode = "local"
# TiDB 连接信息
tidb-host = <tidb-host>
tidb-port = <tidb-port>
tidb-user = <tidb-user>
tidb-password = <tidb-password>
tidb-status-port = <tidb-status-port>
tidb-ttl = 300

[mydumper]
# 数据文件目录
data-source-dir = "/path/to/backup"
EOF

# 运行 TiDB Lightning
./tidb-lightning -config lightning.toml

2. 使用 DM 迁移

2.1 配置 DM

yaml
# dm-master 配置文件
# dm-master.toml
master-addr = "127.0.0.1:8261"
log-file = "dm-master.log"
log-level = "info"

# dm-worker 配置文件
# dm-worker.toml
worker-addr = "127.0.0.1:8262"
master-addr = "127.0.0.1:8261"
log-file = "dm-worker.log"
log-level = "info"

2.2 创建数据源配置

yaml
# source1.yaml
source-id: "source1"
from:
  host: "<mysql-host>"
  port: <mysql-port>
  user: "<mysql-user>"
  password: "<mysql-password>"

2.3 创建迁移任务配置

yaml
# task.yaml
name: "test"
source-id: ["source1"]
target-database:
  host: "<tidb-host>"
  port: <tidb-port>
  user: "<tidb-user>"
  password: "<tidb-password>"

mydumper-config:
  threads: 4
  chunk-size: 64
  rows: 32000

loader-config:
  pool-size: 16
  dir: "loader"

syncers:
  global:
    worker-count: 16
    batch: 100

routes:
  rule-1:
    schema-pattern: "test_db"
    table-pattern: "test_table"
    target-schema: "test_db"
    target-table: "test_table"

filters:
  rule-1:
    schema-pattern: "test_db"
    table-pattern: "test_table"
    events: ["insert", "update", "delete"]
    sql-pattern: ["^DROP", "^ALTER"]
    action: "ignore"

2.4 启动迁移任务

bash
# 添加数据源
dmctl --master-addr=127.0.0.1:8261 operate-source create source1.yaml

# 启动迁移任务
dmctl --master-addr=127.0.0.1:8261 start-task task.yaml

# 查看任务状态
dmctl --master-addr=127.0.0.1:8261 query-status

迁移后验证

1. 数据完整性验证

sql
-- 检查数据行数
SELECT COUNT(*) FROM <table-name>;

-- 检查数据 checksum
CHECKSUM TABLE <table-name>;

-- 随机抽样检查
SELECT * FROM <table-name> ORDER BY RAND() LIMIT 100;

2. 业务功能验证

  • 在测试环境中运行应用,验证业务功能
  • 执行关键查询,验证性能
  • 测试事务功能,验证一致性

3. 性能验证

  • 运行基准测试,比较 MySQL 和 TiDB 的性能
  • 监控 TiDB 集群的资源使用情况
  • 优化查询和配置,确保性能满足要求

迁移最佳实践

1. 迁移前

  • 清理 MySQL 中的无用数据和索引
  • 优化 MySQL 表结构,适应 TiDB 存储模型
  • 备份 MySQL 数据,确保数据安全
  • 在测试环境中进行迁移演练

2. 迁移中

  • 选择业务低峰期进行迁移
  • 监控迁移过程,及时处理问题
  • 对于大表,考虑分批次迁移
  • 确保网络稳定,避免迁移中断

3. 迁移后

  • 优化 TiDB 配置,提高性能
  • 重建索引,优化查询性能
  • 监控 TiDB 集群,确保稳定运行
  • 逐步迁移业务流量,观察效果

4. 增量迁移

  • 使用 DM 工具实现增量数据同步
  • 设置合适的同步延迟,确保数据一致性
  • 监控增量同步状态,及时处理延迟问题
  • 切换业务前,确保增量同步完成

常见问题及解决方案

1. 数据导入速度慢

解决方案

  • 调整 TiDB Lightning 配置,增加并行度
  • 调整 TiDB 配置,如关闭同步提交、调整 raft store 配置等
  • 使用 TiDB Lightning 的 local 模式,绕过 TiDB 服务器直接导入

2. 数据不一致

解决方案

  • 使用 sync-diff-inspector 工具检查数据一致性
  • 重新导入不一致的数据
  • 检查迁移工具的日志,定位问题原因

3. SQL 兼容性问题

解决方案

  • 修改应用代码,使用 TiDB 支持的 SQL 语法
  • 使用 TiDB 提供的兼容性视图和函数
  • 考虑使用中间件,转换不兼容的 SQL 语句

4. 迁移后性能下降

解决方案

  • 优化 TiDB 配置,如调整内存分配、线程数等
  • 优化表结构,如添加合适的索引
  • 优化查询语句,避免全表扫描
  • 考虑使用 TiFlash 加速分析查询

迁移案例

案例1:小型数据库迁移(`< 10GB)

方案:使用 mysqldump + mysql 客户端 步骤

  1. 使用 mysqldump 导出 MySQL 数据
  2. 使用 mysql 客户端导入数据到 TiDB
  3. 验证数据完整性
  4. 测试业务功能

案例2:中型数据库迁移(10GB - 1TB)

方案:使用 Dumpling + TiDB Lightning 步骤

  1. 使用 Dumpling 导出 MySQL 数据
  2. 使用 TiDB Lightning 导入数据到 TiDB
  3. 验证数据完整性
  4. 运行基准测试,优化性能
  5. 逐步迁移业务流量

案例3:大型分库分表迁移(>` 1TB)

方案:使用 DM 工具 步骤

  1. 配置 DM 集群
  2. 创建数据源和迁移任务
  3. 执行全量迁移
  4. 启动增量同步
  5. 验证数据一致性
  6. 切换业务流量到 TiDB
  7. 停止增量同步

常见问题(FAQ)

Q1: TiDB 支持 MySQL 8.0 的特性吗?

A1: TiDB 支持大部分 MySQL 8.0 的特性,包括窗口函数、CTE(公共表表达式)、JSON 增强功能等。但不支持存储过程、函数、触发器等特性。

Q2: 如何处理 MySQL 中的外键约束?

A2: TiDB 支持外键约束语法,但不强制执行。建议在迁移前移除外键约束,或者在应用层实现外键逻辑。

Q3: 迁移过程中如何最小化业务影响?

A3: 可以使用以下方法最小化业务影响:

  • 使用增量迁移工具,实现近实时同步
  • 选择业务低峰期进行迁移
  • 采用灰度发布方式,逐步迁移业务流量
  • 准备回滚方案,确保可以快速恢复

Q4: 如何迁移 MySQL 中的用户和权限?

A4: TiDB 支持 MySQL 的用户和权限系统,可以使用以下方法迁移:

  • 使用 mysqldump 导出 mysql 数据库
  • 手动创建用户和权限
  • 使用脚本批量迁移用户和权限

Q5: 迁移后如何优化 TiDB 性能?

A5: 可以从以下几个方面优化:

  • 调整 TiDB 配置,如内存分配、线程数等
  • 优化表结构,如添加合适的索引
  • 优化查询语句,避免全表扫描
  • 考虑使用 TiFlash 加速分析查询
  • 配置合适的存储引擎参数

Q6: 如何监控迁移过程?

A6: 可以使用以下工具监控迁移过程:

  • DM 自带的监控功能
  • Prometheus + Grafana 监控 TiDB 集群状态
  • 迁移工具的日志文件
  • 自定义监控脚本,监控迁移进度和状态