疯狂餐厅
86.88M · 2026-03-21
兄弟们,想象一下:MySQL 是个踏实能干的老员工,但公司业务爆炸增长,他一个人(单机)扛不住了。分库分表?就像让老员工分裂成 10 个人格,精神分裂不说,协调起来要命。这时,TiDB 来了——它说:“别分裂了,我来组建个分布式团队,还保持 MySQL 的优良习惯!”
TiDB 是什么? 它是一个开源分布式关系型数据库,核心就一句话: “像用 MySQL 一样简单,享受分布式数据库的扩展能力” 。它是 PingCAP 公司的“亲儿子”,在国内外都有大量生产案例。
爷爷辈:Google Spanner + F1 (理论基础)
爸爸辈:CockroachDB (同期竞争者)
TiDB 自己:中国出生的“分布式数据库优等生”
用户请求
↓
TiDB Server (计算层) → “大脑”:处理SQL,无状态,随便扩
↓
PD Server (调度层) → “总指挥”:管理元数据,调度数据分布
↓
TiKV Server (存储层) → “仓库群”:存数据,Raft保证一致性
类比:
-- MySQL 单机:每秒 5000 订单就卡死
-- 老板:加机器!
-- DBA:要分库分表,改代码,至少一个月...
-- 程序员:我选择跑路
-- 原 MySQL 代码不用改
-- 直接连接 TiDB
-- 数据自动分布,自动扩容
-- 跨节点 Join?支持!
-- 分布式事务?支持!
-- 全局唯一ID?自增主键就行!
CREATE TABLE orders (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- 自增主键,全局唯一
user_id BIGINT,
amount DECIMAL(10,2),
INDEX idx_user_id(user_id)
) SHARD_ROW_ID_BITS = 4; -- 设置行数据打散
关键区别:
传统分片:DBA 手动分区
-- MySQL 手动分区
CREATE TABLE orders (
id INT,
user_id INT
) PARTITION BY RANGE (id) (
PARTITION p0 VALUES LESS THAN (1000000),
PARTITION p1 VALUES LESS THAN (2000000),
-- ... 累死 DBA
);
TiDB 自动分片:
一张表 → 自动切成多个 Region(默认 96MB/个)
每个 Region → 3 副本(通过 Raft 协议保证一致性)
Region 分布 → 自动均衡到不同 TiKV 节点
扩容 → 加 TiKV 节点,PD 自动迁移 Region
可视化:
表 orders
├── Region 1 (rows 1-100w) → [TiKV1, TiKV2, TiKV3] 副本
├── Region 2 (rows 100w-200w) → [TiKV2, TiKV3, TiKV4]
├── Region 3 (rows 200w-300w) → [TiKV3, TiKV4, TiKV5]
└── ...
问题:A 账户(在节点1)转 100 元给 B 账户(在节点2),如何保证原子性?
MySQL 方案:用 XA 事务(性能差)或业务补偿(复杂)
TiDB 方案:Percolator 事务模型(Google 论文实现)
// TiDB 事务流程(简化版)
1. 开始事务,获取 start_ts(时间戳)
2. 写数据到内存缓冲
3. 提交时:
a) 选一个行作为 Primary Key(如 A账户)
b) 对 Primary Key 加锁、写数据
c) 并行提交其他 Secondary Keys(B账户)
d) 清理锁,事务完成
// 关键:通过 PD 获取全局递增时间戳,解决分布式时钟问题
实际使用:和 MySQL 一样!
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;
COMMIT; -- TiDB 自动处理分布式事务
传统扩容:
TiDB 扩容:
# 1. 加个 TiKV 节点
tiup cluster scale-out mycluster -N 192.168.1.100:20160
# 2. PD 自动调度 Region
# 3. 数据自动迁移
# 4. 业务无感知
传统方案:MySQL(OLTP)+ Hadoop/Spark(OLAP)
TiDB 方案:TiDB(OLTP)+ TiFlash(列存引擎)
同一份数据,两种存储:
行存 (TiKV) → 高并发事务
列存 (TiFlash) → 实时分析
-- 创建 TiFlash 副本
ALTER TABLE orders SET TIFLASH REPLICA 1;
-- 分析查询自动路由到 TiFlash
SELECT user_id, SUM(amount)
FROM orders -- TiDB 自动选择 TiFlash
WHERE create_time > '2023-01-01'
GROUP BY user_id
ORDER BY SUM(amount) DESC
LIMIT 10;
连接:用 MySQL 客户端、驱动
协议:MySQL 协议 5.7
语法:大部分兼容
工具:Navicat、Workbench、ORM 框架都能用
// Spring Boot 配置
spring:
datasource:
url: jdbc:mysql://tidb-cluster:4000/test
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 代码一行不用改!
场景:用户在中国,数据在美国,怎么快速访问?
方案:TiDB 的“Follower Read”
主数据中心(美国) → 写入
边缘节点(中国、欧洲) → 只读副本
应用:写走美国,读走最近节点
SELECT /*+ READ_FROM_FOLLOWER() */ *
FROM orders
WHERE user_id = 123;
-- 从最近副本读,延迟降低 80%
问题:自增主键导致新数据都写最后一个 Region
CREATE TABLE orders (
id BIGINT AUTO_INCREMENT PRIMARY KEY, -- 热点!
...
);
解决:
-- 方案1:使用随机主键
CREATE TABLE orders (
id CHAR(32) PRIMARY KEY DEFAULT UUID(), -- 随机
...
);
-- 方案2:使用组合主键
CREATE TABLE orders (
user_id BIGINT,
order_id BIGINT AUTO_INCREMENT,
PRIMARY KEY (user_id, order_id) -- 按 user_id 分散
);
-- 方案3:使用 SHARD_ROW_ID_BITS
CREATE TABLE orders (
id BIGINT AUTO_INCREMENT PRIMARY KEY
) SHARD_ROW_ID_BITS = 4; -- 把行 ID 打散到 16 个 Region
限制:默认单事务不超过 100MB
原因:大事务占用内存多,影响集群
解决:
-- 错误:一次删 1 亿条
DELETE FROM logs WHERE create_time < '2020-01-01';
-- 正确:分批删
WHILE (SELECT COUNT(*) FROM logs WHERE create_time < '2020-01-01') > 0 DO
DELETE FROM logs WHERE create_time < '2020-01-01' LIMIT 10000;
COMMIT;
SLEEP 1; -- 喘口气
END WHILE;
不完全兼容:
建议:迁移前用 TiDB Data Migration (DM) 做兼容性检查
| 维度 | TiDB | CockroachDB | MySQL 分库分表 |
|---|---|---|---|
| 兼容性 | MySQL 协议 | PostgreSQL 协议 | MySQL |
| SQL 支持 | 很丰富 | 丰富 | 受限 |
| 扩展性 | 自动 | 自动 | 手动 |
| 事务 | 强一致 | 强一致 | 最终一致 |
| 生态 | 丰富 | 一般 | 丰富 |
| 部署 | 较复杂 | 较复杂 | 简单 |
| 学习曲线 | 平缓 | 较陡 | 陡峭 |
一句话选择指南:
# 用 Docker 启动
docker run -p 4000:4000 pingcap/tidb
# 连接(和 MySQL 一样!)
mysql -h 127.0.0.1 -P 4000 -u root
# 使用 TiUP(官方部署工具)
# 1. 安装 TiUP
curl --proto '=https' --tlsv1.2 -sSf | sh
# 2. 部署集群
tiup cluster deploy tidb-test v6.1.0 ./topology.yaml
# 3. 启动
tiup cluster start tidb-test
# 使用 DM 工具
# 1. 全量导出
mydumper -B test -o /data/backup
# 2. 增量同步
# DM MySQL binlog,实时同步到 TiDB
# 3. 切换流量
# 改应用连接串到 TiDB
访问:
坚控:Grafana + Prometheus(自动部署)
告警:集成 AlertManager
备份:BR(Backup & Restore)工具
-- 未来:按使用量付费
-- 自动扩缩容,0 维护
CREATE DATABASE mydb; -- 自动分配资源
-- 用多少付多少,像云函数
-- TiDB 自动优化
EXPLAIN SELECT * FROM users WHERE age > 20;
-- AI建议:在 age 列加索引
-- 自动创建索引,自动评估效果
数据分布在 AWS、Azure、阿里云
自动多云调度
合规性自动满足
TiDB 不是银弹,但它是解决“数据库扩展性”问题的最优雅方案之一。
迁移前灵魂三问:
如果答案都是 Yes,那么 TiDB 可能是你的最佳选择。
记住:技术选型不是选最好的,是选最合适的。TiDB 适合那些“MySQL 撑不住,但又不想大改业务”的场景。
下次当你听到 DBA 说“要分库分表了”,可以拍着胸脯说:“试试 TiDB 吧,它能让你少掉几根头发!” ️