gc cr grant 2-way等待过长本质是缓存缺失引发的物理I/O瓶颈,该事件仅标记授权完成,耗时实际来自后续db file scattered/sequential read;根因需优先排查对象未缓存、Master节点错配及DB_CACHE_SIZE可用不足。

gc cr grant 2-way 等待时间过长,本质不是网络或授权慢,而是实例被迫频繁从磁盘读冷数据——它暴露的是缓存缺失 + 物理I/O瓶颈的组合问题。
为什么这个等待本身不“慢”,但耗时却很长
这个等待事件只是“授权完成”的标记,gc cr grant 2-way本身几乎不耗时(通常 db file scattered read 或 db file sequential read。AWR里看到的高“Avg Latency(ms)”其实是把后续物理读的时间也统计进来了(Oracle 12c默认将grant后I/O的等待合并计入该事件)。所以不能只盯着这个事件调优LMS或网络。
- 查证方法:在ASH中过滤
event = 'gc cr grant 2-way',看wait_time是否普遍 > 10ms;若绝大多数为 0,则说明真实延迟来自磁盘读 - 关键指标:对比
buffer cache hit ratio—— 若低于 97%,冷数据访问就是主因 - 典型误导:盲目增加
GCS_SERVER_PROCESSES对该等待无改善,因为LMS没被阻塞,只是安静地发了授权信号
最常被忽略的三个根因位置
排查必须按优先级顺序下钻,否则容易在错误方向上浪费时间:
- 对象未缓存且访问模式固定:比如历史分区表首次被查询、ETL加载后立即做报表扫描。这类对象从未进过Buffer Cache,每次都是“空缓存触发grant + 全盘扫”
-
Master节点与访问节点长期错配:某张大表主要在实例1上被查询,但它的资源主节点是实例2(
gv$resource_limit中master列可查)。所有CR请求都得跨私网找实例2要授权,哪怕实例1本地有足够内存 -
DB_CACHE_SIZE 实际可用不足:设置了
DB_CACHE_SIZE=8G,但被大量小对象碎片化占用,或被KEEP/RECYCLE池挤占,导致热数据反复被踢出。用SELECT pool, name, bytes/1024/1024 mb FROM v$sgastat WHERE name LIKE '%free memory%'查剩余空间
哪些操作看似相关,实则无效或危险
很多DBA第一反应是调参数或加资源,但以下动作在 gc cr grant 2-way 场景下要么无效,要么引发新问题:
- 启用 DRM(
_gc_affinity_time调小):对冷数据无意义,反而可能因频繁主节点切换增加gc drm freeze in enter等待 - 强行绑定SQL到单实例(如改SCAN IP):仅缓解现象,不解决缓存缺失本质;且破坏RAC负载均衡,可能压垮单节点
- 调大
_lm_send_buffers:该参数影响的是 block 传输类事件(如gc cr block 2-way),和 grant 2-way 无关 - 增加私网带宽:grant 2-way 只传几个字节的授权信号,千兆内网已绰绰有余;真瓶颈在存储层
真正需要盯住的,是那个紧随其后的 db file scattered read 的平均响应时间,以及对应 SQL 的 physical reads 是否合理——这才是问题的落点。缓存没起来,调什么都是隔靴搔痒。


















