一、监控体系概览
1.1 TiDB 监控架构
TiDB 使用业界标准的 Prometheus + Grafana 监控体系:
监控数据流:
┌──────┐ ┌──────┐ ┌──────┐
│ TiDB │ │ TiKV │ │ PD │
└──┬───┘ └──┬───┘ └──┬───┘
│ │ │
└────┬────┘────┬────┘
│ │
┌────┴─────────┴────┐
│ Prometheus │ 采集和存储监控指标
│ (每 15s 拉取) │
└────┬─────────┬────┘
│ │
┌────┴────┐┌───┴──────┐
│ Grafana ││ Alertm- │
│(可视化) ││ gr(告警) │
└─────────┘└──────────┘
1.2 监控组件部署
监控组件通常与 TiDB 一起部署:
# topology.yaml
monitoring_servers:
- host: 10.0.1.30
port: 9090
deploy_dir: "/tidb-deploy/prometheus-9090"
data_dir: "/tidb-data/prometheus-9090"
retention: "30d" # 保留 30 天数据
grafana_servers:
- host: 10.0.1.30
port: 3000
deploy_dir: "/tidb-deploy/grafana-3000"
alertmanager_servers:
- host: 10.0.1.30
port: 9093
deploy_dir: "/tidb-deploy/alertmanager-9093"
data_dir: "/tidb-data/alertmanager-9093"
二、TiDB Dashboard
2.1 访问 Dashboard
URL: http://<PD_HOST>:2379/dashboard
默认账号: root
密码: 初次访问时设置
Dashboard 提供的核心功能:
| 功能 | 用途 |
|---|---|
| 集群概览 | 整体 QPS、延迟、存储使用率 |
| Top SQL | 资源消耗最高的 SQL 语句 |
| 流量可视化 | 数据流动的热力图 |
| 慢查询分析 | 定位慢查询及其执行计划 |
| 集群诊断 | 自动诊断集群问题并给出建议 |
| 日志搜索 | 集中查看所有组件日志 |
| SQL 语句分析 | 分析 SQL 的执行统计信息 |
| 实例性能分析 | 持续 Profiling 分析 |
2.2 集群概览页面
集群概览页面展示了关键指标:
┌────────────────────────────────────────────────┐
│ 集群概览 │
│ │
│ QPS: 12,345 │ P99 延迟: 5.2ms │
│ 存储使用: 2.3TB/5TB│ TiKV 节点: 5 │
│ 活跃连接: 234 │ Region 总数: 15,000 │
│ │
│ ┌──────────────────┐ ┌─────────────────────┐ │
│ │ QPS 趋势 (1h) │ │ 延迟趋势 (1h) │ │
│ │ ╱╲ ╱╲ │ │ │ │
│ │ ╱ ╲ ╱ ╲ │ │ ────────────── │ │
│ │╱ ╲╱ ╲ │ │ │ │
│ └──────────────────┘ └─────────────────────┘ │
└────────────────────────────────────────────────┘
2.3 Top SQL
Top SQL 页面显示资源消耗最高的 SQL:
┌──────────────────────────────────────────────────┐
│ Top SQL (过去 1 小时) │
│ │
│ # │ SQL Digest │ CPU% │ 执行次数 │ 延迟 │
│ ───┼─────────────────────┼──────┼─────────┼──────│
│ 1 │ SELECT * FROM ... │ 45% │ 125,340 │ 2.1ms│
│ 2 │ INSERT INTO ... │ 32% │ 89,210 │ 1.5ms│
│ 3 │ UPDATE orders ... │ 18% │ 45,670 │ 5.8ms│
│ 4 │ DELETE FROM ... │ 5% │ 1,230 │ 12ms │
│ │
│ 点击任意行可查看执行计划和详细统计 │
└──────────────────────────────────────────────────┘
三、慢查询分析
3.1 慢查询日志
-- 设置慢查询阈值(单位:纳秒)
-- 300ms = 300000000 纳秒
SET GLOBAL tidb_slow_log_threshold = 300000000;
-- 查看所有慢查询
SELECT * FROM information_schema.slow_query
WHERE Time > NOW() - INTERVAL 1 HOUR
ORDER BY Query_time DESC
LIMIT 20;
3.2 慢查询字段解读
SELECT
Time, -- 执行时间
Query_time, -- 总耗时(秒)
Parse_time, -- 解析时间
Compile_time, -- 编译时间
Rewrite_time, -- 重写时间
Process_time, -- TiKV 处理时间
Wait_time, -- TiKV 等待时间
Request_count, -- 请求次数
Process_keys, -- 处理的 KV 数
Total_keys, -- 扫描的 KV 总数
Mem_max, -- 最大内存使用
Result_rows, -- 返回行数
Succ, -- 是否成功
Query -- SQL 语句
FROM information_schema.slow_query
WHERE Query_time > 1
ORDER BY Query_time DESC
LIMIT 10;
关键字段分析:
| 字段 | 说明 | 优化方向 |
|---|---|---|
Query_time |
总耗时 | 综合优化 |
Process_time |
TiKV 处理时间 | 加索引、优化查询 |
Process_keys |
处理的行数 | 缩小扫描范围 |
Total_keys |
扫描的 KV 数 | 避免全表扫描 |
Mem_max |
内存峰值 | 减少排序/Join 数据量 |
3.3 慢查询案例
-- 示例: 一条慢查询
-- Query_time: 3.5s
-- Process_keys: 5000000
-- Total_keys: 5000000
-- Query: SELECT * FROM orders WHERE status = 'pending' ORDER BY created_at DESC LIMIT 100;
-- 分析:
-- 1. Process_keys = Total_keys = 500万,说明是全表扫描
-- 2. 没有使用 status 索引
-- 优化:
-- 方案 1: 添加索引
CREATE INDEX idx_status_created ON orders(status, created_at);
-- 方案 2: 如果 status 区分度很低(大量 pending),考虑组合索引
CREATE INDEX idx_created_status ON orders(created_at, status);
四、集群诊断
4.1 自动诊断
TiDB Dashboard 的集群诊断功能会自动检查以下方面:
| 检查项 | 说明 |
|---|---|
| CPU 使用率 | 是否持续过高 |
| 磁盘 I/O | 是否有 I/O 瓶颈 |
| 内存使用 | 是否有 OOM 风险 |
| Region 健康 | 是否有 Region 缺失副本 |
| Region 分布 | 是否均衡 |
| TiKV 负载 | 是否有热点节点 |
| 慢查询 | 是否有异常多的慢查询 |
| DDL 状态 | 是否有长时间未完成的 DDL |
4.2 手动诊断 SQL
-- 查看集群组件状态
SELECT type, instance, STATUS_ADDRESS, start_time
FROM information_schema.cluster_info;
-- 查看 TiKV Store 状态
SELECT
STORE_ID,
ADDRESS,
STORE_STATE_NAME,
LEADER_COUNT,
REGION_COUNT,
CAPACITY,
AVAILABLE
FROM information_schema.tikv_store_status
ORDER BY STORE_ID;
-- 查看 Region 分布
SELECT
REGION_ID,
START_KEY,
END_KEY,
APPROXIMATE_SIZE,
APPROXIMATE_KEYS
FROM information_schema.tikv_region_status
LIMIT 10;
-- 查看当前活跃连接
SELECT * FROM information_schema.processlist
WHERE COMMAND != 'Sleep'
ORDER BY TIME DESC
LIMIT 20;
五、常见故障与排查
5.1 TiDB OOM
现象:TiDB Server 进程被系统 OOM Killer 终止。
排查步骤:
-- 1. 查看运行时间长的查询(可能是内存密集型)
SELECT * FROM information_schema.processlist
WHERE COMMAND != 'Sleep'
ORDER BY TIME DESC;
-- 2. 检查内存限制配置
SHOW VARIABLES LIKE 'tidb_mem_quota_query';
-- 3. 设置单查询内存限制(1GB)
SET GLOBAL tidb_mem_quota_query = 1073741824;
-- 4. 查看 OOM 相关日志
-- 登录 TiDB Server 机器查看日志
tail -100 /tidb-deploy/tidb-4000/log/tidb.log | grep -i "oom\|memory"
常见原因:
| 原因 | 对策 |
|---|---|
| 大 Join | 限制 Join 表大小或使用 Index Join |
| 大排序 | 增加索引,减少排序数据量 |
| 聚合大量数据 | 分页或分区处理 |
tidb_mem_quota_query 设置过大 |
适当降低 |
5.2 写入延迟增加
现象:INSERT/UPDATE 操作耗时显著增加。
排查步骤:
-- 1. 检查 TiKV 负载
SELECT
STORE_ID,
ADDRESS,
LEADER_COUNT,
REGION_COUNT
FROM information_schema.tikv_store_status
ORDER BY LEADER_COUNT DESC;
-- 如果某个节点 Leader 数量远高于其他节点,可能存在热点
-- 2. 检查慢查询
SELECT Query, Query_time
FROM information_schema.slow_query
WHERE Query LIKE 'INSERT%' OR Query LIKE 'UPDATE%'
ORDER BY Query_time DESC
LIMIT 10;
-- 3. 检查 Raft 状态
-- 在 Grafana 中查看 TiKV-Raft 面板
-- 关注 Raft Propose Wait Duration
常见原因:
| 原因 | 对策 |
|---|---|
| 写入热点 | 使用 AUTO_RANDOM 或 SHARD_ROW_ID_BITS |
| 磁盘 I/O 瓶颈 | 升级 SSD,检查磁盘使用率 |
| Region 过大 | Split Region |
| GC 压力大 | 调整 GC 间隔和版本历史保留时间 |
5.3 读写延迟增加
排查思路:
延迟增加
│
├── 检查 CPU 使用率
│ └── 高 → 检查 Top SQL
│
├── 检查磁盘 I/O
│ └── 高 → 检查是否有大查询在做全表扫描
│
├── 检查网络延迟
│ └── 高 → 检查网络带宽和丢包
│
├── 检查 Region 健康
│ └── 有缺失副本 → 等待恢复或手动修复
│
└── 检查锁等待
└── 有长时间锁等待 → 检查长事务
-- 检查锁等待
SELECT * FROM information_schema.data_lock_waits;
-- 检查长事务
SELECT * FROM information_schema.tidb_trx
ORDER BY START_TIME ASC
LIMIT 10;
-- 检查正在执行的查询
SELECT * FROM information_schema.processlist
WHERE COMMAND != 'Sleep' AND TIME > 10
ORDER BY TIME DESC;
5.4 Region 热点问题
现象:某个 TiKV 节点的 CPU 或 I/O 使用率远高于其他节点。
排查:
# 通过 PD API 查看热点 Region
curl http://10.0.1.11:2379/pd/api/v1/hotspot/regions/read
curl http://10.0.1.11:2379/pd/api/v1/hotspot/regions/write
-- 通过 Dashboard 流量可视化页面
-- 查看是否有明显的热点区域
解决:
-- 方案 1: 使用 AUTO_RANDOM 代替 AUTO_INCREMENT
CREATE TABLE t (id BIGINT PRIMARY KEY AUTO_RANDOM, ...);
-- 方案 2: 对已有表打散 Row ID
-- 需要重建表(无法在线修改)
-- 方案 3: 手动分裂热点 Region
SPLIT TABLE t BETWEEN (0) AND (1000000000) REGIONS 16;
六、Grafana 监控面板
6.1 关键面板
通过 http://<grafana-host>:3000 访问 Grafana。
核心仪表板:
| 面板名称 | 关注指标 |
|---|---|
| TiDB-Summary | QPS、延迟、连接数 |
| TiDB-Overview | 整体性能概览 |
| TiKV-Summary | QPS、延迟、存储使用 |
| TiKV-Details | 详细的 TiKV 指标 |
| PD | 调度、TSO、Region 状态 |
| TiFlash-Summary | TiFlash 查询性能 |
6.2 关键指标
TiDB 层面
| 指标 | 正常值 | 告警阈值 |
|---|---|---|
| QPS | 视业务而定 | 突降 50%+ |
| P99 延迟 | < 50ms | > 200ms |
| 连接数 | 视配置而定 | > 最大连接数 80% |
| 内存使用 | < 80% | > 90% |
TiKV 层面
| 指标 | 正常值 | 告警阈值 |
|---|---|---|
| CPU 使用率 | < 70% | > 85% |
| 磁盘使用率 | < 80% | > 85% |
| Raft 延迟 | < 10ms | > 100ms |
| gRPC 延迟 | < 5ms | > 50ms |
| 慢查询数 | 0 | > 10/min |
PD 层面
| 指标 | 正常值 | 告警阈值 |
|---|---|---|
| TSO 延迟 | < 5ms | > 50ms |
| Region 未调度数 | 0 | > 100 |
| Leader 均衡度 | 各节点相差 < 20% | 相差 > 50% |
七、告警配置
7.1 告警规则
TiDB 预置了完整的告警规则,可以在 Alertmanager 中查看和修改:
# 查看告警规则
curl http://10.0.1.30:9090/api/v1/rules | jq '.data.groups[].rules[] | select(.type == "alerting") | .name'
7.2 配置告警通知
# alertmanager.yml
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'instance']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'webhook'
receivers:
- name: 'webhook'
webhook_configs:
- url: 'http://your-alert-system/webhook'
send_resolved: true
7.3 常用告警通道
| 通道 | 配置方式 |
|---|---|
| 企业微信 | Webhook / API |
| 钉钉 | Webhook |
| 邮件 | SMTP |
| Slack | Webhook |
| PagerDuty | API Key |
八、日常巡检清单
8.1 每日检查
-- 1. 检查集群状态
SELECT type, instance, STATUS_ADDRESS FROM information_schema.cluster_info;
-- 2. 检查慢查询数量
SELECT COUNT(*) FROM information_schema.slow_query
WHERE Time > NOW() - INTERVAL 1 DAY;
-- 3. 检查存储使用
SELECT
ADDRESS,
ROUND(AVAILABLE * 100.0 / CAPACITY, 1) AS available_pct
FROM information_schema.tikv_store_status;
8.2 每周检查
- 检查 Grafana 监控面板的趋势图
- 检查备份是否按时完成
- 检查磁盘使用率趋势
- 检查是否有未完成的 DDL
8.3 每月检查
- 评估容量规划(是否需要扩容)
- 检查版本更新,计划升级
- 做一次恢复演练
- 审查告警规则,优化阈值