必须直查gv$system_event区分acquire与release:acquire高说明本地会话等待远程释放块,release高表明远程提交后释放消息卡在LMD或私网;两者均高且release占比超30%时优先排查LMD和GES,而非优化SQL。

别直接信AWR里“gc buffer busy”这行字——它在19c中早已失效,混着acquire和release两类根本不同的等待,一查就偏。
怎么确认是 acquire 还是 release
必须绕过AWR的笼统统计,直查实时视图:
- 跑
SELECT inst_id, event, total_waits, time_waited_micro FROM gv$system_event WHERE event IN ('gc buffer busy acquire', 'gc buffer busy release'),看哪个占主导 - 若
gc buffer busy acquire高,说明本地会话在等远程释放块;若gc buffer busy release高,说明远程已提交但释放消息卡在LMD或私网 - 两者同时高且
gc buffer busy release占比超30%,优先查LMD和GES,不是改SQL
为什么不能只看Segments by Global Cache Buffer Busy
这个AWR节标题有误导性:它只统计“被跨实例请求次数”,不反映争用强度,更不区分acquire/release。一张大表被扫100次,和一个4KB索引叶块被2000次acquire争抢,都算“高”,但根因天差地别。
- 真正要盯的是ASH下钻:
SELECT sql_id, object_name, current_obj#, COUNT(*) FROM v$active_session_history WHERE event = 'gc buffer busy acquire' GROUP BY sql_id, object_name, current_obj# ORDER BY COUNT(*) DESC - 如果反复出现
SEQ_LOG_ID_IDX或SYS_IOT_TOP_12345这类小对象,基本就是热点块 - 注意
current_obj#是数据字典对象号,需联查dba_objects确认真实段名
查到热点块后,下一步该做什么
定位只是开始,关键在判断争用类型和可落地动作:
- 如果是INSERT/UPDATE引发的acquire,检查键值分布:主键递增+单实例写入,极易打满一个索引叶块;换成
REVERSE索引或PARTITION BY HASH(id)能立竿见影 - 如果是全表扫描类SQL触发,先加谓词过滤,别一上来就分区;小配置表可考虑
NOLOGGING + APPEND批量加载避开单块路径 - 别跳过基础设施验证:用
ping -M do -s 8000 -c 10测8KB包延迟,avg > 1.5ms 就得调MTU或QoS;查ps -eo pid,pcpu,comm --sort=-pcpu | grep lms,单个lms进程CPU > 50% 表示GCS负载不均
最常被跳过的一步:查 gv$ges_enqueue.cum_queue_time 求和。一旦超500ms,说明GES层已压垮,此时调索引、分表、改SQL全无效,必须先解决LMD过载或私网丢包。











