ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

测试人员排查“跑批慢“的 10 分钟 SOP

测试人员排查“跑批慢“的 10 分钟 SOP 适用Oracle 数据库跑批/压测变慢、响应超时、CPU 飙高目标10 分钟内定位是 SQL 慢 / 是锁等待 / 是 IO 瓶颈 / 是资源不够第 0 步先确认慢是什么感觉30 秒在排查前先搞清楚慢的表现形式不同表现指向不同方向现象大概率方向批作业卡住不动超时报错锁/死锁 或 SQL 卡在等待批在跑但比平时慢 2~3 倍资源争用 或 SQL 执行计划变差整个数据库连查询都卡服务器/IO 问题 或 有人跑大查询⚠️如果批已经挂在那里 5 分钟没响应马上走第 3 步查锁别犹豫。第 1 步看数据库里谁在跑1 分钟目标找到跑批里正在执行的会话和 SQL-- 1. 活跃会话谁在跑、跑多久 SELECT s.sid, s.serial#, s.username, s.status, s.last_call_et AS secs_running, -- 已运行秒数 s.event, -- 当前等待事件 q.sql_id, q.sql_fulltext AS sql_text FROM v$session s JOIN v$sql q ON s.sql_id q.sql_id WHERE s.status ACTIVE AND s.username IS NOT NULL ORDER BY s.last_call_et DESC;看什么有没有不是本次跑批的会话在瞎跑很多人忘关的大查询secs_running已经很大但还在ACTIVE→ 大概率是卡住了sql_text指向哪张表 → 大概率的瓶颈 SQL 如果连这条查询都卡住 5 秒以上响应直接跳到第 4 步数据库整体挂了。第 2 步看这条 SQL 为什么慢2 分钟目标判断是缺索引、全表扫、还是数据量大-- 2. 看 SQL 的读取情况 SELECT sql_id, sql_text, executions, elapsed_time / 1000000 AS elapsed_sec, -- 总耗时秒 cpu_time / 1000000 AS cpu_sec, -- 总CPU秒 buffer_gets, -- 逻辑读 disk_reads -- 物理读 FROM v$sql WHERE sql_id sql_id; -- 上一步拿到的怎么判断指标值说明disk_reads/buffer_getsdisk 远大于 buffer大量物理读 → 缺索引或没走索引elapsed_sec大但 cpu_sec 小几乎不耗 CPU卡在 IO 等待或锁等待buffer_gets巨大几百万以上大表没走索引全表扫看执行计划-- 看是否走索引 SELECT * FROM table(dbms_xplan.display_cursor(sql_id, null, ALL));看到TABLE ACCESS FULL但表有索引 →索引失效函数索引、隐式转换、统计信息过期。看到SORT、HASH JOIN在大表上 → 数据量确实大要考虑分批。第 3 步查锁和阻塞1 分钟卡住必查目标确认有没有会话互相等待-- 3a. 当前锁对象 SELECT l.session_id AS sid, s.username, o.object_name, l.locked_mode, s.sql_id FROM v$locked_object l JOIN dba_objects o ON l.object_id o.object_id JOIN v$session s ON l.session_id s.sid ORDER BY l.session_id; -- 3b. 阻塞链谁堵谁 SELECT s1.sid || blocked by || s2.sid AS chain, s1.username, s2.username, s1.sql_id AS blocked_sql, s2.sql_id AS blocker_sql FROM v$lock l1 JOIN v$lock l2 ON l1.id1 l2.id1 AND l1.block 1 JOIN v$session s1 ON l1.sid s1.sid JOIN v$session s2 ON l2.sid s2.sid;看到阻塞链立刻记录被堵的sid和 blocked SQL评估是批处理内部顺序问题还是并发造数没控制顺序测试环境直接ALTER SYSTEM KILL SESSION sid,serial#;杀掉然后重跑生产禁止这么做第 4 步看等什么等事件1 分钟目标卡在 IO 还是卡在逻辑-- 4. 等待事件排名 SELECT event, total_waits, time_waited / 100 AS sec_waited -- 总等待秒数 FROM v$system_event WHERE wait_class ! Idle ORDER BY time_waited DESC FETCH FIRST 10 ROWS ONLY;快速对照表高频等待事件含义排查方向db file sequential read单块读索引/回表SQL 是否走错索引存储响应慢db file scattered read多块读全表扫大表没走索引latch: cache buffers chains热块争用并发读同一块并发高考虑哈希分区/缓存enq: TX - row lock contention行锁等待第 3 步看阻塞链log file sync写 redo 等待写入量大或磁盘写慢DB CPU纯 CPU 跑SQL 确实重需改写/加索引第 5 步顺手看一眼服务器1 分钟目标排除机器本身的问题# CPU top -bn1 | head -5 # IO重点看 %util 和 await iostat -x 1 3 # 内存/Swap free -m判断%util接近 100% → 存储瓶颈所有 SQL 都慢waIO wait高 → 同上Swap被用 → 内存不够系统开始换页第 6 步出结论 记录30 秒把上面 5 步的信息整理成一句话结论【结论模板】 跑批慢在 SQL/作业名原因是 全表扫/锁等待/IO瓶颈/资源不足 证据disk_readsxxx、等待事件xxx、%utilxxx%。 建议加索引 / 调作业顺序 / 错峰执行 / 加内存。示例跑批慢在JOB_POSTING原因是ACCT_BAL的更新没走主键索引全表扫 2000 万行证据该 SQLdisk_reads5,000,000等待事件db file scattered read排名第一。建议对该 UPDATE 的 WHERE 条件字段建索引或分批提交。附一张速查卡贴桌面卡住/超时 ──→ 第3步(锁) ──┐ ├─→ 第1步 谁在跑 有响应但慢 ──→ 第5步(OS) ──┤ ├─→ 第2步 SQL执行计划 整体挂了 ──→ 第5步(OS) ──┘ └─→ 第4步 等待事件定方向附测试环境常备小脚本-- 一键抓最可疑的 SQL贴到 SQL*Plus 直接跑 SELECT * FROM ( SELECT sql_id, sql_fulltext, executions, elapsed_time/1e6 AS el_sec, cpu_time/1e6 AS cpu_sec, buffer_gets, disk_reads FROM v$sql WHERE executions 0 ORDER BY elapsed_time DESC ) WHERE ROWNUM 10;一句话总结v$session 看谁在跑 → v$sql 看哪句慢 → v$system_event 看卡在哪 → OS 看机器扛不扛得住这四步顺序就是这份 SOP 的骨架反复用就熟了。
返回列表