一、引言
生产环境突然变慢,第一反应是什么?很多同学直接看慢日志,但在OceanBase里,GV$OB_SQL_AUDIT 才是真正的“监控录像机”——它记录了每一次SQL请求的完整生命周期。
二、核心字段排查矩阵
| 阶段 | 关键字段 | 正常值 | 异常排查方向 |
|---|---|---|---|
| 获取计划 | GET_PLAN_TIME |
<1ms | 如果值大且IS_HIT_PLAN=0 ,说明没命中plan cache ,走了硬解析 |
| 排队等待 | QUEUE_TIME |
<1ms | 值大说明租户工作线程不足 ,有锁竞争或并发太高 |
| 存储扫描 |
SSSTORE_READ_ROW_COUNT / MEMSTORE_READ_ROW_COUNT
|
与预期一致 | 扫描行数远大于预期,可能是Buffer表问题 或索引缺失 |
| 重试次数 | RETRY_CNT |
0 | 值大说明有锁冲突或切主 ,事务被回滚重试 |
| 实际执行 | EXECUTE_TIME |
与业务预期匹配 | 值大需分析执行计划是否合理 |
三、实战排查三步走
第一步:找到最近最慢的SQL
sql
SELECT SQL_ID, QUERY_SQL, ELAPSED_TIME/1000000 ELAPSED_SEC, GET_PLAN_TIME, QUEUE_TIME, EXECUTE_TIME, SSSTORE_READ_ROW_COUNT, MEMSTORE_READ_ROW_COUNT, RETRY_CNT FROM oceanbase.GV$OB_SQL_AUDIT WHERE REQUEST_TIME > DATE_SUB(NOW(), INTERVAL 10 MINUTE) ORDER BY ELAPSED_TIME DESC LIMIT 10;
第二步:定位具体慢在哪
- 如果
GET_PLAN_TIME占比高 → 检查plan cache命中率 - 如果
QUEUE_TIME占比高 → 查GV$OB_THREAD看工作线程是否跑满 - 如果
SSSTORE_READ_ROW_COUNT异常大 → 检查索引和分区裁剪 - 如果
RETRY_CNT> 0 → 查GV$OB_LOCKS看锁等待
第三步:拿到SQL_ID后深挖执行计划
sql
SELECT OPERATOR, OBJECT_NAME, ROWS, COST FROM TABLE(DBMS_XPLAN.DISPLAY_AUDIT(‘你的SQL_ID’));
四、进阶技巧:捕捉瞬时抖动的SQL
如果问题SQL是偶发性的,等你看的时候已经被淘汰出SQL_AUDIT了怎么办?
sql
– 临时关闭SQL_AUDIT,让抖动的SQL不被淘汰 ALTER SYSTEM SET ob_enable_sql_audit = 0; – 等抖动发生后,再打开 ALTER SYSTEM SET ob_enable_sql_audit = 1; – 这时SQL_AUDIT里只保留了关闭期间的请求,更容易捕获目标[citation:5]
五、案例复盘
某电商大促期间,核心接口RT从20ms飙到500ms。通过SQL_AUDIT排查发现:
-
QUEUE_TIME高达300ms → 租户工作线程不足 - 进一步查
GV$OB_THREAD,发现active_threads跑满 - 临时扩容租户
MAX_CPU,RT恢复