如果你正面临单机 MySQL 无法承载数据量或写入压力的问题,PingCAP 开源的 TiDB 无疑是一个值得考虑的水平扩展方案。它兼容 MySQL 5.7 协议,底层基于 TiKV 和 RocksDB,能提供对应用透明的分布式能力。不过,TiDB 并非 MySQL 的“平替”,它有着自己独特的架构约束和使用边界。
在开始之前,不妨先在数据库/中间件/技术栈中评估一下,确认 TiDB 是否真的适合你当前的业务场景。
一、架构、场景与部署
1.1 架构组件
TiDB 集群由四个核心组件构成,职责划分非常清晰:
- TiDB Server:无状态的 SQL 层,负责解析 SQL、生成执行计划与协调事务。它可水平扩展,多个节点共享同一份数据。
- TiKV:分布式 KV 存储。数据以 Region(默认 96MB)为单位分片,每个 Region 通过 Raft 协议在 3 个不同 TiKV 节点上维护副本,以保证一致性。
- PD(Placement Driver):集群的“大脑”,存储元数据、分配全局唯一时间戳(TSO)并调度 Region 分布。PD 必须是奇数个节点(通常 3 个)以确保强一致性。
- TiFlash:列存引擎,异步从 TiKV 同步数据,专为 OLAP 查询优化。其副本与 TiKV 副本独立,互不影响 OLTP 性能。
1.2 适用场景
什么时候才真的需要 TiDB 呢?你可以对照一下:
- 单表数据量超过 5 亿行,MySQL 的分库分表方案维护成本过高。
- 写入 TPS 超过单机 MySQL 上限(通常 > 5 万 TPS)。
- 需要在同一份数据上同时支持 OLTP 和实时分析查询(HTAP)。
- 需要跨地域多活部署,且对 RPO/RTO 有严格要求。
1.3 环境要求
部署前,请确保服务器满足下表的最低规格:
| 组件 |
最小规格(生产) |
推荐规格 |
说明 |
| TiDB Server |
8C 16GB |
16C 32GB |
无状态,可按负载水平扩展 |
| TiKV |
8C 32GB,SSD 1TB |
16C 64GB,NVMe 2TB |
存储节点,I/O 密集型 |
| PD |
4C 8GB,SSD 200GB |
8C 16GB |
3 节点,存储元数据 |
| TiFlash |
8C 32GB,SSD 1TB |
16C 64GB,NVMe 2TB |
按需部署,用于 OLAP 场景 |
| 操作系统 |
CentOS 7.6+ / Rocky 8+ |
Rocky Linux 8 |
需要关闭 NUMA 绑定 |
二、详细部署步骤
2.1 部署前准备
2.1.1 系统配置
TiDB 对系统配置有严格要求,以下配置必须在部署前完成,否则后续可能出现性能抖动等问题。
# 关闭 swap(TiKV 对内存压力敏感,swap 会导致性能抖动)
swapoff -a
sed -i '/swap/d' /etc/fstab
# 设置系统参数
cat >> /etc/sysctl.conf << 'EOF'
# TiDB 推荐配置
vm.swappiness = 0
net.core.somaxconn = 32768
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_syn_backlog = 16384
net.core.netdev_max_backlog = 16384
fs.file-max = 1000000
EOF
sysctl -p
# 设置文件描述符限制
cat >> /etc/security/limits.conf << 'EOF'
tidb soft nofile 1000000
tidb hard nofile 1000000
tidb soft stack 10240
EOF
# 关闭透明大页(THP),TiKV 在 THP 开启时延迟会显著增加
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 持久化
cat >> /etc/rc.local << 'EOF'
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
EOF
# 检查 NTP 时间同步(PD 的 TSO 依赖时钟同步)
timedatectl status
chronyc tracking | grep "System time"
# 要求各节点时钟偏差 < 50ms
2.1.2 安装 TiUP
TiUP 是 TiDB 的官方部署和管理工具,类似于 MySQL 的 mysqladmin,在中控机上执行以下命令安装。
# 安装 TiUP
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
# 加载环境变量
source ~/.bashrc
# 验证安装
tiup --version
# 安装 cluster 组件
tiup cluster
2.2 集群部署
2.2.1 拓扑配置文件
下面是一个最小生产集群(3 PD + 3 TiKV + 2 TiDB)的配置示例,文件路径为 /opt/tidb/topology.yaml。
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/tidb-deploy"
data_dir: "/tidb-data"
# 日志目录
log_dir: "/tidb-log"
# 服务器资源配置
server_configs:
tidb:
log.slow-threshold: 300 # 慢查询阈值,单位 ms
performance.max-procs: 0 # 0 表示使用所有 CPU
prepared-plan-cache.enabled: true # 开启 prepared statement 缓存
tikv-client.max-batch-wait-time: 2000000 # 批量请求等待时间,单位 ns
tikv:
# RocksDB 配置
rocksdb.defaultcf.block-cache-size: "8GB" # 根据内存调整,建议内存的 30-40%
rocksdb.writecf.block-cache-size: "2GB"
# Raft 配置
raftstore.sync-log: true # 生产环境必须开启
raftstore.raft-base-tick-interval: "1s"
# 存储配置
storage.reserve-space: "5GB" # 预留空间,防止磁盘写满导致 TiKV panic
pd:
replication.max-replicas: 3 # 数据副本数
replication.location-labels: ["host"] # 副本分布策略
schedule.leader-schedule-limit: 4
schedule.region-schedule-limit: 2048
pd_servers:
- host: 10.0.1.10
- host: 10.0.1.11
- host: 10.0.1.12
tidb_servers:
- host: 10.0.1.13
port: 4000
status_port: 10080
- host: 10.0.1.14
port: 4000
status_port: 10080
tikv_servers:
- host: 10.0.1.15
port: 20160
status_port: 20180
config:
server.labels: { host: "tikv-1" }
- host: 10.0.1.16
port: 20160
status_port: 20180
config:
server.labels: { host: "tikv-2" }
- host: 10.0.1.17
port: 20160
status_port: 20180
config:
server.labels: { host: "tikv-3" }
monitoring_servers:
- host: 10.0.1.10
grafana_servers:
- host: 10.0.1.10
2.2.2 部署和启动
准备好拓扑文件后,使用 TiUP 一键完成检查、部署和启动。
# 检查拓扑配置
tiup cluster check /opt/tidb/topology.yaml --user root
# 自动修复可修复的问题
tiup cluster check /opt/tidb/topology.yaml --user root --apply
# 部署集群
tiup cluster deploy tidb-prod v8.1.0 /opt/tidb/topology.yaml --user root
# 启动集群
tiup cluster start tidb-prod
# 查看集群状态
tiup cluster display tidb-prod
# 连接 TiDB(默认 root 无密码,立即修改)
mysql -h 10.0.1.13 -P 4000 -u root
# 修改 root 密码
ALTER USER 'root'@'%' IDENTIFIED BY 'TiDB@Root2024!';
三、MySQL 兼容性边界
3.1 支持的功能
TiDB 兼容 MySQL 5.7 协议,多数 DDL、DML 和事务操作都能直接运行。存储过程、函数、触发器、分区表、JSON 类型、窗口函数等在 8.x 版本中已基本完善。
3.2 不支持或有差异的功能
这是迁移前必须逐一确认的清单,特别是外键、全文索引和 AUTO_INCREMENT 的行为差异。
-- 1. 不支持 FOREIGN KEY 约束(语法不报错,但不强制执行)
-- TiDB 会忽略外键约束,应用层需要自行保证数据完整性
-- 2. 不支持 FULLTEXT 索引
-- 需要改用 Elasticsearch 或其他全文搜索方案
-- 3. AUTO_INCREMENT 行为不同
-- TiDB 的 AUTO_INCREMENT 在分布式环境下不保证连续,只保证唯一和递增。
-- 如果业务依赖 AUTO_INCREMENT 的连续性,需要改造。
-- 推荐使用 AUTO_RANDOM 替代,避免写热点:
CREATE TABLE orders (
id BIGINT AUTO_RANDOM PRIMARY KEY, -- 随机分配,避免热点
user_id BIGINT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 4. 不支持 LOCK TABLES 和 UNLOCK TABLES
-- 需要改用事务或 SELECT ... FOR UPDATE
-- 5. 不支持 GET_LOCK() / RELEASE_LOCK()
-- 分布式锁需要用 Redis 或其他方案实现
-- 6. 存储过程中不支持游标的某些用法
-- 建议在应用层处理复杂逻辑
-- 7. 字符集:推荐使用 utf8mb4,其他字符集支持有限
3.3 事务模式选择
TiDB 的事务模式直接影响性能表现,理解其区别至关重要。
-- 悲观事务(默认,8.x 版本):行为与 MySQL 一致,适合高冲突场景
-- 乐观事务:提交时才检测冲突,适合低冲突场景,性能更好但需要处理冲突重试
-- 查看当前事务模式
SHOW VARIABLES LIKE 'tidb_txn_mode';
-- 会话级别切换
SET tidb_txn_mode = 'optimistic';
-- 全局切换(my.cnf 中配置)
-- tidb_txn_mode = "pessimistic"
四、热点问题排查
4.1 热点的成因
热点是 TiDB 运维中的头号敌人。当大量请求集中到少数 Region 上,会导致对应的 TiKV 节点 CPU 和 I/O 打满,而其他节点却很空闲。常见场景有:
- AUTO_INCREMENT 写热点:顺序递增的主键使新数据总是写入最后一个 Region。
- 时间序列写热点:按时间排序的数据(如日志表)写入模式类似。
- 热门数据读热点:某些热门商品或用户信息被超高频率地读取。
4.2 热点排查
通过 TiDB Dashboard 或 SQL 都能进行热点分析。
-- 通过 TiDB Dashboard 查看热点(推荐)
-- 访问 http://10.0.1.10:2379/dashboard
-- 通过 SQL 查看热点 Region
SELECT * FROM information_schema.TIKV_REGION_STATUS
WHERE IS_INDEX = 0
ORDER BY WRITTEN_BYTES DESC
LIMIT 20;
-- 查看热点表
SELECT TABLE_NAME, WRITTEN_BYTES, READ_BYTES
FROM information_schema.TIKV_REGION_STATUS
WHERE IS_INDEX = 0
ORDER BY WRITTEN_BYTES + READ_BYTES DESC
LIMIT 10;
-- 查看 Region 分布是否均匀
SELECT STORE_ID, COUNT(*) as region_count
FROM information_schema.TIKV_REGION_STATUS
GROUP BY STORE_ID
ORDER BY region_count DESC;
4.3 热点解决方案
新表设计时,应优先考虑 AUTO_RANDOM 和预分裂 Region。
-- 方案一:使用 AUTO_RANDOM 替代 AUTO_INCREMENT(推荐)
-- AUTO_RANDOM 在高位随机填充,数据均匀分布到所有 Region
ALTER TABLE orders MODIFY COLUMN id BIGINT AUTO_RANDOM;
-- 方案二:SHARD_ROW_ID_BITS(对已有表)
-- 将行 ID 的高位用于分片,减少热点
ALTER TABLE logs SHARD_ROW_ID_BITS = 4; -- 分成 2^4=16 个分片
-- 方案三:PRE_SPLIT_REGIONS(建表时预分裂)
-- 建表时就创建多个 Region,避免初始写入热点
CREATE TABLE events (
id BIGINT AUTO_RANDOM PRIMARY KEY,
event_type VARCHAR(50),
created_at TIMESTAMP
) PRE_SPLIT_REGIONS = 4; -- 预分裂为 4 个 Region
-- 方案四:手动分裂热点 Region
-- 找到热点 Region ID 后手动分裂
-- 通过 TiDB Dashboard 或 pd-ctl 操作
五、故障排查和监控
一套完善的运维/DevOps/SRE体系离不开高效的监控。TiDB Dashboard 是日常运维的核心入口。
5.1 Dashboard 监控关键指标
Dashboard 内置于 PD,访问 http://<pd-ip>:2379/dashboard 即可。需重点关注以下面板:
Overview 面板:
- QPS:每秒查询数,区分 SELECT/INSERT/UPDATE/DELETE
- Latency:P99 延迟,正常应 < 100ms
- Connection Count:连接数,接近 max_connections 时告警
TiKV 面板:
- gRPC Duration:TiDB 到 TiKV 的 RPC 延迟,P99 > 50ms 需关注
- Storage:各 TiKV 节点的磁盘使用量,不均匀说明有热点
- Raft Store CPU:Raft 处理 CPU,持续 > 80% 说明写入压力过大
PD 面板:
- Region Health:unhealthy region 数量,正常应为 0
- Scheduler:Region 调度频率,频繁调度说明集群不均衡
- TSO:时间戳分配延迟,P99 > 2ms 需关注
5.2 慢查询分析
TiDB 将慢查询存储在系统表中,方便排查。
-- 查看慢查询日志
SELECT query_time, parse_time, compile_time, exec_details,
query, user, db
FROM information_schema.SLOW_QUERY
WHERE query_time > 1 -- 超过 1 秒
ORDER BY query_time DESC
LIMIT 20;
-- 分析执行计划
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 12345;
-- 查看是否走了全表扫描
-- 关注 task 列中的 "TableFullScan",应尽量避免
-- 强制使用索引
SELECT * FROM orders USE INDEX (idx_user_id) WHERE user_id = 12345;
-- 查看统计信息是否过期(统计信息不准会导致执行计划退化)
SHOW STATS_META WHERE table_name = 'orders';
-- 手动更新统计信息
ANALYZE TABLE orders;
5.3 常见问题排查
5.3.1 日志查看
# TiDB Server 日志
tail -f /tidb-log/tidb/tidb.log | grep -i "error\|warn"
# TiKV 日志
tail -f /tidb-log/tikv/tikv.log | grep -i "error\|slow"
# PD 日志
tail -f /tidb-log/pd/pd.log | grep -i "error\|warn"
# 通过 TiUP 查看集群状态
tiup cluster display tidb-prod
# 查看组件日志
tiup cluster audit tidb-prod
5.3.2 常见问题
问题一:写入延迟突然升高
# 检查 TiKV 磁盘 I/O
iostat -x 1 5
# 检查是否有 Region 调度风暴
# 访问 Dashboard -> PD -> Scheduler 面板
# 检查 RocksDB compaction 是否积压
grep "compaction" /tidb-log/tikv/tikv.log | tail -20
问题二:事务冲突导致大量重试
-- 查看事务冲突统计
SHOW STATUS LIKE 'tidb_txn_retry%';
-- 查看锁等待情况
SELECT * FROM information_schema.DATA_LOCK_WAITS;
-- 查看当前活跃事务
SELECT * FROM information_schema.TIDB_TRX WHERE state = 'LockWaiting';
问题三:Region 不均衡
# 使用 pd-ctl 查看 Region 分布
tiup ctl:v8.1.0 pd -u http://10.0.1.10:2379 region --jq '.regions | map(select(.leader.store_id)) | group_by(.leader.store_id) | map({store: .[0].leader.store_id, count: length})'
# 触发手动均衡
tiup ctl:v8.1.0 pd -u http://10.0.1.10:2379 operator add balance-region <region-id>
5.4 关键性能指标速查
| 指标名称 |
正常范围 |
告警阈值 |
说明 |
| QPS P99 延迟 |
< 50ms |
> 200ms |
整体查询延迟 |
| TiKV gRPC P99 |
< 20ms |
> 100ms |
TiDB 到 TiKV 的 RPC 延迟 |
| PD TSO P99 |
< 2ms |
> 10ms |
时间戳分配延迟 |
| Region 健康数 |
0 |
> 0 |
异常 Region 数量 |
| TiKV CPU |
< 70% |
> 90% |
TiKV 节点 CPU 使用率 |
| Raft apply log duration |
< 1ms |
> 10ms |
Raft 日志应用延迟 |
5.5 备份与恢复
使用 BR 工具进行全量与增量备份,并可实现高效恢复。
# 使用 BR(Backup & Restore)工具进行全量备份
tiup br backup full \
--pd "10.0.1.10:2379" \
--storage "local:///backup/tidb/$(date +%Y%m%d)" \
--log-file /var/log/tidb/br_backup.log \
--concurrency 4
# 增量备份(基于上次备份的时间点),存储到 S3
tiup br backup full \
--pd "10.0.1.10:2379" \
--storage "s3://your-bucket/tidb-backup/$(date +%Y%m%d)" \
--s3.endpoint "https://s3.amazonaws.com" \
--log-file /var/log/tidb/br_backup.log
# 恢复
tiup br restore full \
--pd "10.0.1.10:2379" \
--storage "local:///backup/tidb/20240101" \
--log-file /var/log/tidb/br_restore.log
# 查看备份信息
tiup br validate decode \
--field "end-version" \
--storage "local:///backup/tidb/20240101"
六、总结与展望
6.1 TiFlash HTAP 场景
为需要分析的表创建 TiFlash 副本,可以让分析查询在不影响 OLTP 的前提下运行。
-- 为表创建 TiFlash 副本
ALTER TABLE orders SET TIFLASH REPLICA 1;
-- 查看 TiFlash 同步进度
SELECT * FROM information_schema.TIFLASH_REPLICA
WHERE TABLE_NAME = 'orders';
-- 强制查询走 TiFlash(分析查询)
SELECT /*+ READ_FROM_STORAGE(TIFLASH[orders]) */
DATE(created_at) as date,
COUNT(*) as order_count,
SUM(amount) as total_amount
FROM orders
WHERE created_at >= '2024-01-01'
GROUP BY DATE(created_at)
ORDER BY date;
-- TiDB 优化器会自动选择 TiKV 或 TiFlash
-- OLTP 查询走 TiKV,OLAP 查询走 TiFlash
6.2 迁移决策
不是所有场景都适合迁移。只有当单表数据量、写入压力成为瓶颈,或需要一套系统同时满足 OLTP 与实时分析需求时,TiDB 才真正体现了它的价值。如果数据量小于 1TB、写入 TPS 不到 1 万,或者重度依赖外键等 MySQL 特有功能,或许维持现状是更好的选择。
6.3 技术要点回顾
- 理解架构是前提:TiDB Server、TiKV、PD 三者职责清晰,定位问题时要对应到具体组件。
- 热点是首要敌人:新表设计一律推荐
AUTO_RANDOM,这是血的教训。
- 摸清兼容性边界:外键、
FULLTEXT、LOCK TABLES 等不支持项,迁移前必须核实。
- TiFlash 按需开启:只为有实时分析需求的表创建副本,避免浪费资源。
- 善用 Dashboard:它集成了热点、慢查询、集群拓扑等关键信息,是运维的核心工具。
附录 A. 命令速查表
# 查看集群状态
tiup cluster display tidb-prod
# 启动/停止/重启集群
tiup cluster start tidb-prod
tiup cluster stop tidb-prod
tiup cluster restart tidb-prod
# 滚动重启单个组件
tiup cluster restart tidb-prod -R tidb
# 扩容(添加新 TiKV 节点)
tiup cluster scale-out tidb-prod scale-out.yaml
# 缩容(移除 TiKV 节点,会自动迁移数据)
tiup cluster scale-in tidb-prod --node 10.0.1.18:20160
# 升级集群版本
tiup cluster upgrade tidb-prod v8.2.0
# 查看慢查询
mysql -h 10.0.1.13 -P 4000 -u root -p -e \
"SELECT query_time, query FROM information_schema.SLOW_QUERY ORDER BY query_time DESC LIMIT 10;"
附录 B. 关键配置参数
| 参数 |
默认值 |
说明 |
tidb_slow_log_threshold |
300ms |
慢查询记录阈值 |
tidb_txn_mode |
pessimistic |
事务模式,pessimistic/optimistic |
tidb_mem_quota_query |
1GB |
单个查询最大内存使用量 |
tidb_distsql_scan_concurrency |
15 |
分布式扫描并发度 |
rocksdb.defaultcf.block-cache-size |
系统内存 45% |
RocksDB 块缓存大小 |
storage.reserve-space |
5GB |
TiKV 预留磁盘空间 |
附录 C. 术语表
| 术语 |
英文 |
解释 |
| 区域 |
Region |
TiKV 数据分片单位,默认 96MB,每个 Region 有 3 个 Raft 副本 |
| 放置驱动 |
PD (Placement Driver) |
集群元数据管理和调度中心 |
| 热点 |
Hotspot |
大量请求集中到少数 Region,导致负载不均衡 |
| 列存引擎 |
TiFlash |
TiDB 的 OLAP 列存储引擎,异步同步 TiKV 数据 |
| 混合事务分析 |
HTAP |
在同一系统中同时支持 OLTP 和 OLAP 工作负载 |
| 全局事务标识 |
TSO (Timestamp Oracle) |
PD 分配的全局唯一单调递增时间戳,用于 MVCC |