为什么选 TiDB
传统数据库的扩展困境:MySQL 主从架构写入只能走单点,分库分表后跨库事务和 join 极其痛苦。TiDB 作为原生分布式 HTAP 数据库,用一套引擎同时解决 OLTP 和 OLAP:
| 维度 | MySQL 分库分表 | TiDB |
|---|---|---|
| 扩展方式 | 应用层分片 | 透明水平扩展 |
| 分布式事务 | 难(XA 性能差) | 原生支持(Percolator) |
| 跨节点 Join | 不支持 | 支持(优化器自动下推) |
| 强一致性 | 单库内 | 全局 ACID |
| OLAP 能力 | 弱(锁表影响 TP) | TiFlash 列存,OLTP/OLAP 物理隔离 |
| 运维复杂度 | 高(分片元数据管理) | 中(PD 自动调度) |
| MySQL 兼容 | 原生 | 高度兼容(协议+语法) |
架构总览
┌─────────────────────────────────────────────────────────────┐
│ 应用层 (MySQL 协议) │
│ 兼容 MySQL 5.7/8.0 协议与语法 │
├──────────────┬──────────────┬───────────────────────────────┤
│ TiDB Node │ TiDB Node │ TiDB Node │
│ (SQL 解析 │ (执行计划 │ (无状态, 可任意扩缩) │
│ 优化执行) │ 生成调度) │ │
├──────────────┴──────────────┴───────────────────────────────┤
│ PD Cluster │
│ Placement Driver (元数据/调度中心) │
│ ┌─────────┬─────────┬─────────┐ │
│ │ PD-Leader│PD-Follow│PD-Follow│ Raft 3 节点 │
│ └─────────┴─────────┴─────────┘ │
├──────────────────────────────────────────────────────────────┤
│ TiKV Cluster (行存) │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ TiKV-1 │ │ TiKV-2 │ │ TiKV-3 │ │
│ │ Region[A] │ │ Region[B] │ │ Region[C] │ │
│ │ (Raft Leader)│ │(Raft Follower)│ │(Raft Follower)│ │
│ └────────────┘ └────────────┘ └────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ TiFlash Cluster (列存) │
│ ┌────────────┐ ┌────────────┐ │
│ │ TiFlash-1 │ │ TiFlash-2 │ 异步复制 TiKV 的数据 │
│ │ Columnar │ │ Columnar │ MPP 引擎并行查询 │
│ └────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────┘
三层核心组件:
- TiDB Server:无状态 SQL 层,MySQL 协议入口,解析 SQL → 生成执行计划 → 下推到 TiKV 执行
- PD(Placement Driver):集群大脑,管理元数据、Region 调度、时间戳分配(TSO)
- TiKV:分布式 KV 存储引擎,Raft 多副本保证强一致性,Region(~96MB)为基本调度单位
- TiFlash:列存引擎,通过 Raft Learner 异步复制 TiKV 数据,OLAP 查询走 TiFlash 不影响 OLTP
部署方式
TiUP 部署(推荐)
# 安装 TiUP
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
source ~/.bash_profile
tiup update --self
# 生成拓扑模板
tiup cluster template > topology.yaml
# 编辑拓扑文件
cat > topology.yaml << 'EOF'
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/tidb-deploy"
data_dir: "/tidb-data"
pd_servers:
- host: 10.0.1.11
- host: 10.0.1.12
- host: 10.0.1.13
tidb_servers:
- host: 10.0.1.21
- host: 10.0.1.22
tikv_servers:
- host: 10.0.1.31
data_dir: "/tidb-data/tikv-1,/ssd1/tikv-1" # 多盘挂载
- host: 10.0.1.32
data_dir: "/tidb-data/tikv-2,/ssd1/tikv-2"
- host: 10.0.1.33
data_dir: "/tidb-data/tikv-3,/ssd1/tikv-3"
tiflash_servers:
- host: 10.0.1.41
- host: 10.0.1.42
monitoring_servers:
- host: 10.0.1.11
grafana_servers:
- host: 10.0.1.11
alertmanager_servers:
- host: 10.0.1.11
EOF
# 检查集群拓扑
tiup cluster check topology.yaml --user root -p
# 部署集群(指定版本)
tiup cluster deploy tidb-prod v7.5.0 topology.yaml --user root -p
# 启动集群
tiup cluster start tidb-prod
# 检查集群状态
tiup cluster display tidb-prod
连接验证
# MySQL 客户端直连 TiDB
mysql -h 10.0.1.21 -P 4000 -u root -p
# 查看集群版本
SELECT tidb_version();
# 查看存储引擎
SELECT * FROM information_schema.TIKV_STORE_STATUS;
SELECT * FROM information_schema.TIFLASH_REPLICA;
# 建库建表
CREATE DATABASE IF NOT EXISTS app_db;
USE app_db;
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_RANDOM,
user_id BIGINT NOT NULL,
amount DECIMAL(12,2) NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) SHARD_ROW_ID_BITS = 4 PRE_SPLIT_REGIONS = 4;
AUTO_RANDOM替代AUTO_INCREMENT,避免写入热点;PRE_SPLIT_REGIONS预分裂 Region 避免冷启动热点。
Region 与调度策略
Region 生命周期
[单个 Region ~96MB]
│
├── 写入增长 → 超过 96MB → Region Split(分裂为 2 个)
│
├── PD 检测不均 → Region Balance(迁移到空闲节点)
│
├── 副本不可用 → Region 补副本(从 Follower 选举新 Leader)
│
└── Leader 热点 → Region Move Leader(迁移 Leader 到其他节点)
PD 调度策略配置
-- 查看当前调度策略
SHOW CONFIG WHERE type = 'pd';
-- 关键参数
-- 1. Region 分裂阈值(默认 96MB)
SET CONFIG pd `split-merge-size = '96MiB'`;
-- 2. 副本数(默认 3)
SET CONFIG pd `max-replicas = 3`;
-- 3. Leader 调度策略
SET CONFIG pd `leader-schedule-limit = 4`; -- 同时进行的 Leader 迁移数
SET CONFIG pd `region-schedule-limit = 2048`; -- 同时进行的 Region 迁移数
SET CONFIG pd `hot-region-schedule-limit = 4`; -- 热点 Region 调度并发
-- 4. 标签调度(让副本分布到不同机架/可用区)
-- 先给 TiKV 打标签
tiup cluster edit-config tidb-prod
# tikv_servers 中添加:
# config:
# server.labels: { zone: "z1", rack: "r1", host: "tikv-1" }
-- 再配置 Placement Rules
SET CONFIG pd `enable-placement-rules = true`;
-- 3 副本分别在不同 zone
-- PD 会自动调度保证同一 Region 的 3 个副本不在同一 zone
热点问题诊断与处理
-- 查看热点 Region
SELECT * FROM information_schema.TIDB_HOT_REGIONS_HISTORY
WHERE update_time > NOW() - INTERVAL 1 HOUR
ORDER BY flow_bytes DESC LIMIT 10;
-- 查看某个表的热点分布
SELECT REGION_ID, START_KEY, END_KEY, WRITTEN_BYTES, READ_BYTES
FROM information_schema.TIDB_HOT_REGIONS
WHERE DB_NAME = 'app_db' AND TABLE_NAME = 'orders';
-- 处理写入热点(自增主键场景)
-- 1. 使用 AUTO_RANDOM 代替 AUTO_INCREMENT
-- 2. 对已有表添加 SHARD_ROW_ID_BITS
ALTER TABLE orders SHARD_ROW_ID_BITS = 4;
-- 3. 手动分裂热点 Region
-- 通过 pd-ctl 手动分裂
-- pd-ctl >> operator add split-region <region_id> --policy scan
TiFlash 列存分析
TiFlash 是 TiDB HTAP 能力的核心——通过 Raft Learner 异步复制 TiKV 数据到列存引擎,OLAP 查询自动路由到 TiFlash,不影响 OLTP 性能。
启用 TiFlash 副本
-- 为整库添加 TiFlash 副本
ALTER DATABASE app_db SET TIFLASH REPLICA 1;
-- 为单表添加
ALTER TABLE orders SET TIFLASH REPLICA 1;
-- 查看副本同步进度
SELECT * FROM information_schema.TIFLASH_REPLICA
WHERE TABLE_SCHEMA = 'app_db' AND TABLE_NAME = 'orders';
-- PROGRESS = 1.0 表示同步完成
-- 查看列存统计信息
SELECT TABLE_NAME, TABLE_ROWS, DATA_LENGTH
FROM information_schema.TIFLASH_SEGMENTS
WHERE TABLE_SCHEMA = 'app_db';
查询路由
-- TiDB 优化器自动选择 TiKV(行存)或 TiFlash(列存)执行
-- 大多数分析查询会自动走 TiFlash
-- 强制走 TiFlash
SET SESSION tidb_isolation_read_engines = 'tiflash';
SELECT COUNT(*), SUM(amount) FROM orders WHERE created_at > '2026-01-01';
-- 强制走 TiKV(OLTP 路径)
SET SESSION tidb_isolation_read_engines = 'tikv';
SELECT * FROM orders WHERE id = 12345;
-- 恢复自动选择
SET SESSION tidb_isolation_read_engines = 'tikv,tiflash';
-- MPP 模式(多节点并行计算,适合大表聚合)
SET SESSION tidb_allow_mpp = 1;
SET SESSION tidb_enforce_mpp = 1;
SELECT user_id, COUNT(*) cnt, SUM(amount) total
FROM orders
GROUP BY user_id
ORDER BY total DESC
LIMIT 100;
OLTP vs OLAP 性能对比
| 场景 | TiKV(行存) | TiFlash(列存) |
|---|---|---|
点查 WHERE id = ? |
极快(索引扫描) | 不推荐 |
范围扫描 WHERE id BETWEEN ? AND ? |
快 | 中 |
| 全表 COUNT/SUM | 慢(大量 IO) | 极快(列存压缩+向量化) |
| GROUP BY 聚合 | 中 | 极快(MPP 并行) |
| 多表 JOIN | 中 | 极快(Hash Join 并行) |
| 实时写入 | 强(Raft Leader 直写) | 最终一致(Learner 异步复制,秒级延迟) |
备份与恢复
BR 工具(推荐)
# 全量备份到 S3/NFS/本地
tiup br backup full \
--pd "10.0.1.11:2379" \
--storage "s3://tidb-backup/full-20260722" \
--s3.endpoint "https://s3.cn-north-1.amazonaws.com.cn" \
--ratelimit 128 \
--log-file /tmp/br-backup.log
# 指定库备份
tiup br backup db \
--pd "10.0.1.11:2379" \
--db "app_db" \
--storage "local:///tidb-backup/app_db-20260722"
# 增量备份(基于上次备份的 TS)
LAST_TS=$(tiup br validate decode --storage "s3://tidb-backup/full-20260721" \
--log-file /dev/stdout 2>&1 | grep "TS" | awk '{print $NF}')
tiup br backup full \
--pd "10.0.1.11:2379" \
--storage "s3://tidb-backup/incr-20260722" \
--lastbackupts $LAST_TS
# 恢复
tiup br restore full \
--pd "10.0.1.11:2379" \
--storage "s3://tidb-backup/full-20260722" \
--ratelimit 256
# 恢复指定库
tiup br restore db \
--pd "10.0.1.11:2379" \
--db "app_db" \
--storage "s3://tidb-backup/full-20260722"
Dumpling + Lightning(逻辑备份+导入)
# Dumpling 导出(适合小量数据或迁移)
tiup dumpling \
--host 10.0.1.21 --port 4000 --user root \
--output /tidb-backup/dump-20260722 \
--filetype sql \
--threads 8 \
--rows 100000 \
--database app_db
# Lightning 导入(高速批量导入,适合大表初始化)
tiup tidb-lightning \
--tidb-host 10.0.1.21 --tidb-port 4000 --tidb-user root \
--importer-host 10.0.1.31 --importer-port 8287 \
--sorted-kv-dir /tmp/sorted-kv \
--source-file /tidb-backup/dump-20260722 \
--log-file /tmp/lightning.log
PITR(时间点恢复)
# 需要先开启日志备份(持续运行)
tiup br log start \
--task-name "continuous-backup" \
--pd "10.0.1.11:2379" \
--storage "s3://tidb-backup/logs"
# 查看 PITR 可恢复的时间范围
tiup br log status \
--task-name "continuous-backup" \
--pd "10.0.1.11:2379"
# 恢复到指定时间点
tiup br log restore \
--pd "10.0.1.11:2379" \
--task-name "continuous-backup" \
--restored-ts '2026-07-22 14:30:00+0800' \
--storage "s3://tidb-backup/logs"
在线扩缩容
扩容节点
# 编辑拓扑文件,添加新节点
cat >> topology-scale-out.yaml << 'EOF'
tikv_servers:
- host: 10.0.1.34
data_dir: "/tidb-data/tikv-4,/ssd1/tikv-4"
EOF
# 执行扩容
tiup cluster scale-out tidb-prod topology-scale-out.yaml
# PD 会自动调度 Region 到新节点
# 观察均衡进度
tiup ctl pd -u 10.0.1.11:2379 store
# 重点关注: new store 的 region_count 逐步增长
缩容节点
# 缩容(PD 会先将该节点的 Region 迁移到其他节点,再下线)
tiup cluster scale-in tidb-prod -N 10.0.1.34
# 查看下线进度
tiup ctl pd -u 10.0.1.11:2379 store
# 状态变为 Offline → 当 region_count 降为 0 → 变为 Tombstone → 安全移除
# 如果需要强制快速下线(生产慎用)
# tiup ctl pd -u 10.0.1.11:2379 store delete <store_id>
扩缩容期间业务零感知——PD 的 Region 调度限速保证了平滑迁移。扩容后数据自动均衡通常需要数小时(取决于数据量和网络带宽)。
监控与告警
TiUP 部署自带 Prometheus + Grafana 监控体系。关键面板:
核心指标
| 指标 | 含义 | 告警阈值 |
|---|---|---|
pd_cluster_status |
集群健康状态 | 非 healthy |
tikv_engine_size |
各 TiKV 节点存储量 | 磁盘用量 > 80% |
tikv_region_count |
各节点 Region 数 | 节点间偏差 > 20% |
tidb_query_duration |
查询延迟 P99 | > 100ms(TP)/ > 30s(AP) |
tikv_grpc_msg_duration |
TiKV RPC 延迟 | P99 > 50ms |
tikv_leader_count |
各节点 Leader 数 | 偏差 > 20% |
tidb_tikvclient_backoff_seconds_count |
事务重试次数 | 增长率突增 |
tiflash_storage_throughput |
TiFlash 同步延迟 | > 60s |
关键告警规则
groups:
- name: tidb
rules:
- alert: TiKVStoreDown
expr: pd_store_status{state="Down"} > 0
for: 1m
labels: { severity: critical }
annotations:
summary: "TiKV 节点离线"
- alert: TiKVRegionUnhealthy
expr: sum(tikv_raftstore_region_count{type="unavailable"}) > 0
for: 5m
labels: { severity: critical }
- alert: TiDBHighQPSRetry
expr: rate(tidb_tikvclient_backoff_seconds_count[5m]) > 100
for: 5m
labels: { severity: warning }
- alert: TiFlashReplicaLag
expr: max(tiflash_storage_raft_apply_log_lag) > 60
for: 5m
labels: { severity: warning }
- alert: DiskSpaceLow
expr: 1 - tikv_engine_size / tikv_store_available * 0 > 0.8
for: 10m
labels: { severity: warning }
Dashboard
Grafana: http://10.0.1.11:3000
├── Overview → 集群总览
├── TiDB → SQL 层性能
├── PD → 调度与 Region 分布
├── TiKV-Details → 存储引擎细节
├── TiKV-Trouble → 故障诊断
├── TiFlash-Summary → 列存引擎
└── Transaction → 事务性能
常见问题处理
写入热点
-- 诊断:查看 HOT_REGIONS
SELECT * FROM information_schema.TIDB_HOT_REGIONS
WHERE TYPE = 'write';
-- 解决方案:
-- 1. AUTO_INCREMENT → AUTO_RANDOM
-- 2. 预分裂 Region
ALTER TABLE orders PRE_SPLIT_REGIONS = 4;
-- 3. 对于时间序列场景,使用 SHARD_ROW_ID_BITS + PRE_SPLIT_REGIONS
OOM(内存溢出)
-- 查看 SQL 内存使用
SELECT QUERY_ID, DIGEST_TEXT, MEM
FROM information_schema.CLUSTER_TIDB_MEMORY_USAGE
ORDER BY MEM DESC LIMIT 10;
-- 设置内存限制
SET GLOBAL tidb_mem_quota_query = 1073741824; -- 1GB per query
-- 强制落盘排序
SET GLOBAL tidb_enable_tmp_storage_on_oom = 1;
TiKV 节点磁盘满
# 紧急处理:压缩 RocksDB 释放空间
tiup ctl tikv --host 10.0.1.31:20160 compact -c default
tiup ctl tikv --host 10.0.1.31:20160 compact -c write
# 如果无法恢复,强制下线该节点并扩容新节点
# 数据会从其他副本恢复
GC 卡住
-- 查看 GC 状态
SELECT * FROM information_schema.TIDB_GC_STATUS;
SELECT * FROM information_schema.TIKV_GC_STATUS;
-- GC 生命周期(默认 10 分钟)
SELECT VARIABLE_VALUE FROM mysql.tidb
WHERE VARIABLE_NAME = 'tikv_gc_life_time';
-- 调大可支持更长时间的事务,但会增加 MVCC 版本堆积
SET GLOBAL tikv_gc_life_time = '30m';
-- 如果 GC 卡住,检查是否有长事务持有旧版本
SELECT ID, TIME, INFO
FROM information_schema.PROCESSLIST
WHERE TIME > 600
ORDER BY TIME DESC;
避坑清单
| # | 坑 | 症状 | 解决 |
|---|---|---|---|
| 1 | AUTO_INCREMENT 写入热点 | 某个 TiKV 节点 CPU/IO 远高于其他节点 | 使用 AUTO_RANDOM 或 SHARD_ROW_ID_BITS 打散 |
| 2 | 大事务超限 | BatchResolveLock / txn too large 错误 |
单事务默认限制 100MB,拆分批处理;或调大 txn-total-size-limit |
| 3 | TiFlash 同步延迟 | AP 查询数据不是最新的 | TiFlash 是异步复制(秒级延迟),对实时性要求高的查询走 TiKV |
| 4 | PD 单点故障 | 集群不可用 | PD 必须部署 3 节点 Raft,奇数节点,不同物理机 |
| 5 | Region 调度限速不当 | 扩容后长时间不均衡 | 调大 region-schedule-limit 和 leader-schedule-limit,但避免影响在线业务 |
| 6 | Grafana 告警风暴 | 短暂网络抖动导致大量告警 | 配置告警的 for 持续时间(至少 1-5 分钟)避免抖动误报 |
| 7 | BR 恢复数据被覆盖 | 恢复操作覆盖了已有数据 | BR 恢复前确认目标库不存在或已清空;恢复到新库名 |
| 8 | PD Leader 切换导致短暂不可用 | TSO 分配暂停 ~1-3 秒 | PD 选举优化 election-timeout;客户端重试机制 |
| 9 | TiKV RocksDB write stall | 写入延迟突然飙升 | 磁盘 IO 瓶颈——增加 TiKV 节点或升级 NVMe SSD |
| 10 | tikv_gc_life_time 过大 | 磁盘空间持续增长不释放 | GC life_time 不超过 1 小时;定期检查长事务并 KILL |
总结
TiDB 用一套系统同时解决 OLTP 和 OLAP,核心运维要点:
- PD 是大脑——3 节点 Raft 部署,标签调度实现跨可用区容灾
- AUTO_RANDOM + 预分裂是避免写入热点的标配
- TiFlash 异步复制——AP 查询走列存,TP 查询走行存,物理隔离互不影响
- BR 全量+增量+PITR 三级备份策略,RPO 可控在分钟级
- 扩缩容零停机——PD 限速调度 Region,业务完全无感
- 监控告警靠自带 Grafana——关键指标(Store 状态、Region 健康、查询延迟)全覆盖
选型建议:数据量 < 1TB 且无分布式事务需求,MySQL + 读写分离足够;数据量 1TB~100TB 且有扩展需求,TiDB 是国产分布式数据库的首选;纯 OLAP 场景(日志分析、BI 报表),ClickHouse 性价比更高。