gc current block busy等待事件90%以上源于本地热点块争用或LMS处理延迟,非网络问题;需通过p1/p2定位固定块、结合blocking_session和sql_id确认是否多会话更新同一行,再查gv$ges_enqueue.cum_queue_time及LMS进程状态。
直接看 gc current block busy 的等待时间占比和会话堆栈,90% 以上是本地热点块争用或 lms 处理延迟,不是网络问题——先别急着调私网参数。
查清是不是真由跨实例块传输引起
这个等待事件常被误判为“网络慢”,其实多数情况根本没走到网络层。关键看 p1/p2 是否指向同一对象的固定块(比如索引叶块、小表头块),再结合 gv$session 中的 blocking_session 和 sql_id 判断是否多个会话在更新同一行或相邻行。
- 执行
SELECT inst_id, sid, sql_id, p1, p2, blocking_session FROM gv$session WHERE event = 'gc current block busy',若blocking_session非空且集中在某几个sid,说明是持有方事务未提交或修改过长 - 若
p1/p2在不同会话中反复出现相同值(如 file# 4, block# 180),用DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE和DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK定位对象,大概率是索引分裂或计数器表热点 - 若
gv$ges_enqueue.cum_queue_time很低(
验证 LMS 进程是否真正过载
gc current block busy 和 gc current block congested 容易混淆:前者是持有方“能处理但慢”,后者是 LMS “队列已满根本处理不了”。必须区分。
- 运行
ps -eo pid,pcpu,pmem,cmd | grep lms | sort -k2 -nr,确认单个lms进程 CPU 是否持续 >90%;若只是偶发尖峰,优先查 SQL 而非扩容 LMS - 检查
crsctl stat res -t -w "TYPE = ora.lms.type",状态必须是ONLINE;若为OFFLINE或INTERMEDIATE,LMS 已异常退出,需查$ORACLE_HOME/log/<host>/lms*.log</host> -
_gc_affinity_time默认 30 分钟,若频繁 DRM(主节点迁移),可适当调大(如 180),但不要设为 0——否则失去缓存亲和性,反而加剧gc current block busy
避开常见优化陷阱
很多 DBA 一上来就改 _gc_policy_minimum 或调大 GCS_SERVER_PROCESSES,结果无效甚至恶化。根本原因往往在应用或对象设计。
- 高频单行更新(如库存扣减):别指望调参解决,必须拆分热点,例如用哈希分区计数器表,或改用应用层批量合并更新
- 单调递增主键索引:并发插入必然争用右most 叶块,加
PCTFREE 20+INITRANS 16只能缓解,根治是换 UUID/序列号+散列,或启用ASSM+COMPRESS FOR OLTP - 误信“加大 buffer cache 就能减少等待”:接收端 Buffer Cache 不足主要影响
gc cr block busy,对gc current block busy几乎无作用——它卡在持有方的 buffer pin 或 GES 授权环节
最易被忽略的是:gc current block busy 的 P3 值为 1 表示请求排他锁(XCUR),此时若持有方正在做物理写(DBWR 写脏块)、或正重建 CR 副本、或卡在某个内部闩锁(如 gcs resource hash),等待就会发生——这些都得靠 oradebug dump systemstate 266 结合堆栈才能定位,AWR 里看不到。


















