【架构实战】TiDB分布式数据库:从MySQL到NewSQL的迁移
📅 2026/7/11 19:22:46
👁️ 阅读次数
📝 编程学习
【架构实战】TiDB分布式数据库:从MySQL到NewSQL的迁移
一、MySQL的尽头,是TiDB
2021年,业务量翻了5倍,MySQL分库分表也扛不住了。
当时的技术债:
- 16个MySQL库,128张分表,运维成本爆炸
- DDL要选窗口期,怕锁表影响线上
- 分片键用
user_id,但运营团队天天要按order_status、product_id查 - 扩容要rehash,每次都是心惊胆战
- 分布式事务用Seata,补偿逻辑越写越复杂
CTO一句话决策:考察NewSQL,目标是"像用MySQL一样用分布式数据库"。
对比了TiDB、OceanBase、CockroachDB后,选择了TiDB——理由很简单:兼容MySQL协议,DBA团队学习成本最低。
二、TiDB架构详解
2.1 三大核心组件
┌─────────────────┐ │ TiDB Server │ ← SQL层(无状态,可水平扩展) │ (SQL解析+优化) │ └────────┬────────┘ │ ┌──────────────┼──────────────┐ │ │ │ ┌─────────▼─────┐ ┌─────▼─────┐ ┌─────▼─────────┐ │ PD │ │ TiKV │ │ TiFlash │ │ (调度+元数据) │ │ (行存储) │ │ (列存储) │ │ │ │ RocksDB │ │ ClickHouse │ └───────────────┘ └───────────┘ └───────────────┘2.2 组件职责
| 组件 | 职责 | 类比MySQL | 关键特性 |
|---|---|---|---|
| TiDB Server | SQL解析、优化、执行 | Server层 | 无状态,随便扩 |
| PD | 集群调度、元数据、TSO | 无(分布式特有) | Raft Leader选举 |
| TiKV | 行存储引擎(OLTP) | InnoDB | 数据分Region,自动分裂 |
| TiFlash | 列存储引擎(OLAP) | 无 | 实时同步TiKV,HTAP核心 |
2.3 Region分裂与调度
数据以Region为单位管理(默认96MB),自动分裂和调度:
T1: Region1 [key: 000 ~ 100] 大小50MB T2: Region1 [key: 000 ~ 100] 大小100MB → 自动分裂 T3: Region1 [key: 000 ~ 050] Region2 [key: 051 ~ 100] T4: PD调度Rebalance,Region2迁移到其他TiKV节点这就是TiDB扩展性的核心:不需要分库分表,数据自动分片、自动均衡。
三、从MySQL迁移到TiDB
3.1 兼容性评估
-- TiDB兼容的MySQL特性(大部分)SELECT,INSERT,UPDATE,DELETEJOIN,SUBQUERY,UNIONINDEX,VIEW,TRIGGERAUTO_INCREMENT-- 需要注意的差异-- 1. 不支持存储过程、函数(TiDB 5.0+开始支持但有限制)-- 2. 不支持外键(分布式场景下性能差)-- 3. 事务大小限制:单事务不超过100MB-- 4. 自增ID仅保证唯一,不保证连续3.2 数据迁移工具——TiDB Lightning
# 1. Dumpling导出MySQL数据./dumpling\-hmysql-host-P3306\-uroot-ppassword\-Bmydb\-o/data/export\--filetype=sql\--threads=16# 2. TiDB Lightning导入./tidb-lightning\-configtidb-lightning.toml\-check-requirements=false# tidb-lightning.toml[lightning]level="strict"file="/tmp/lightning.log"[tikv-importer]backend="local"# 本地导入模式,性能最高[mydumper]>="/data/export"[tidb]host="127.0.0.1"port=4000user="root"password=""3.3 SQL改写实战
-- BEFORE: MySQL分库分表后按user_id查-- 应用层需要根据 user_id % 16 路由到具体分片SELECT*FROMt_orderWHEREuser_id=12345;-- AFTER: TiDB直接查,不需要分片逻辑SELECT*FROMt_orderWHEREuser_id=12345;-- TiDB自动根据user_id的key范围路由到对应Region-- 更爽的是:按order_status跨分片查询-- MySQL时代需要遍历16个库-- TiDB直接查,PD全局路由SELECT*FROMt_orderWHEREstatus='PAID'LIMIT100;3.4 迁移checklist
┌── 迁移前 ──────────────────────────────┐ │ □ 评估SQL兼容性(存储过程、外键等) │ │ □ 识别热点表,规划预切分Region │ │ □ 全量数据导出(Dumpling) │ │ □ 建立增量同步(TiCDC) │ │ □ 准备回滚方案(MySQL备份保留7天) │ ├── 迁移中 ──────────────────────────────┤ │ □ 全量导入(Lightning) │ │ □ 数据校验(sync-diff-inspector) │ │ □ 灰度切流(5% → 20% → 100%) │ │ □ 监控:QPS、延迟、错误率 │ ├── 迁移后 ──────────────────────────────┤ │ □ 观察3天,确认稳定 │ │ □ 优化慢查询(ANALYZE TABLE) │ │ □ 调整GC策略(tidb_gc_life_time) │ │ □ 清理MySQL数据 │ └────────────────────────────────────────┘四、TiDB性能优化
4.1 热点问题——最常见的问题
-- 问题:自增主键的INSERT全部写入同一个RegionINSERTINTOorders(user_id,amount)VALUES(?,?);-- 所有新数据的key聚集在一个Region,造成写热点-- 解决方案1:SHARD_ROW_ID_BITS(打散自增ID)ALTERTABLEorders SHARD_ROW_ID_BITS=4;-- 解决方案2:AUTO_RANDOM(推荐)CREATETABLEorders(idBIGINTPRIMARYKEYAUTO_RANDOM,user_idBIGINT,amountDECIMAL(12,2));-- 解决方案3:UUID替换自增IDCREATETABLEorders(idVARCHAR(36)PRIMARYKEYDEFAULT(UUID()),user_idBIGINT,amountDECIMAL(12,2));4.2 慢查询优化
-- TiDB特有的执行计划查看EXPLAINANALYZESELECT*FROMordersWHEREuser_id=12345;-- 关注点:-- cop_task: TiKV上的执行时间(存储层)-- root_task: TiDB上的执行时间(SQL层)-- 如果cop_task很多,说明大量数据从TiKV拉到TiDB处理,需要优化索引-- 统计信息更新ANALYZETABLEorders;-- TiDB依赖统计信息优化查询,定期UPDATE非常重要4.3 HTAP实战:OLTP + OLAP共存
-- TiFlash自动同步TiKV数据,AP查询自动路由到TiFlash-- 无需额外配置,优化器自动选择EXPLAINSELECTcategory_id,SUM(amount)FROMordersWHEREcreate_time>='2025-06-01'GROUPBYcategory_id;-- 如果看到 cop[tiflash],说明走了列存引擎-- 0.3秒完成8亿行数据聚合五、运维最佳实践
# TiUP集群拓扑(生产环境最低配置)tidb_servers:-host:10.0.1.1-host:10.0.1.2-host:10.0.1.3# 3台TiDB Serverpd_servers:-host:10.0.1.4-host:10.0.1.5-host:10.0.1.6# 3台PD(必须奇数)tikv_servers:-host:10.0.2.1-host:10.0.2.2-host:10.0.2.3# 至少3台TiKV(3副本)data_dir:/data/tikv六、总结
迁移TiDB最大的感受是:DBA终于不用半夜起来调分库分表了。
核心价值:
- MySQL兼容协议,迁移成本低,团队学习曲线平缓
- 自动分片,告别手动分库分表的运维噩梦
- HTAP能力,OLTP+OLAP一个引擎搞定,不需要T+1数据同步
- 水平扩展只需加机器,数据自动rebalance
注意事项:
- TiDB适合大数据量(TB级别),数据量小就别折腾
- 存储过程和复杂事务场景需要评估兼容性
- 自增ID要换成AUTO_RANDOM,避免写热点
- 运维团队要理解Raft协议和Region概念
一句话:如果MySQL分库分表让你痛不欲生,TiDB值得你认真考虑。
个人观点,仅供参考
编程学习
技术分享
实战经验