数据库运维17 min read

TiDB 分布式数据库运维实战

为什么选 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_RANDOMSHARD_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-limitleader-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,核心运维要点:

  1. PD 是大脑——3 节点 Raft 部署,标签调度实现跨可用区容灾
  2. AUTO_RANDOM + 预分裂是避免写入热点的标配
  3. TiFlash 异步复制——AP 查询走列存,TP 查询走行存,物理隔离互不影响
  4. BR 全量+增量+PITR 三级备份策略,RPO 可控在分钟级
  5. 扩缩容零停机——PD 限速调度 Region,业务完全无感
  6. 监控告警靠自带 Grafana——关键指标(Store 状态、Region 健康、查询延迟)全覆盖

选型建议:数据量 < 1TB 且无分布式事务需求,MySQL + 读写分离足够;数据量 1TB~100TB 且有扩展需求,TiDB 是国产分布式数据库的首选;纯 OLAP 场景(日志分析、BI 报表),ClickHouse 性价比更高。

分享:

评论区