查不到px等待需用gv$active_session_history,因rac中px进程跨实例分布;关键看time_waited而非sample_count,max(time_waited)>5s表明存在严重并行倾斜。
查不到px等待?先确认是否用了gv$视图
在rac环境下,v$active_session_history只记录本实例采样数据,而并行查询的协调进程(px coordinator)和从进程(px slave)可能跨节点分布。若只查单实例视图,px deq: execution message、parallel query dequeue wait这类关键等待根本不会出现。
必须用gv$active_session_history,且建议显式指定inst_id比对各节点行为:
SELECT inst_id, sql_id, event, COUNT(*) cnt FROM gv$active_session_history WHERE sample_time > SYSDATE - 1/1440 AND (event LIKE 'PX %' OR event LIKE 'parallel %') GROUP BY inst_id, sql_id, event ORDER BY cnt DESC;
- 若某
sql_id的等待集中在单个inst_id,说明并行工作未跨节点倾斜,问题更可能出在本地CPU或I/O - 若
event在多个inst_id上分散但time_waited差异极大(如节点2平均800ms,节点1仅5ms),就是典型并行工作分配不均 -
gv$查询结果延迟数秒属正常,别依赖它做毫秒级诊断;关键问题仍需连接各实例单独查v$active_session_history
识别并行倾斜:看time_waited而不是sample_count
ASH每秒采样一次,COUNT(*)高只代表“被采到的次数多”,不等于“真卡了那么久”。真正反映并行倾斜的是time_waited(单位:微秒)——它来自底层等待事件的精确计时,能暴露长尾延迟。
以下语句可定位最耗时的并行等待样本:
SELECT sql_id, event,
ROUND(AVG(time_waited)/1000, 2) avg_ms,
MAX(time_waited)/1000 max_ms
FROM v$active_session_history
WHERE event IN ('PX Deq: Execution Message',
'PX Deq: Table Q Normal',
'PX qref latch')
AND sample_time > SYSDATE - 1/24
GROUP BY sql_id, event
HAVING MAX(time_waited) > 5000000
ORDER BY max_ms DESC;
-
MAX(time_waited) > 5000000(即5秒)是硬信号:说明至少有一个PX slave卡住,拖慢整个并行组 - 若
AVG(time_waited)低但MAX极高,基本可断定是数据分布倾斜或分区裁剪失效,导致某个slave扫描远超其他slave - 别忽略
current_obj#:结合dba_objects查出该sql_id正在访问的表,再检查其分区键是否被函数包裹(如WHERE trunc(order_date) = ...)
gc cr block busy偏高?重点看跨节点逻辑读分布
gc cr block busy在某节点显著偏高,通常不是网络延迟问题,而是该节点承担了过多一致性读请求。根源常出在应用连接没打散或SQL执行计划不稳定。
应查DBA_HIST_SYSTEM_EVENT按INSTANCE_NUMBER分组分析等待事件分布,因其反映跨快照的持续负载模式:
SELECT instance_number, event,
SUM(time_waited_micro)/1000000 time_sec
FROM dba_hist_system_event
WHERE snap_id BETWEEN &start_snap AND &end_snap
AND event IN ('gc cr block busy',
'gc buffer busy acquire',
'enq: TX - row lock contention')
GROUP BY instance_number, event
ORDER BY time_sec DESC;
- 若
gc cr block busy在节点1远高于节点2,检查DBA_SERVICES中对应service_name的LOAD_BALANCE是否为YES -
gc cr block busy时间高但gc cr blocks received不高,说明不是传输慢,而是本地buffer cache没命中又等不到远程块——可能该节点shared_pool_size或db_cache_size设置偏低 - 看
gc cr blocks received与本节点logical reads的比值:>0.3就值得警惕,>0.5基本确认存在严重跨节点访问放大
row cache lock争用?按p1定位具体缓存类型
row cache lock等待高时,不能只调参数,得先查v$active_session_history按p1分组锁定争用缓存类型,再关联v$rowcache确认具体字典项。
快速定位争用缓存类型:
SELECT p1, COUNT(*) FROM v$active_session_history WHERE event = 'row cache lock' AND sample_time > SYSDATE - 1/24 GROUP BY p1 ORDER BY 2 DESC;
- 拿到最高频的
p1值(如8),再查名称:SELECT parameter FROM v$rowcache WHERE cache# = 8 - 常见值含义:
dc_sequences(序列)、dc_objects(对象定义)、dc_users(用户权限)、dc_tablespaces(表空间) - RAC下
dc_sequences争用90%是因为没设CACHE:每次NEXTVAL都要跨实例更新seq$表,引发全局行缓存同步开销 -
p2是当前持有锁的模式(KQRMX = 5为排他锁),p3是等待者请求的模式(KQRMS = 3为共享锁);若大量p2 = 5且p3 = 3,说明一个会话长期持X锁(如大事务中ALTER TABLE)
RAC中等待事件的跨实例特性决定了单实例视角必然失真;真正有效的诊断必须在gv$或历史视图层面做横向对比,且始终以time_waited而非采样次数为判断依据——这点最容易被忽略,也最常导致误判。











