awr报告仅能揭示enq: tx - row lock contention存在及耗时,无法定位具体阻塞链;必须结合dba_hist_active_sess_history(查blocking_session、current_obj#等)和v$lock等动态视图交叉验证,才能确定谁持锁、谁等待、锁在哪一行。
awr本身不直接暴露“哪个会话锁了谁”,它只告诉你有争用、在哪类资源上、耗时多少;真要定位具体锁定关系,必须跳出awr报告,结合dba_hist_active_sess_history和v$lock等动态视图交叉验证。
查AWR里“enq: TX - row lock contention”只算起步,不是终点
AWR报告中“Top 5 Timed Foreground Events”出现enq: TX - row lock contention,只说明存在行级锁等待,但无法区分是应用逻辑缺陷、SQL未提交、还是索引缺失导致的锁范围扩大。它也不告诉你阻塞链:谁在持锁、谁在等、锁在哪一行。
- 先确认该事件是否进入Top 5且
Time Waited占比超过10%,否则可能是偶发抖动,不值得深挖 - 接着看“Segments by Row Lock Waits”子节,定位到具体表(如
WAREHOUSES),再结合“SQL Statistics”找Buffer Gets per Exec异常高的UPDATE/DELETE语句 - 注意:如果某条SQL的
%CPU + %IO总和远低于100%(比如只有2.15%),而它的Elapsed Time又接近该等待事件总耗时,基本可锁定它是主因
用DBA_HIST_ACTIVE_SESS_HISTORY反查阻塞源头节点
AWR快照是聚合数据,丢失会话粒度细节;DBA_HIST_ACTIVE_SESS_HISTORY保留每秒采样点,能还原阻塞路径。关键字段是blocking_session和blocking_instance,它们指向持锁方所在实例和会话ID。
- 执行查询时必须限定
snap_id范围,避开空闲时段,聚焦业务高峰期连续3–5个快照 -
CURRENT_OBJ#、CURRENT_FILE#、CURRENT_BLOCK#、CURRENT_ROW#四字段可拼出被锁行的ROWID,直接定位业务记录 - 别用
V$SESSION查当前阻塞——问题发生时可能早已结束,必须依赖历史ASH数据
区分gc cr block busy高是负载倾斜,还是GC网络真慢
gc cr block busy在RAC中常被误读为“网络卡”。实际它反映的是节点间一致性读(CR)构建延迟,根源往往是应用连接没均衡或SQL路由失效,而非物理链路问题。
- 运行
SELECT inst_id, service_name, COUNT(*) FROM gv$session GROUP BY inst_id, service_name,检查连接是否全挤在单节点 - 查
DBA_SERVICES中对应service_name的LOAD_BALANCE和FAILOVER_METHOD是否都为YES - 对比两节点的
gc cr blocks received和logical reads:若节点1接收CR块是节点2的3倍,但逻辑读只高20%,说明节点2的查询被错误路由到节点1执行
latch free排名高?先看Latch Activity表,别急着调参
latch free是泛型等待事件,本身不具诊断价值。真正要盯的是具体子事件,比如latch: cache buffers chains或latch: library cache,以及DBA_HIST_LATCH里的统计指标。
- 打开AWR报告,直奔“Latch Activity”表格,重点看
% Get Miss(>5%才需干预)和Avg Slps/Miss(>2表示已休眠重试,争用较重) -
cache buffers chains的GETS天然很高,但% Get Miss只要低于0.1%就属正常;跳到0.5%以上,得结合SQL的Buffer Gets per Exec排查执行计划恶化 - 若
library cache争用明显,且parse count (hard) / parse count (total)> 10%,大概率是绑定变量缺失,不是共享池大小问题
最易被忽略的一点:AWR快照默认每小时一次,对持续时间短于10分钟的问题(比如瞬时锁升级、短事务阻塞)可能完全漏掉。遇到这类问题,必须搭配实时gv$session和gv$lock抓取,而不是死守AWR报告。











