gc cr block busy等待的是本地缓冲区空间分配、cbc latch争用或gcs协调延迟,而非网络传输;高发于高频小结果集、跨节点读一致性的sql,如未绑定变量循环查询、全局配置表高并发读、非分区键range查询等。

gc cr block busy到底在等什么
它不是等网络传输,而是等接收端(本实例)把远程发来的CR块塞进Buffer Cache。关键阻塞点在本地:缓冲区空间分配、CBC latch争用、或GCS协调延迟。现象上会看到gc cr block busy等待时间集中在1ms–4ms桶,而非16ms以上——这说明问题不在私网延迟,而在本机资源调度。
哪些SQL和对象最容易触发这个等待
高频、小结果集、跨节点读一致性版本的查询最危险。典型场景包括:
- 未绑定变量的循环查询,如
SELECT * FROM t WHERE id = :1反复执行,每次可能走不同执行计划,部分触发全表扫描,大量构造CR块 - 全局配置表被高并发读取,例如
SELECT * FROM sys_parameter WHERE param_class IN (:1, :2)每秒70+次,热点块(如file# 93, block# 65696)在多个实例间反复传输 - RANGE分区表按非分区键查询(如按
status查,但表按created_date分区),导致扫描分散到多个实例,本地无缓存,CR请求密集 - 索引根块或分支块被多实例高频扫描,如日期字段索引范围查询,CR块构造压力集中
排查时别跳过这几个关键指标
光看gv$system_event里总等待时间没用,必须交叉验证:
- 查
gv$active_session_history定位具体sql_id和p1/p2(文件号/块号),再用DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE反解主节点位置 - 看
gv$bh里同一块是否在多个实例缓存(inst_id不同但file#/block#相同),确认是否存在冗余缓存 - 检查
gv$sysstat中gc cr blocks received与gc current blocks served比值,若远高于1,说明CR构造开销远超current块服务开销,大概率是SQL未走索引或绑定变量失效 - 观察
gv$session_wait中blocking_session是否为空——gc cr block busy通常是本机资源瓶颈,而非被其他会话直接阻塞
隐式参数能压住症状,但压不住根因
_gc_affinity_time = 10和_gc_affinity_percent = 50确实能让块多留在本地,降低CR跨节点频率,但前提是数据访问模式本身稳定。如果SQL本身就在疯狂全表扫描,或者序列号表被高频争抢,这些参数只会延缓恶化,不会阻止gc cr block busy持续上涨。真正要动的是SQL写法、绑定变量使用、索引覆盖和分区裁剪逻辑——否则调参只是给定时炸弹加个消音器。











