
以下是关于 Oracle RAC 中 gc current grant 2-way 等待事件的深度解析,涵盖其机制、触发场景、根因及系统化排查流程:
⚙️ 一、等待事件本质与核心机制
定义:当实例需要修改当前模式(CURRENT)数据块,但该块未被任何实例缓存时,资源主节点(Master Instance)授权请求实例直接从磁盘读取数据块。这是 RAC 中 DML 操作的"快速路径"。
关键特征:
- 磁盘授权:主节点授权磁盘读取(而非块传输)
- 2-way 交互:仅涉及请求方和主节点两次通信
- 物理 I/O 前置:必然触发
db file sequential/scattered read
工作流程:
- 本地检查:实例 A 需要修改块 X,本地无缓存
- 主节点请求:向该块的主节点(如实例 B)发送
gc current request - 主节点响应:
- 检查 GRD 确认无实例缓存该块
- 发送
grant信号(非数据块)授权磁盘读取
- 磁盘读取:实例 A 从数据文件读取块并修改
- 等待结束:完成物理 I/O 后继续操作
📌 关键点:与
gc cr grant 2-way的区别:
current grant:用于 DML 修改cr grant:用于 查询一致性读
⚠️ 二、典型触发场景
| 场景类型 | 具体表现 | 关联事件 |
|---|---|---|
| 冷数据修改 | 历史分区首次更新或缓存被清空 | db file sequential read |
| 批量数据加载 | INSERT INTO SELECT 操作非缓存表 | direct path write |
| 索引维护操作 | 重建非缓存索引的分支块 | gc current block busy |
| DRM 主节点切换 | 动态资源迁移后首次访问 | gc drm freeze in enter |
🔍 三、根本原因分类
1. 对象未缓存(>60% 案例)
- 冷数据访问:历史数据首次修改
- 缓存过小:
DB_CACHE_SIZE不足导致块被挤出 - 全表扫描更新:
UPDATE table SET col=val
2. 主节点瓶颈(~25%)
- LMS 进程过载:主节点 CPU 饱和延迟授权响应
- GCS 消息积压:
gv$ges_enqueue中cum_queue_time > 100ms
3. 物理 I/O 问题(~10%)
- 慢磁盘:ASM 磁盘组响应时间 > 20ms
- HCC 压缩表:查询压缩块需额外解压时间
4. 参数配置不当(~5%)
_gc_affinity_time过短导致主节点频繁切换_gc_policy_minimum阈值过高禁用本地缓存
🧩 四、详细排查流程
1. 症状定位
- AWR 报告分析:
SELECT event, total_waits, time_waited_micro/1000 "Avg Latency(ms)" FROM dba_hist_system_event WHERE event = 'gc current grant 2-way' ORDER BY snap_id DESC FETCH FIRST 1 ROW ONLY; -- 严重阈值:>5ms (正常应<1ms) - ASH 热点对象定位:
SELECT sql_id, object_id, current_file#, current_block#, COUNT(*) FROM gv$active_session_history WHERE event = 'gc current grant 2-way' GROUP BY sql_id, object_id, current_file#, current_block# ORDER BY COUNT(*) DESC FETCH FIRST 5 ROWS ONLY;
2. 缓存状态诊断
- 对象缓存分布:
SELECT inst_id, COUNT(*) cached_blocks FROM gv$bh WHERE objd = (SELECT data_object_id FROM dba_objects WHERE object_name = '&TABLE_NAME') GROUP BY inst_id; -- 全为0表示未缓存 - 主节点位置:
SELECT kjbmaster, COUNT(*) FROM x$kjbm WHERE kjbmhdl = (SELECT file_id || '.' || block_id FROM dba_extents WHERE segment_name = '&TABLE_NAME' AND rownum = 1); -- 需替换为实际块地址
3. 物理 I/O 分析
- 磁盘响应时间:
SELECT inst_id, name, time/1000 "Avg Time(ms)" FROM gv$sysstat WHERE name LIKE '%disk read%'; -- 关注 'physical read total time' > 20ms 异常 - ASM 性能:
SELECT group_number, name, read_time, write_time FROM v$asm_disk_iostat; -- >15ms 需关注
4. LMS 与主节点检查
- 主节点负载:
SELECT inst_id, program, event, state FROM gv$session WHERE program LIKE '%LMS%' AND inst_id = (SELECT kjbmaster FROM x$kjbm ...); -- 主节点实例 - 消息队列深度:
SELECT inst_id, SUM(cum_queue_time) queue_ms FROM gv$ges_enqueue WHERE inst_id = &master_inst -- 主节点实例 GROUP BY inst_id;
🛠️ 五、优化解决方案
1. 缓存预热策略
- 主动加载热表:
BEGIN DBMS_WORKLOAD_REPOSITORY.LOAD_TABLE( owner => 'SCHEMA', table_name => 'HOT_TABLE', force_read => TRUE); -- 强制全表扫描加载 END; - KEEP 池锁定:
ALTER TABLE orders STORAGE (BUFFER_POOL KEEP); -- 防止被挤出
2. 主节点优化
- LMS 优先级提升(Linux):
chrt -r -p 99 $(pgrep -f lms) # 实时优先级 - DRM 冻结减少:
ALTER SYSTEM SET "_gc_affinity_time"=720 SCOPE=SPFILE; -- 12小时策略
3. 物理 I/O 加速
- ASM 条带优化:
ALTER DISKGROUP DATA ADD TEMPLATE hot_template ATTRIBUTES (FINE); -- 细粒度条带 ALTER TABLE orders MOVE PARTITION p1 STORAGE (CELL_FLASH_CACHE KEEP) -- Exadata 闪存加速 TABLESPACE data HOT TEMPLATE; -- 使用热模板 - HCC 解压优化:
ALTER TABLE sales COMPRESS FOR QUERY; -- 降低解压开销
4. 架构级改造
- 分区亲和性:
ALTER TABLE orders MODIFY PARTITION p_2023 AFFINITY 'rac1' SERVICE 'svc_rac1'; -- 绑定到实例 - 本地化索引:
CREATE INDEX idx_local ON orders(order_date) LOCAL;
💎 六、典型案例
案例1:历史数据迁移引发授权风暴
现象:每月初跑批作业 gc current grant 2-way 等待占比 40%
根因:更新 12 个月前分区,数据已被挤出缓存
解决:
-- 预加载分区
SELECT /*+ FULL(p) */ *
FROM orders PARTITION (p_202301); -- 提前全扫加载
-- 修改存储策略
ALTER TABLE orders MODIFY PARTITION p_202301
STORAGE (BUFFER_POOL RECYCLE); -- 使用独立缓存池
案例2:主节点切换导致延迟飙升
现象:DRM 活动期间授权延迟从 1ms 升至 50ms
根因:_gc_affinity_time=10(每 10 分钟评估迁移)
解决:
ALTER SYSTEM SET "_gc_affinity_time"=1440 SCOPE=SPFILE; -- 24小时
案例3:KEEP 池不足引发反复授权
现象:核心配置表更新频繁触发授权
分析:
SELECT segment_name, blocks
FROM dba_segments
WHERE buffer_pool = 'KEEP'
AND blocks > (SELECT bytes/block_size
FROM v$buffer_pool
WHERE name='KEEP'); -- 对象大于KEEP池容量
解决:
-- 扩容KEEP池
ALTER SYSTEM SET db_keep_cache_size=1G SCOPE=BOTH;
-- 对象压缩
ALTER TABLE config_table MOVE COMPRESS; -- 减少块数量
📊 优化效果评估指标
- 核心指标:
gc current grant 2-way平均延迟 < 1ms- 事件总等待时间下降 > 70%
- 缓存效率:
Buffer Cache Hit Ratio> 99%gv$bh中热表缓存率 100%
- I/O 健康度:
Avg disk read time< 10ms- ASM 磁盘读延迟 < 5ms
⚠️ 终极方案:对无法缓存的超大表启用 In-Memory 列存储:
ALTER TABLE historical_data INMEMORY PRIORITY HIGH MEMCOMPRESS FOR CAPACITY LOW; -- 列式缓存 -- 查询时强制列扫描 SELECT /*+ INMEMORY */ ... FROM historical_data;
通过以上措施,可显著减少 gc current grant 2-way 等待,将 DML 操作从磁盘访问路径优化为内存优先路径,提升 RAC 集群写性能。
欢迎关注我的公众号《IT小Chen》
1413

被折叠的 条评论
为什么被折叠?



