做 Oracle 运维的时候,日常巡检的习惯是看实例、表空间、ASM、归档、Data Guard、Job,再扫一眼告警和异常会话。很多问题当前可能没影响业务,但状态和前一天不一样,通常就需要多看一下。这篇主要结合原有业务以及原来Oracle的检查顺序,把 TiDB 的常用巡检命令和系统表做下整理记录。
下面的环境和输出主要来源于测试环境,不包含实际的业务环境数据。对应的版本为 TiDB 8.5.0,地址、业务库和账号如下:
一、实验环境与账号
节点和地址环境规划
| 组件或配置 | 地址或取值 | 数量 |
|---|---|---|
| TiDB Server | 10.20.10.11:4000、10.20.10.12:4000 |
2 |
| PD | 10.20.10.21~10.20.10.23,端口 2379 |
3 |
| TiKV | 10.20.10.31~10.20.10.33,端口 20160 |
3 |
| Prometheus / Grafana | 10.20.10.41 |
1 |
| TiDB Dashboard | 通过 PD 地址访问 | — |
| TiDB 版本 | v8.5.0 | — |
| TiUP 集群名 | hospital-tidb85 |
— |
业务库和应用账号按医院里常见的系统区分:
| 业务系统 | 业务库 | 应用账号 |
|---|---|---|
| HIS | his_lab |
his_app |
| EMR | emr_lab |
emr_app |
| LIS | lis_lab |
lis_app |
| 医院集成平台 | hip_lab |
hip_app |
下面的 SQL 按 DBA 巡检账号编写,查看其他应用账号的完整会话、事务信息需要 PROCESS 权限;权限不足时,只能看到当前账号自己的相关记录。
二、第一眼还是看 TiUP
登录中控机后,从下面这条命令开始。TiUP Cluster 负责集群部署、启停、扩缩容等管理,日常巡检用 display 查看组件运行状态。
tiup cluster display hospital-tidb85
节点状态示例,只保留组件、实例和状态:
| 组件 | 实例 | 状态 |
|---|---|---|
| pd | 10.20.10.21:2379 |
Up |
| pd | 10.20.10.22:2379 |
Up |
| pd | 10.20.10.23:2379 |
Up |
| tikv | 10.20.10.31:20160 |
Up |
| tikv | 10.20.10.32:20160 |
Up |
| tikv | 10.20.10.33:20160 |
Up |
| tidb | 10.20.10.11:4000 |
Up |
| tidb | 10.20.10.12:4000 |
Up |
这里把节点数量和环境规划对照,检查当前状态。所有节点都显示 Up 时,还需要核对启动时间:如果之前已经连续运行一个月,今天却只运行了十几分钟,就要查是否发生过异常重启。启动时间放到下面的 CLUSTER_INFO 里看。
三、进数据库以后,再从 CLUSTER_INFO 对一遍
连进数据库后,用 CLUSTER_INFO 查看集群拓扑。它提供组件类型、实例地址、HTTP 状态地址、版本、启动时间和运行时长,便于和部署规划核对。
SELECT
TYPE,
INSTANCE,
STATUS_ADDRESS,
VERSION,
START_TIME,
UPTIME
FROM information_schema.CLUSTER_INFO
ORDER BY TYPE, INSTANCE;
集群信息,表中省略 STATUS_ADDRESS 列,版本只列组件版本,运行时长按天和小时简写:
| TYPE | INSTANCE | VERSION | START_TIME | UPTIME(约) |
|---|---|---|---|---|
| pd | 10.20.10.21:2379 |
8.5.0 | 2026-09-01 22:10:11 | 12 天 10 小时 |
| pd | 10.20.10.22:2379 |
8.5.0 | 2026-09-01 22:11:03 | 12 天 10 小时 |
| pd | 10.20.10.23:2379 |
8.5.0 | 2026-09-01 22:12:07 | 12 天 10 小时 |
| tidb | 10.20.10.11:4000 |
8.5.0 | 2026-09-01 22:16:31 | 12 天 10 小时 |
| tidb | 10.20.10.12:4000 |
8.5.0 | 2026-09-01 22:17:10 | 12 天 10 小时 |
| tikv | 10.20.10.31:20160 |
8.5.0 | 2026-09-01 22:13:20 | 12 天 10 小时 |
| tikv | 10.20.10.32:20160 |
8.5.0 | 2026-09-01 22:14:08 | 12 天 10 小时 |
| tikv | 10.20.10.33:20160 |
8.5.0 | 2026-09-01 22:14:46 | 12 天 10 小时 |
对照部署规划核对组件数量和版本,再比较 START_TIME。某个 TiKV 的 UPTIME 只有 18m、其他节点已经运行十几天时,即使业务没有告警,也要查对应节点日志或 systemd 记录,确认这次重启是否在计划内。
四、Dashboard 看整体变化
Dashboard 这一步,我通过 PD 地址访问,入口格式是 http://<pd-ip>:2379/dashboard/。多 PD 环境可以从任意 PD 地址进入,前提是浏览器能访问各 PD 实例及端口;如果有防火墙或反向代理,需要按实际部署处理访问路径。
Overview 页面可以查看节点状态、QPS 和查询延迟趋势,也有累计耗时较高的 SQL、慢查询以及监控和告警入口。相关页面依赖已部署的监控组件:例如 QPS 和延迟图需要 Prometheus,告警入口需要 Alertmanager。
在这里主要看和平时不一样的地方。例如,实例页面里一台 TiKV 的启动时间变了,或者没有业务变更,查询延迟却比平时高了一截。慢查询里突然多出一批 hip_app 的接口查询,也要带着账号和 SQL 信息继续查,不需要把每张图都截图、解释一遍。
五、TiKV 空间单独看
Oracle 巡检时看表空间和 ASM,在 TiDB 里则要看 TiKV Store 的容量和剩余空间。TIKV_STORE_STATUS 通过 PD API 提供 Store 状态、容量等信息,下面这条 SQL 取日常检查需要的字段。
SELECT
STORE_ID,
ADDRESS,
STORE_STATE_NAME,
CAPACITY,
AVAILABLE,
UPTIME
FROM information_schema.TIKV_STORE_STATUS
ORDER BY STORE_ID;
Store 状态示例,运行时长按天和小时简写:
| STORE_ID | ADDRESS | STORE_STATE_NAME | CAPACITY | AVAILABLE | UPTIME(约) |
|---|---|---|---|---|---|
| 1 | 10.20.10.31:20160 |
Up | 1.80 TiB | 1.21 TiB | 12 天 10 小时 |
| 4 | 10.20.10.32:20160 |
Up | 1.80 TiB | 1.18 TiB | 12 天 10 小时 |
| 5 | 10.20.10.33:20160 |
Up | 1.80 TiB | 1.20 TiB | 12 天 10 小时 |
除了当前还剩多少空间,也要看变化趋势。这组三台 TiKV 的容量相同,可以比较剩余空间是否接近,再和前一天的记录对照。如果一天内突然少了一大块空间,或者某个 Store 的剩余空间明显低于另外两台,就继续查 Region、副本和热点分布。容量和 Region 后面单独写。
六、医院应用连接不能只看总数
业务正常时,数据库连接数通常有自己的规律。比如 HIS 应用服务器较多,连接可能比 LIS 多;接口平台会保留一批长连接。按应用账号和 TiDB 节点分别统计,方便和各系统平时的连接数比较。
SHOW PROCESSLIST 查看的是当前 TiDB 节点:
SHOW PROCESSLIST;
两台 TiDB Server 的连接放在一起统计时,查 CLUSTER_PROCESSLIST:
SELECT
INSTANCE,
USER,
DB,
COMMAND,
COUNT(*) AS session_count
FROM information_schema.CLUSTER_PROCESSLIST
WHERE USER IN (
'his_app',
'emr_app',
'lis_app',
'hip_app'
)
GROUP BY
INSTANCE,
USER,
DB,
COMMAND
ORDER BY USER, INSTANCE, COMMAND;
这里的 INSTANCE 是 TiDB 状态服务地址。示例按默认状态端口 10080 整理,与应用连接使用的 4000 端口分开;实际地址可以和 CLUSTER_INFO.STATUS_ADDRESS 对照。
连接统计:
| INSTANCE | USER | DB | COMMAND | session_count |
|---|---|---|---|---|
10.20.10.11:10080 |
emr_app | emr_lab | Sleep | 18 |
10.20.10.12:10080 |
emr_app | emr_lab | Sleep | 17 |
10.20.10.11:10080 |
hip_app | hip_lab | Sleep | 8 |
10.20.10.12:10080 |
hip_app | hip_lab | Sleep | 9 |
10.20.10.11:10080 |
his_app | his_lab | Sleep | 36 |
10.20.10.12:10080 |
his_app | his_lab | Sleep | 34 |
10.20.10.11:10080 |
lis_app | lis_lab | Sleep | 10 |
10.20.10.12:10080 |
lis_app | lis_lab | Sleep | 11 |
这些数字没有统一的“正常标准”,要和医院自己的连接基线比较。如果 HIS 平时六七十个连接,某天突然出现几百个,就需要查这段时间应用侧有什么变化。接口平台的连接突然全没了,或者连接长期明显偏向一台 TiDB Server,也需要结合连接池和应用访问情况继续看。
七、有连接不代表正在执行 SQL
看完连接数,再用下面的条件筛出持续时间较长的非空闲会话。TIME 的单位是秒,COMMAND <> 'Sleep' 排除了空闲连接;这里的 30 秒只是示例过滤条件,没有把它当成统一的故障阈值。
SELECT
INSTANCE,
ID,
USER,
HOST,
DB,
TIME,
STATE,
LEFT(INFO, 200) AS SQL_TEXT
FROM information_schema.CLUSTER_PROCESSLIST
WHERE COMMAND <> 'Sleep'
AND TIME >= 30
ORDER BY TIME DESC;
非空闲会话示例,摘录部分字段:
| INSTANCE | USER | DB | TIME | STATE |
|---|---|---|---|---|
10.20.10.12:10080 |
hip_app | hip_lab | 46 | autocommit |
这条记录按接口历史数据查询来分析。检查到持续 46 秒的会话,先确认它是否在处理大批量数据,再查执行计划有没有变化,不直接 KILL。TiDB 8.5 默认开启 Global Kill,可以跨 TiDB 实例终止连接或查询;如果修改过 enable-global-kill,需要按实际配置判断。终止会话要结合业务确认,不列为每天固定执行的巡检动作。
八、长事务比长 SQL 更容易被忽略
一条 SQL 执行完,不代表事务已经结束。医院收费、库存和接口批处理程序如果开启事务后没有及时提交,事务可能一直留在那里。用 CLUSTER_TIDB_TRX 查看整个集群的事务;只查当前 TiDB 节点时,对应的表是 TIDB_TRX。TIDB_TRX 与 CLUSTER_TIDB_TRX
把筛选条件设为 60 秒,查看持续时间较长的事务。这个时间只用于本节筛选,不作为统一的故障阈值:
SELECT
INSTANCE,
ID AS trx_id,
START_TIME,
TIMESTAMPDIFF(
SECOND,
START_TIME,
NOW()
) AS trx_seconds,
STATE,
USER,
DB,
SESSION_ID,
MEM_BUFFER_KEYS,
MEM_BUFFER_BYTES,
LEFT(
CURRENT_SQL_DIGEST_TEXT,
200
) AS current_sql
FROM information_schema.CLUSTER_TIDB_TRX
WHERE START_TIME < NOW() - INTERVAL 60 SECOND
ORDER BY START_TIME;
表中包含事务开始时间、状态、会话 ID 和内存缓冲区写入量。CURRENT_SQL_DIGEST_TEXT 是当前语句的归一化文本,不包含参数原值;事务空闲或无法从语句摘要中找到对应文本时,它可能为 NULL。这些字段在 TiDB 8.5 中可用,也可以直接查看表定义:
DESC information_schema.CLUSTER_TIDB_TRX;
长事务示例,摘录部分字段:
| USER | DB | trx_seconds | STATE |
|---|---|---|---|
| his_app | his_lab | 214 | Idle |
表中事务持续 214 秒,当前处于 Idle,正在等待客户端发送下一条语句。碰到这种记录,要继续确认收费程序是否开启事务后没有及时提交,不能仅凭 Idle 就认定程序出错或直接终止会话。长事务和锁等待,后面放到收费业务场景里详细写。
九、早上再看一下有没有遗留 DDL
医院业务库加字段、建索引,很多时候会放在夜间处理。检查这部分时,要对照变更记录确认任务是否结束,用 ADMIN SHOW DDL 看当前 DDL 状态,再用 ADMIN SHOW DDL JOBS 查看当前任务和近期历史任务。
ADMIN SHOW DDL;
ADMIN SHOW DDL JOBS 20;
没有运行中的 DDL 时,ADMIN SHOW DDL 的 RUNNING_JOBS 字段可以为空。有夜间变更任务时,按任务记录核对:昨晚提交的 ADD INDEX 到早上 STATE 仍是 running,就继续看表规模和回填进度,并确认是否影响白天的业务负载,不能只记录一个“运行中”就结束。
TiDB 8.5.0 支持动态调整部分 ADD INDEX 任务的回填参数,但要求任务是在关闭 tidb_enable_dist_task 后提交并运行的。
十、统计信息没必要每天手工 ANALYZE
统计信息这一步,先查健康度有没有明显变化,再决定是否需要处理,不把每天手工 ANALYZE 当成固定动作。
SHOW STATS_HEALTHY
WHERE Db_name IN (
'his_lab',
'emr_lab',
'lis_lab',
'hip_lab'
);
SHOW STATS_HEALTHY 返回 0~100 的健康度,用来粗略判断统计信息的状态。健康度低时可能出现次优执行计划,但这个数值不能直接当作执行计划估算的正确率。
统计信息健康度示例,只保留库名、表名和健康度:
| Db_name | Table_name | Healthy |
|---|---|---|
| his_lab | outpatient_visit | 100 |
| his_lab | charge_detail | 97 |
| emr_lab | emr_document_index | 92 |
| lis_lab | lab_request | 100 |
| hip_lab | interface_message | 86 |
不要因为 interface_message 的健康度是 86 就立即收集统计信息。如果确认需要手工收集,对应语句是:
ANALYZE TABLE hip_lab.interface_message;
自动收集也要看触发条件。tidb_auto_analyze_ratio 比较的是修改行数与总行数的比例,默认值为 0.5,不能直接拿它和 Healthy 的数值比较。自动收集开启后,还受时间窗口等条件限制;少于 1000 行的小表,不会仅因数据修改触发自动收集。
决定是否人工干预前,要结合最近的数据变化看健康度是否持续下降,确认 Auto Analyze 是否正常。如果实际 SQL 已经出现估算偏差,再把执行计划和统计信息放在一起查。这和 Oracle 里使用 DBMS_STATS 一样,不能只因为统计信息时间旧了一点就重新收集。
十一、检查近期慢 SQL
Dashboard 可以直接查看慢查询;需要从 SQL 侧筛选时,查 CLUSTER_SLOW_QUERY。下面取最近一小时、默认库为这四个业务库的慢日志,按耗时排序查看前 20 条。
SELECT
INSTANCE,
TIME,
USER,
DB,
ROUND(QUERY_TIME, 3) AS query_time_s,
PROCESS_KEYS,
TOTAL_KEYS,
DIGEST,
LEFT(`QUERY`, 200) AS SQL_TEXT
FROM information_schema.CLUSTER_SLOW_QUERY
WHERE TIME >= NOW() - INTERVAL 1 HOUR
AND DB IN (
'his_lab',
'emr_lab',
'lis_lab',
'hip_lab'
)
ORDER BY QUERY_TIME DESC
LIMIT 20;
主要看和平时不同的 SQL。例如 HIS 某条查询原来没有进入慢日志,今天却连续出现,就要查这段时间发生了什么变化。接口平台同一个 Digest 短时间大量出现,或者 PROCESS_KEYS 很大、实际返回数据却很少,也会记下来继续排查,不能看到一条慢 SQL 就立即改索引。
十二、检查日志备份是否还在推进
检查日志备份任务的状态,任务名 hospital-pitr,对应的查询命令如下:
tiup br:v8.5.0 log status \
--task-name=hospital-pitr \
--pd "10.20.10.21:2379"
br log status 返回任务状态和日志备份进度,checkpoint[global] 表示日志已经备份到的时间点。要做 PITR,还需要目标时间点之前可用的全量快照,以及从快照衔接到目标时间点的完整日志。
日志备份状态示例,共一个任务:
| 字段 | 示例值 |
|---|---|
| name | hospital-pitr |
| status | NORMAL |
| start | 2026-09-01 00:10:00 +0800 |
| storage | s3://tidb-backup/hospital-pitr |
| checkpoint[global] | 2026-09-14 08:09:26 +0800 |
| gap | 2m18s |
把任务状态和 checkpoint 放在一起看。显示 NORMAL 时,也要确认 checkpoint 是否持续往前推进,和当前时间的差距有没有扩大。
TiDB 8.5 官方文档推荐为运行中的日志备份配置 RPO 告警:超过 10 分钟为 warning,超过 30 分钟为 critical。这些是需要配置的推荐规则,文档明确说明 PITR 没有内置这些告警项。任务进入 ERROR 时,继续用 br log status 查看失败原因,必要时查 TiKV 日志。备份恢复监控告警
十三、告警恢复了,也要查发生过什么
Prometheus、Grafana 和 Alertmanager 要按实际部署检查。部署了 Alertmanager 时,Dashboard Overview 会提供告警入口;同时要把告警时间和组件当前状态对起来看。
比如凌晨出现过 TiKV Down 告警,现在节点已经恢复,就要检查 START_TIME、节点日志和当时的监控曲线。如果是 LogBackupFailed,就查日志备份任务的失败原因和 TiKV 日志。官方文档还列出了日志备份暂停、GC SafePoint 超过 checkpoint 等推荐告警规则。
十四、日常巡检与专项检查分开
不要把全库 ANALYZE、逐表 ADMIN CHECK、逐个 Region 检查、全库 checksum 或重启组件验证,全部塞进每天的巡检。这些操作需要按具体问题安排。日常先确认状态和变化,发现异常后,再进入对应的专项检查。
十五、日常巡检表
按前面的操作顺序整理了这张巡检表,方便检查时逐项对照。检查项来自官方运维接口,并结合医院 DBA 的日常维护习惯取舍;用于具体环境时,还要按部署架构、业务系统和备份方案增减,不代表 TiDB 官方规定的医院巡检标准。
| 检查内容 | 主要工具 | 关注点 |
|---|---|---|
| 集群节点 | TiUP、CLUSTER_INFO |
当前状态、节点数量、启动时间变化 |
| 整体状态 | Dashboard | 节点、告警、SQL 异常变化 |
| TiKV Store | TIKV_STORE_STATUS |
Store 状态、容量、剩余空间、运行时长 |
| 应用连接 | CLUSTER_PROCESSLIST |
HIS、EMR、LIS 和接口账号的连接变化 |
| 持续时间较长的非空闲会话 | CLUSTER_PROCESSLIST |
当前语句、持续时间和业务用途 |
| 长事务 | CLUSTER_TIDB_TRX |
事务持续时间、Idle 状态及应用提交情况 |
| DDL | ADMIN SHOW DDL JOBS |
夜间变更是否还在执行、进度是否变化 |
| 统计信息 | SHOW STATS_HEALTHY |
健康度变化及是否需要进一步检查 |
| 慢查询 | Dashboard、CLUSTER_SLOW_QUERY |
和日常基线明显不同的 SQL |
| 日志备份 | br log status |
任务状态、Global Checkpoint 的推进情况 |
| 告警 | Dashboard、Alertmanager | 新告警、重复告警及已经恢复的告警 |