在 2015 年前后,团队的分库分表方案一度让我非常头疼。单个 MySQL 的单机容量走到瓶颈后,技术选型团队尝试过 MyCAT、ShardingSphere-Proxyd 之类的中间件,又把主从复制拆成多套,结果业务层动不动就报“跨库查询不支持”“分布式事务状态不一致”,排查问题要从多个 MySQL 实例里拉日志。后来朋友推荐我去看 TiDB,说它能保留 MySQL 的连接协议和 SQL 习惯,同时解决“扩容不用改代码”的问题。
这篇不打算给你背书式地把产品文档念一遍。我以比较偏工程落地的视角,把 TiDB 本身的定位、最核心的架构分层、以及大多数人会纠结的“tiDB 和 MySQL 的区别”聊透,最后给出一套从 MySQL 迁移到 TiDB 时比较稳妥的路线和踩坑经验。如果你正在评估 TiDB,或者被单机 MySQL 压得有点喘不过气,这篇会对你比较有帮助。
1. 为什么 TiDB 会出现在这个时间点:从 MySQL 容量焦虑说起
1.1 单机数据库的扩容短板,不是加内存就能填补的
MySQL 本身是一个足够成熟的关系型数据库,但在互联网业务量增长到一定阶段,所有人都会撞上同样的墙:单实例的 CPU、内存、磁盘 IO 即使不停升级硬件,性能曲线也会越来越难看。磁盘扩容容易,内存扩容后 InnoDB 的缓冲池、连接数、锁冲突却不会同比例变好。
大多数人遇到这个瓶颈后的第一反应是分库分表。把用户表按 user_id 哈希成 64 张表,或者把订单表按月分表,听起来没有技术难度,实际上后续灾难无穷。
分库分表的痛点很典型:
- SQL 路由规则写死之后,业务代码里到处都是“先路由到哪个库再执行”的逻辑,后期改分片键等于重写。
- 跨分片的 JOIN、子查询、聚合函数全部变成高级需求,要么回内存里 Merge,要么直接在应用层做二次加工。
- 唯一键、分布式 ID、事务变成最麻烦的部分。两个分片之间要同时写数据时,常见做法是本地消息表和接口补偿,不仅技术上费劲,数据不一致时的定位成本更高。
- 运维层还得自己做一套数据迁移、扩缩容脚本,每加一个分片就要重新平衡数据。
分库分表本质上是“把一个大数据库拆成很多个小 MySQL”,它在数据层加了一层中间件逻辑。这套东西不是不能用,但维护成本不低。TiDB 能出来,就是因为它在保证分布式扩展能力的同时,不让业务感知分片的存在。
1.2 TiDB 的定位:兼容 MySQL 生态的分布式数据库
TiDB 是开源的分布式关系型数据库,核心目标是把 MySQL 当作“前台兼容层”,后台换成一套能水平扩展的分布式存储引擎。业务方不需要改变连接 MySQL 的方式,不需要自己再维护一套 Sharding 中间件,只把连接地址换到 TiDB 集群,就能获得接近无限的水平扩展能力。
这个方向很聪明的一点在于,它继承了 MySQL 现有的驱动和生态。你在 Java 里用的 JDBC、在 Python 里用的 PyMySQL 或 mysql-connector-python、在运维里用的 mysqldump 等工具都可以直接连上去操作。开发团队不用额外学习一套新的开发模型。你该写 SQL 还是写 SQL,该做 ORM 映射还做 ORM 映射,TiDB 会像 MySQL 一样回报结果。
但 TiDB 并不仅仅是“开源版的 MySQL 集群”。它解决了 MySQL 生态里比较难处理的几个点:
- 数据可以自动分片,且分片对业务透明;
- 支持跨节点的分布式事务,保持真正的 ACID;
- 具备多副本同步复制机制,故障时自动切换,不需要人工干预。
- 存储层和计算层可以独立扩展,业务量大时加节点即可。
因此,TiDB 的定位准确来说是:一款具备 MySQL 协议兼容能力的分布式关系型数据库。对于中小项目来说,MySQL 也许没有太大问题;但如果业务清晰可见地会持续增长,TiDB 的架构方式能为未来留下更大的空间。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. TiDB 架构中最核心的三块组件,以及为什么这样拆分
很多人第一次打开 TiDB 官方文档会被 TiDB、TiKV、PD、TiFlash 各种组件绕晕。不要紧,我先用一张比较直观的分层关系帮你捋清它们。
TiDB 从大的逻辑上看是两层结构:
- 计算层(TiDB Server):负责接收 SQL、解析 SQL、生成执行计划、再把任务发往后端存储层,最后汇总结果集。
- 存储层(TiKV 和 TiFlash):负责真正存数据,并以多副本的方式保证数据可靠性。其中 TiKV 存行式数据,主要承担在线交易读写;TiFlash 存列式数据,负责分析型查询。
在这两层之上还有一个 PD(Placement Driver),按官方说法是“调度模块”。它像总指挥一样管理整个集群的数据分布、副本平衡和事务时间戳分配。
如果用一个面向真实场景的样例来说明,你可能会更容易理解。
2.1 一次 SQL 查询在 TiDB 中是怎么被处理的
假设
