1. 概述
1.1 迁移目标
将腾讯云数据库(以 TencentDB for MySQL 为主要场景)平滑迁移至 TiDB 分布式数据库,确保数据一致性、业务可用性和迁移过程的可控性。
1.2 TiDB 核心特性回顾
| 特性 | 说明 |
|---|---|
| 水平扩展 | 计算与存储分离,可独立扩容 TiDB / TiKV / PD 节点 |
| 分布式事务 | 基于 Percolator 模型的乐观/悲观事务,支持 ACID |
| MySQL 兼容 | 兼容 MySQL 5.7 协议和大部分语法,迁移成本低 |
| HTAP | 同时支持 OLTP 和 OLAP 场景,内置 TiFlash 列存引擎 |
| 高可用 | 基于 Raft 的多副本机制,自动故障转移 |
1.3 迁移总体流程
评估分析 → 环境准备 → 方案设计 → 全量迁移 → 增量同步 → 数据校验 → 业务切换 → 观察优化
2. 迁移前评估
2.1 兼容性评估
2.1.1 不支持的特性(需改造)
| 类别 | 具体内容 | 改造建议 |
|---|---|---|
| 存储引擎 | MyISAM 表 | 全部转为 InnoDB |
| 存储过程/函数 | TiDB 支持有限 | 改造成应用层逻辑或使用 TiDB 兼容写法 |
| 触发器 | 不支持 | 改为应用层实现 |
| 外键 | 不支持(可建但不生效) | 应用层保证约束 |
| 全文索引 | 不支持 | 使用 Elasticsearch 等外部方案 |
| 空间索引 | 不支持 | 使用 PostGIS 等替代 |
| SELECT ... FOR UPDATE 跨分片 | 部分场景不支持 | 改用悲观事务模式 |
| 分区表 | 部分分区类型不支持 | 评估后使用 HASH/RANGE 分区 |
| 字符集 | 仅支持 utf8 / utf8mb4 | 确认所有表字符集统一 |
2.1.2 SQL 兼容性检查
-- 在源库执行,检查不兼容的 SQL 模式
SELECT @@sql_mode;
SELECT @@innodb_strict_mode;
SELECT @@explicit_defaults_for_timestamp;
关键 SQL 模式建议:
-- TiDB 建议的 sql_mode
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
2.1.3 使用 TiDB 官方工具检查
# 下载并运行 tidb-toolkit 中的 compatibility checker
# 方式一:使用 Dumpling 导出表结构后用 mydumper 检查
# 方式二:使用 TiDB Dashboard 的 SQL 分析功能
# 在 TiDB 集群部署后,通过 Dashboard 观察慢查询和 SQL 兼容性
2.2 数据规模评估
-- 统计源库核心指标
-- 总数据量
SELECT
table_schema AS '数据库',
ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) AS '数据大小(GB)',
COUNT(*) AS '表数量'
FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys')
GROUP BY table_schema
ORDER BY SUM(data_length + index_length) DESC;
-- 大表识别(超过 1000 万行)
SELECT
table_schema,
table_name,
table_rows,
ROUND((data_length + index_length) / 1024 / 1024 / 1024, 2) AS size_gb
FROM information_schema.tables
WHERE table_rows > 10000000
AND table_schema NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys')
ORDER BY table_rows DESC;
2.3 业务特征评估
| 评估维度 | 评估方法 | 关键指标 |
|---|---|---|
| QPS/TPS | 腾讯云监控面板 / SHOW GLOBAL STATUS |
峰值 QPS、TPS |
| 热点表/行 | 慢查询日志 + 腾讯云 DBbrain | Top 10 热点表 |
| 事务复杂度 | 业务方梳理 | 大事务、长事务数量 |
| 读写比例 | SHOW GLOBAL STATUS LIKE 'Com%' |
读多写少/均衡/写多读少 |
| 连接数 | 腾讯云控制台 | 峰值连接数 |
2.4 TiDB 集群规模规划
经验公式:TiDB 所需资源约 = 源库资源 + 30% 冗余
| 节点类型 | CPU | 内存 | 磁盘 | 数量 | 备注 |
|---|---|---|---|---|---|
| TiDB Server | 8-16 核 | 16-32 GB | 100 GB SSD | 2-3 台 | 无状态,可水平扩展 |
| PD Server | 4-8 核 | 8-16 GB | 100 GB SSD | 3 台 | 奇数个,推荐 3 或 5 |
| TiKV Server | 16-32 核 | 32-64 GB | NVMe SSD(数据量×3/副本数) | 3+ 台 | 存储节点,资源消耗最大 |
| TiFlash(可选) | 16-32 核 | 32-64 GB | NVMe SSD | 1+ 台 | 列存副本,AP 场景必备 |
| 监控 | 4-8 核 | 8-16 GB | 200 GB SSD | 1 台 | Prometheus + Grafana |
3. 环境准备
3.1 TiDB 集群部署
3.1.1 使用 TiUP 部署(推荐)
# 1. 安装 TiUP
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
source ~/.bashrc
# 2. 编写拓扑文件 topology.yaml
cat > topology.yaml << 'EOF'
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/data/tidb-deploy"
data_dir: "/data/tidb-data"
pd_servers:
- host: 10.0.1.1
- host: 10.0.1.2
- host: 10.0.1.3
tidb_servers:
- host: 10.0.2.1
port: 4000
status_port: 10080
- host: 10.0.2.2
port: 4000
status_port: 10080
tikv_servers:
- host: 10.0.3.1
port: 20160
status_port: 20180
config:
server.labels: { host: "tikv-1" }
- host: 10.0.3.2
port: 20160
status_port: 20180
config:
server.labels: { host: "tikv-2" }
- host: 10.0.3.3
port: 20160
status_port: 20180
config:
server.labels: { host: "tikv-3" }
monitoring_servers:
- host: 10.0.4.1
grafana_servers:
- host: 10.0.4.1
alertmanager_servers:
- host: 10.0.4.1
EOF
# 3. 部署集群
tiup cluster deploy tidb-prod v7.5.1 ./topology.yaml --user root -p
# 4. 启动集群
tiup cluster start tidb-prod
# 5. 查看集群状态
tiup cluster display tidb-prod
3.1.2 TiDB 关键参数配置
-- TiDB 参数调优(连接 TiDB 后执行)
-- 开启悲观事务模式(推荐迁移初期使用)
SET GLOBAL tidb_txn_mode = 'pessimistic';
-- 事务大小限制
SET GLOBAL tidb_mem_quota_query = 8 << 30; -- 单条 SQL 内存限制 8GB
SET GLOBAL txn-total-size-limit = 100 << 30; -- 单个事务大小限制 100GB
-- 批量操作优化
SET GLOBAL tidb_dml_batch_size = 20000;
SET GLOBAL tidb_batch_commit = 1;
SET GLOBAL tidb_enable_amend_pessimistic_txn = 1; -- 悲观事务自动重试
-- GC 配置
UPDATE mysql.tidb SET VARIABLE_VALUE = '10m' WHERE VARIABLE_NAME = 'tikv_gc_life_time';
3.2 源库(腾讯云)准备
3.2.1 创建迁移专用账号
-- 在腾讯云 MySQL 实例上执行
-- 创建迁移专用账号(需从 TiDB 集群 IP 访问)
CREATE USER 'tidb_migration'@'%' IDENTIFIED BY 'StrongPassword123!';
-- 授予必要权限
GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT,
LOCK TABLES, PROCESS ON *.* TO 'tidb_migration'@'%';
-- TiCDC / DM 需要的权限
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX
ON *.* TO 'tidb_migration'@'%';
FLUSH PRIVILEGES;
3.2.2 源库参数检查与调整
-- 确保 Binlog 开启且格式为 ROW
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'binlog_format'; -- 必须为 ROW
SHOW VARIABLES LIKE 'binlog_row_image'; -- 建议 FULL
-- 如果不是 ROW 格式,在腾讯云控制台修改参数:
-- binlog_format = ROW
-- binlog_row_image = FULL
-- 检查 server_id(TiCDC 同步需要)
SHOW VARIABLES LIKE 'server_id'; -- 确保有唯一值
-- GTID 检查
SHOW VARIABLES LIKE 'gtid_mode'; -- 建议开启
SHOW VARIABLES LIKE 'enforce_gtid_consistency';
3.3 网络连通性
┌──────────────────┐ ┌──────────────────┐
│ 腾讯云 MySQL │ ────▶ │ TiDB 集群 │
│ (源数据库) │ 专线/ │ (目标数据库) │
│ TencentDB │ 公网 │ 自建/云上 │
└──────────────────┘ └──────────────────┘
网络方案选择:
| 方案 | 延迟 | 带宽 | 成本 | 适用场景 |
|---|---|---|---|---|
| 云联网 / 专线 | < 2ms | 高 | 中 | 同地域迁移(推荐) |
| 公网 | 5-20ms | 受限 | 低 | 非生产/小数据量 |
| VPN | 3-10ms | 中 | 低 | 跨地域迁移 |
| 腾讯云与 TiDB Cloud 专线 | < 5ms | 高 | 中 | 迁移到 TiDB Cloud |
4. 迁移方案选择
4.1 方案对比
| 方案 | 适用场景 | 停机时间 | 复杂度 | 数据一致性 |
|---|---|---|---|---|
| Dumpling + TiDB Lightning | 数据量大,可接受停机 | 长(取决于数据量) | 低 | 强一致(停写) |
| TiDB Data Migration (DM) | 在线迁移,最小停机 | 短(秒级) | 中 | 最终一致 |
| TiCDC + Dumpling | 在线迁移,需灵活控制 | 短(分钟级) | 中高 | 最终一致 |
| mysqldump / mydumper | 小数据量,简单场景 | 中 | 低 | 强一致(停写) |
| 腾讯云 DTS → 中转 MySQL → DM | 腾讯云 DTS 不支持直接到 TiDB | 短 | 高 | 取决于实现 |
4.2 推荐方案:Dumpling + TiDB Lightning(全量)+ TiCDC(增量)
组合使用,推荐以下标准流程:
阶段一:全量迁移
源库 ──Dumpling导出──▶ SQL/CSV文件 ──TiDB Lightning导入──▶ TiDB
阶段二:增量同步
源库 ──TiCDC实时同步──▶ TiDB
阶段三:切换
停写源库 → 等待同步追平 → 切换业务 → 校验
5. 详细操作步骤
5.1 阶段一:全量数据迁移
5.1.1 使用 Dumpling 导出数据
# 安装 Dumpling(通过 TiUP)
tiup install dumpling
# 导出全量数据
tiup dumpling \
-u tidb_migration \
-p 'StrongPassword123!' \
-h <腾讯云MySQL内网地址> \
-P 3306 \
-o /data/migration/full_export \
--filetype sql \
--threads 8 \
--rows 200000 \
--consistency snapshot \
--snapshot "427612461234567890" \
--params "tidb_distsql_scan_concurrency=15" \
-F 256MiB \
--logfile /data/migration/dumpling.log
参数说明:
| 参数 | 说明 | 建议值 |
|---|---|---|
--threads |
导出并发数 | CPU 核心数 × 0.5 |
--rows |
每个文件最大行数 | 100000-200000 |
--filetype |
导出格式 | sql(可读)/ csv(快) |
--consistency |
一致性保证 | snapshot(推荐)/ lock / flush |
-F |
单个文件最大大小 | 256MiB |
--where |
过滤条件 | 用于分库分表按条件导出 |
数据量估算与分片导出(超大规模场景):
# 如果单表超大(超过 500GB),建议按范围分片导出
# 示例:按主键 id 范围分片
for i in $(seq 0 9); do
tiup dumpling \
-u tidb_migration \
-p 'StrongPassword123!' \
-h <源库地址> -P 3306 \
-B mydb \
-T mydb.huge_table \
--where "id >= $((i * 10000000)) AND id < $(((i + 1) * 10000000))" \
-o /data/migration/shard_${i} \
--filetype csv \
--threads 4 \
&
done
wait
5.1.2 使用 TiDB Lightning 导入数据
步骤一:编写 Lightning 配置
cat > /data/migration/tidb-lightning.toml << 'EOF'
[lightning]
# 并发数
index-concurrency = 8
table-concurrency = 6
region-concurrency = 40
# 日志
level = "info"
file = "/data/migration/lightning.log"
[checkpoint]
# 断点续传
enable = true
schema = "tidb_lightning_checkpoint"
driver = "file"
dsn = "/data/migration/checkpoint.pb"
[tikv-importer]
# 使用 Local 模式(推荐,速度快)
backend = "local"
# 排序目录(需 NVMe SSD,至少与导入数据量相当)
sorted-kv-dir = "/data/migration/sorted-kv"
# 磁盘配额
disk-quota = "200 GB"
# TiKV 地址
addr = "10.0.3.1:20160"
[mydumper]
# Dumpling 导出目录
data-source-dir = "/data/migration/full_export"
# 过滤规则
no-schema = false
# 字符集
character-set = "utf8mb4"
[tidb]
# TiDB 地址
host = "10.0.2.1"
port = 4000
user = "root"
password = ""
status-port = 10080
pd-addr = "10.0.1.1:2379"
EOF
步骤二:执行导入
# 使用 TiUP 运行 Lightning
tiup tidb-lightning -config /data/migration/tidb-lightning.toml
# 观察进度
# Lightning 会输出进度日志,可通过以下命令查看
tail -f /data/migration/lightning.log | grep "progress"
# 也可通过 Grafana 的 Lightning 面板监控
步骤三:导入完成后验证
# 检查导入结果
grep "the whole procedure completed" /data/migration/lightning.log
# 检查是否有错误
grep "ERROR" /data/migration/lightning.log
关键注意事项:
- Local 模式:Lightning 直接生成 SST 文件注入 TiKV,速度最快(可达 500GB/h+),但导入期间 TiKV 集群负载较高
- 排序目录磁盘空间:
sorted-kv-dir至少需要源数据大小的 1.5 倍 - 断点续传:务必开启 checkpoint,防止中断后重头开始
- GC 时间调整:导入期间将 GC 时间调大,导入完成后恢复
-- 导入前:调大 GC 时间
UPDATE mysql.tidb SET VARIABLE_VALUE = '24h' WHERE VARIABLE_NAME = 'tikv_gc_life_time';
-- 导入完成后:恢复 GC 时间
UPDATE mysql.tidb SET VARIABLE_VALUE = '10m' WHERE VARIABLE_NAME = 'tikv_gc_life_time';
5.2 阶段二:增量数据同步(TiCDC)
5.2.1 TiCDC 架构
┌──────────────┐ ┌─────────────┐ ┌──────────┐
│ 腾讯云 MySQL │ ───▶ │ TiCDC │ ───▶ │ TiDB │
│ (Source) │ binlog│ (Capture) │ SQL │ (Target) │
└──────────────┘ └─────────────┘ └──────────┘
5.2.2 部署 TiCDC
# 1. 扩容 TiCDC 节点
cat > scale-out-ticdc.yaml << 'EOF'
cdc_servers:
- host: 10.0.5.1
port: 8300
deploy_dir: "/data/tidb-deploy/cdc-8300"
log_dir: "/data/tidb-deploy/cdc-8300/log"
EOF
tiup cluster scale-out tidb-prod scale-out-ticdc.yaml
# 2. 验证 TiCDC 状态
tiup ctl:v7.5.1 cdc capture list --pd=http://10.0.1.1:2379
5.2.3 创建 TiCDC Changefeed
# 方式一:使用 cdc cli 创建 changefeed
tiup ctl:v7.5.1 cdc changefeed create \
--server=http://10.0.5.1:8300 \
--sink-uri="mysql://root@10.0.2.1:4000/?time-zone=Asia%2FShanghai" \
--changefeed-id="tencentdb-to-tidb" \
--start-ts=<dumpling导出的snapshot_ts> \
--config=/data/migration/changefeed.toml
TiCDC 配置文件 changefeed.toml:
# 过滤规则
[filter]
# 忽略系统库
ignore-tables = [
"mysql.*",
"information_schema.*",
"performance_schema.*",
"sys.*"
]
# 如果某些表不需要同步
# ignore-tables = ["test_db.tmp_table", "test_db.log_table"]
# 只同步指定库表
# rules = ["mydb.*"]
# 同步参数
[mounter]
worker-num = 16
[sink]
# 同步冲突处理
# 冲突检测和解决
dispatchers = [
{ matcher = ["*.*"], dispatcher = "table" }
]
# 安全模式(追数据时使用)
# safe-mode = true
# 同步协议
protocol = "default"
# 一致性配置
[consistent]
level = "eventual"
flush-interval = 1000
5.2.4 监控 TiCDC 同步状态
# 查看 changefeed 列表
tiup ctl:v7.5.1 cdc changefeed list --pd=http://10.0.1.1:2379
# 查看特定 changefeed 状态
tiup ctl:v7.5.1 cdc changefeed query \
--changefeed-id=tencentdb-to-tidb \
--pd=http://10.0.1.1:2379
# 查看同步延迟
tiup ctl:v7.5.1 cdc changefeed query \
--changefeed-id=tencentdb-to-tidb \
--pd=http://10.0.1.1:2379 | jq '.status."checkpoint-ts"'
5.3 阶段三:使用 TiDB Data Migration (DM) 方案(替代 TiCDC)
如果更习惯 DM 的使用方式,也可以使用 DM 完成全量+增量迁移:
# 1. 部署 DM 集群
tiup install dm
cat > dm-topology.yaml << 'EOF'
global:
user: "tidb"
deploy_dir: "/data/dm-deploy"
dm-master:
- host: 10.0.6.1
dm-worker:
- host: 10.0.6.1
- host: 10.0.6.2
- host: 10.0.6.3
monitoring_servers:
- host: 10.0.6.1
EOF
tiup dm deploy dm-prod v7.5.1 ./dm-topology.yaml
tiup dm start dm-prod
DM 任务配置 migration-task.yaml:
name: "tencentdb-to-tidb"
task-mode: "all" # all = 全量 + 增量
shard-mode: "pessimistic" # 悲观协调模式
ignore-checking-items: [] # 不忽略任何检查项
target-database:
host: "10.0.2.1"
port: 4000
user: "root"
password: ""
mysql-instances:
- source-id: "tencentdb-source"
# 黑白名单
block-allow-list: "instance"
# 过滤规则
filter-rules: ["filter-sys-db"]
# 表路由规则(如果需要改名)
# route-rules: ["route-rule-1"]
# Dumpling 全量导出配置
mydumpers:
global:
threads: 8
chunk-filesize: "256"
rows: 200000
# Lightning 导入配置
loaders:
global:
pool-size: 16
dir: "/data/dm/dumped_data"
# Syncer 增量同步配置
syncer:
worker-count: 16
batch: 100
safe-mode: false
enable-heartbeat: true
# 黑白名单
block-allow-list:
instance:
do-dbs: ["mydb"] # 只同步 mydb 库
# do-tables:
# - db-name: "mydb"
# tbl-name: "users"
ignore-dbs: ["mysql", "information_schema", "performance_schema", "sys"]
# 过滤规则
filters:
filter-sys-db:
schema-pattern: "mysql"
table-pattern: "*"
events: []
action: "Ignore"
启动 DM 任务:
# 创建数据源
tiup dmctl:v7.5.1 --master-addr=10.0.6.1:8261 operate-source create /data/dm/mysql-source.yaml
# 启动迁移任务
tiup dmctl:v7.5.1 --master-addr=10.0.6.1:8261 start-task /data/migration/dm-task.yaml
# 查看任务状态
tiup dmctl:v7.5.1 --master-addr=10.0.6.1:8261 query-status tencentdb-to-tidb
6. 数据校验
6.1 行数校验
-- 在源库(腾讯云)执行
SELECT
table_schema,
table_name,
table_rows,
ROUND((data_length + index_length) / 1024 / 1024 / 1024, 2) size_gb
FROM information_schema.tables
WHERE table_schema = 'mydb'
ORDER BY table_rows DESC;
-- 在目标库(TiDB)执行同样的查询
-- 精确行数对比(小表)
SELECT COUNT(*) FROM mydb.users;
SELECT COUNT(*) FROM mydb.orders;
6.2 CRC32 / CHECKSUM 校验
-- TiDB 支持 ADMIN CHECKSUM,可以逐表校验
ADMIN CHECKSUM TABLE mydb.users;
ADMIN CHECKSUM TABLE mydb.orders;
-- 源库也可通过 CRC32 函数校验
SELECT BIT_XOR(CRC32(CONCAT_WS(',', col1, col2, col3, col4, col5)))
FROM mydb.users;
6.3 使用 sync-diff-inspector 工具(推荐)
# 安装
tiup install sync-diff-inspector
# 配置文件 diff-config.toml
cat > diff-config.toml << 'EOF'
# 对比模式:data(全量数据对比)/ schema(仅结构)/ count(仅行数)
check-struct-only = false
[data-sources]
[data-sources.mysql1]
host = "<腾讯云MySQL地址>"
port = 3306
user = "tidb_migration"
password = "StrongPassword123!"
# 快照,确保一致性
snapshot = "427659173852413952"
[data-sources.tidb1]
host = "10.0.2.1"
port = 4000
user = "root"
password = ""
[task]
output-dir = "/data/migration/diff_output"
source-instances = ["mysql1"]
target-instance = "tidb1"
target-check-tables = ["mydb.*"]
# 对比配置
[task.options]
# 分片大小
chunk-size = 1000
# 抽样对比(百分比,0-100)
sample-percent = 100
# 并发数
check-thread-count = 8
# 使用校验和对比(快)而非逐行对比
use-checksum = true
# 只对比表结构
# only-use-checksum = true
EOF
# 执行对比
tiup sync-diff-inspector --config=diff-config.toml
6.4 校验清单
| 检查项 | 方法 | 期望结果 |
|---|---|---|
| 表数量 | SHOW TABLES 对比 |
完全一致 |
| 行数 | sync-diff-inspector / COUNT(*) | 差异 < 0.01% |
| 数据内容 | sync-diff-inspector 全量对比 | 完全一致 |
| 索引 | SHOW INDEX FROM table |
一致(注意 TiDB 可能做了优化) |
| 自增ID | SHOW CREATE TABLE |
最大值对齐 |
| 字符集 | SHOW CREATE TABLE |
统一 utf8mb4 |
| 视图 | SHOW FULL TABLES WHERE TABLE_TYPE='VIEW' |
确认兼容性 |
| 存储过程/函数 | SHOW PROCEDURE STATUS |
已改造或移除 |
7. 业务切换方案
7.1 灰度切换策略
灰度阶段:
1. 只读验证 (0% 流量) - 验证数据正确性
2. 灰度流量 (5% 流量) - 小范围验证
3. 扩大灰度 (20% 流量) - 观察性能表现
4. 全量切换 (100% 流量) - 正式迁移
7.2 切换步骤详解
Step 1:停写源库
-- 在腾讯云 MySQL 源库执行
-- 设置为只读模式
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;
-- 确认所有连接已断开或为只读
SHOW PROCESSLIST;
Step 2:等待增量同步追平
# TiCDC 追平确认
tiup ctl:v7.5.1 cdc changefeed query \
--changefeed-id=tencentdb-to-tidb \
--pd=http://10.0.1.1:2379 | jq '.status'
# DM 追平确认
tiup dmctl:v7.5.1 --master-addr=10.0.6.1:8261 query-status tencentdb-to-tidb
# 确认条件:
# - checkpoint-ts 接近当前时间
# - 延迟 < 1 秒
# - 无未处理的 binlog event
Step 3:最终数据校验
# 执行最终数据对比
tiup sync-diff-inspector --config=diff-config.toml
Step 4:切换业务连接
# 应用配置切换示例(Kubernetes ConfigMap)
apiVersion: v1
kind: ConfigMap
metadata:
name: app-db-config
data:
db_host: "10.0.2.1" # TiDB 地址
db_port: "4000"
db_user: "app_user"
db_name: "mydb"
# 连接参数
db_params: "?charset=utf8mb4&parseTime=true&loc=Local&timeout=5s"
应用端连接串建议:
# JDBC
jdbc:mysql://10.0.2.1:4000/mydb?useSSL=true&characterEncoding=utf8mb4&rewriteBatchedStatements=true
# Go
user:password@tcp(10.0.2.1:4000)/mydb?charset=utf8mb4&parseTime=true
# Python
mysql+pymysql://user:password@10.0.2.1:4000/mydb?charset=utf8mb4
Step 5:观察与验证
-- 验证业务写入正常
SELECT COUNT(*) FROM mydb.orders WHERE created_at > '2024-01-01';
SHOW MASTER STATUS;
-- 监控 QPS / TPS(Grafana)
-- 监控慢查询
SELECT * FROM information_schema.cluster_slow_query
WHERE Time > NOW() - INTERVAL 30 MINUTE
ORDER BY Query_time DESC LIMIT 20;
-- 监控 Region 分布
SELECT
db_name,
table_name,
COUNT(*) region_count
FROM information_schema.tikv_region_status
WHERE db_name = 'mydb'
GROUP BY db_name, table_name;
8. 回滚方案
8.1 回滚触发条件
- 数据校验发现严重不一致
- 业务出现大量错误(错误率 > 1%)
- TiDB 集群故障无法快速恢复
- 性能不达标且短期无法优化
8.2 反向同步(TiDB → 腾讯云 MySQL)
# 如果长时间灰度,可配置反向同步以备回滚
# 创建反向 TiCDC changefeed
tiup ctl:v7.5.1 cdc changefeed create \
--server=http://10.0.5.1:8300 \
--sink-uri="mysql://tidb_migration:StrongPassword123!@<腾讯云MySQL>:3306/" \
--changefeed-id="tidb-back-to-tencentdb" \
--start-ts=<当前TiDB的TSO> \
--config=/data/migration/reverse-changefeed.toml
8.3 回滚操作步骤
# 1. TiDB 端设置为只读
mysql -h 10.0.2.1 -P 4000 -u root -e "SET GLOBAL read_only = ON;"
# 2. 等待反向同步追平
tiup ctl:v7.5.1 cdc changefeed query \
--changefeed-id=tidb-back-to-tencentdb \
--pd=http://10.0.1.1:2379
# 3. 腾讯云源库解除只读
mysql -h <腾讯云MySQL地址> -P 3306 -u root -p -e "
SET GLOBAL read_only = OFF;
SET GLOBAL super_read_only = OFF;
"
# 4. 应用切换回腾讯云 MySQL
# 5. 验证业务恢复
9. 性能优化与调优
9.1 迁移后常见性能问题
| 问题 | 现象 | 排查方法 | 解决方案 |
|---|---|---|---|
| 热点写 | 单个 TiKV 节点负载高 | Grafana → TiKV → Scheduler | 打散主键(SHARD_ROW_ID_BITS / AUTO_RANDOM) |
| 热点读 | 单 Region 成为热点 | Dashboard → 热点可视化 | 增加 TiDB 节点 / 开启 Follower Read |
| 大事务 | OOM / 超时 | 慢查询日志 | 拆分大事务,限制 tidb_mem_quota_query |
| 统计信息不准 | 执行计划差 | SHOW STATS_HEALTHY |
ANALYZE TABLE |
| 连接数过多 | 拒绝连接 | SHOW PROCESSLIST |
连接池限制 + HAProxy 代理 |
9.2 关键优化操作
-- 1. 收集统计信息
ANALYZE TABLE mydb.users;
ANALYZE TABLE mydb.orders;
-- 查看统计信息健康度
SHOW STATS_HEALTHY WHERE db_name = 'mydb';
-- healthy < 70 的表需要重新收集
-- 2. 开启 AUTO_RANDOM(新表)
CREATE TABLE orders_new (
id BIGINT PRIMARY KEY AUTO_RANDOM,
order_no VARCHAR(64),
...
);
-- 3. 已有表转 AUTO_RANDOM(需要重建)
-- 由于 TiDB 不支持直接修改已有主键为 AUTO_RANDOM
-- 需要创建新表并迁移数据
CREATE TABLE users_new LIKE users;
ALTER TABLE users_new MODIFY id BIGINT AUTO_RANDOM;
INSERT INTO users_new SELECT * FROM users;
RENAME TABLE users TO users_old, users_new TO users;
-- 4. SHARD_ROW_ID_BITS(非聚簇表)
ALTER TABLE mydb.logs SHARD_ROW_ID_BITS = 4;
-- 5. 开启 Coprocessor Cache
SET GLOBAL tidb_enable_multi_statement = ON;
-- 6. 读热点:开启 Follower Read
SET SESSION tidb_replica_read = 'follower';
-- 或全局设置
SET GLOBAL tidb_replica_read = 'leader-and-follower';
9.3 TiKV 参数调优
# 编辑 TiKV 配置
tiup cluster edit-config tidb-prod
# 在 tikv_servers 配置中添加:
server_configs:
tikv:
# RocksDB 调优
rocksdb.defaultcf.block-cache-size: "8GB"
rocksdb.writecf.block-cache-size: "2GB"
# 后台 compaction 线程
rocksdb.defaultcf.max-background-jobs: 8
# 内存限制
storage.block-cache.capacity: "16GB"
# Raft 日志回收
raftstore.raft-log-gc-tick-interval: "10s"
raftstore.raft-log-gc-size-limit: "72MB"
# 应用配置
tiup cluster reload tidb-prod
10. 常见问题与排查
10.1 迁移中常见问题
Q1:TiDB Lightning 报错 "context deadline exceeded"
原因:TiKV 写入压力过大,响应超时。
解决:
# 降低并发参数
# 修改 lightning.toml
[lightning]
index-concurrency = 4 # 降低为原来一半
table-concurrency = 3
region-concurrency = 20 # 降低 Region 分裂并发
[tikv-importer]
disk-quota = "100 GB" # 降低磁盘配额
Q2:增量同步延迟越来越大
排查:
# 1. 检查 TiCDC 状态
tiup ctl:v7.5.1 cdc changefeed query \
--changefeed-id=tencentdb-to-tidb \
--pd=http://10.0.1.1:2379
# 2. 检查网络延迟
ping <腾讯云MySQL地址>
# 3. 检查源库 binlog 产生速度
mysql -e "SHOW MASTER STATUS;"
# 对比两次的 Position 增长速度
# 4. 增加 TiCDC worker 数量
tiup ctl:v7.5.1 cdc changefeed update \
--changefeed-id=tencentdb-to-tidb \
--pd=http://10.0.1.1:2379 \
--sink-uri="mysql://root@10.0.2.1:4000/?worker-count=32"
Q3:DDL 同步失败
常见原因:
- 不兼容的 DDL(如修改存储引擎为 MyISAM)
- 大表 DDL 超时
解决:
-- TiDB 中手动执行失败的 DDL
ALTER TABLE mydb.users ADD COLUMN new_col VARCHAR(255) DEFAULT '';
-- 然后跳过 TiCDC 中已失败的 event
tiup ctl:v7.5.1 cdc changefeed update \
--changefeed-id=tencentdb-to-tidb \
--pd=http://10.0.1.1:2379 \
--config="[filter] ignore-tables = []"
Q4:自增 ID 不一致
TiDB 的 AUTO_INCREMENT 是全局唯一的,但不同 TiDB Server 节点分配的 ID 范围不连续。
-- 确保应用不依赖自增 ID 的连续性
-- 如需严格递增,考虑使用 Snowflake 等分布式 ID 方案
-- 查看当前自增值
SHOW TABLE mydb.users NEXT_ROW_ID;
10.2 应急操作速查
| 场景 | 应急命令 |
|---|---|
| 停止迁移任务 | tiup dmctl --master-addr=10.0.6.1:8261 stop-task tencentdb-to-tidb |
| 暂停增量同步 | tiup ctl:v7.5.1 cdc changefeed pause --changefeed-id=tencentdb-to-tidb --pd=http://10.0.1.1:2379 |
| TiDB 紧急只读 | mysql -h 10.0.2.1 -P 4000 -e "SET GLOBAL read_only = ON;" |
| 查看集群状态 | tiup cluster display tidb-prod |
| 快速扩容 TiDB | tiup cluster scale-out tidb-prod scale-out.yaml |
| 回滚 TiDB 参数 | tiup cluster reload tidb-prod |
本文档基于 TiDB v7.5.x LTS 版本编写,其他版本可能存在差异,请以对应版本官方文档为准。