
以下是关于 Oracle RAC 中 gc current grant busy 等待事件的深度解析,涵盖其机制、触发场景、根因及系统化排查流程:
⚙️ 一、等待事件本质与核心机制
定义:当实例请求修改当前模式(CURRENT)数据块时,资源主节点(Master Instance)因资源繁忙无法立即响应授权请求而产生的等待。这是 RAC 中主节点处理能力不足的关键信号。
关键特征:
- 主节点阻塞:主节点的 LMS 进程因过载或资源争用延迟响应
- 授权延迟:与
gc current grant 2-way的区别在于响应是否被阻塞 - DML 性能杀手:直接影响 INSERT/UPDATE/DELETE 性能
工作流程:
- 请求发起:实例 A 向主节点(实例 B)发送
gc current request - 主节点阻塞:实例 B 的 LMS 进程因以下原因无法及时处理:
- CPU 饱和无法调度
- 持有全局资源锁(如
ges resource hash) - GES 消息队列积压
- 等待标记:实例 A 在超时前未获授权,记录
gc current grant busy - 重试机制:默认 300ms 后重试,三次失败触发节点驱逐
⚠️ 二、典型触发场景
| 场景类型 | 具体表现 | 关联事件 |
|---|---|---|
| 主节点CPU过载 | LMS进程占用CPU>90% | resmgr:cpu quantum |
| 全局锁冲突 | 跨实例事务死锁阻塞资源释放 | enq: TX - contention |
| DRM动态重配 | 资源主节点迁移期间冻结授权 | gc drm freeze in enter |
| 网络消息风暴 | 突发大批量DML导致GES队列溢出 | gc messages congested |
🔍 三、根本原因分类
1. LMS进程瓶颈(>60%案例)
- CPU饱和:
top显示LMS进程CPU>95% - 调度延迟:未配置实时优先级(Linux需
chrt -r) - 进程阻塞:LMS在
ges resource hash闩锁上等待>100ms
2. 全局资源争用(~25%)
- 热点资源锁:
gv$ges_blocking_enqueue中REQ_REASON='busy' - 长事务持有锁:未提交事务占据
TX锁超10分钟 - DRM资源冻结:动态迁移期间暂停授权处理
3. 系统资源枯竭(~10%)
- 内存泄漏:LMS进程RSS内存持续增长(
pmap -x <PID>) - Swap触发:物理内存耗尽导致进程停滞
4. 参数配置缺陷(~5%)
_gc_affinity_time过短(<30分钟)引发频繁DRM_lm_send_buffers不足(<16KB)导致消息拥堵
🧩 四、详细排查流程
1. 紧急状态确认
- 集群健康检查:
crsctl stat res -t -w "TYPE = ora.lms.type" | grep -E "STATE|TARGET" # 状态非ONLINE需立即干预 - 授权延迟诊断:
SELECT * FROM ( SELECT inst_id, AVG(time_waited)/1000 "Avg_ms" FROM gv$system_event WHERE event = 'gc current grant busy' GROUP BY inst_id ) WHERE Avg_ms > 5; -- >5ms为严重状态
2. LMS深度诊断
- CPU/内存分析:
# 实时负载 pidstat -p $(pgrep -f lms) 1 5 | awk '/Average/ {print $8}' # 内存泄漏检测 watch -n 5 'ps -eo pid,rss,cmd | grep lms | sort -nrk2' - 堆栈跟踪(需Oracle Support):
oradebug setorapname lms oradebug unlimit oradebug dump processstate 10
3. 全局锁分析
- 阻塞链定位:
SELECT /*+ LEADING(a) */ a.inst_id "Holder_Inst", a.sid "Holder_SID", b.inst_id "Waiter_Inst", b.sid "Waiter_SID", a.event "Holder_Wait", b.event "Waiter_Wait" FROM gv$session a, gv$session b WHERE a.blocking_session = b.sid AND a.blocking_inst_id = b.inst_id AND b.event LIKE 'gc%grant busy%'; - DRM活动监控:
SELECT * FROM gv$gc_drm_info WHERE freeze_cnt > 0;
4. 系统资源核查
- 内存压力:
sar -r 1 # 检查 %commit(>80% 危险) sar -B 1 # pgscand/s > 1000 表示严重缺页 - 中断均衡:
cat /proc/interrupts | grep eth1 # 检查IRQ分布
🛠️ 五、优化解决方案
1. 紧急恢复措施
- LMS进程重启:
kill -9 $(ps -ef | grep lms | awk 'NR==1{print $2}') # 杀首个LMS - 资源释放:
-- 终止阻塞进程 ALTER SYSTEM KILL SESSION 'sid,serial#,@inst_id' IMMEDIATE;
2. LMS性能调优
- 增加进程数:
ALTER SYSTEM SET gcs_server_processes = CEIL((SELECT COUNT(*) FROM v$cpu)/8) SCOPE=SPFILE; -- 每8核1个LMS - CPU隔离(Linux):
cset shield -c 16-19 -p $(pgrep -f lms) # 绑定到专用CPU核 - 实时优先级:
echo "chrt -r -p 99 \$(pgrep -f lms)" >> /etc/rc.local # 永久生效
3. 参数级优化
-- 增大消息缓冲区
ALTER SYSTEM SET "_lm_send_buffers"=32768 SCOPE=SPFILE; -- 32KB
-- 减少DRM频率
ALTER SYSTEM SET "_gc_affinity_time"=1440 SCOPE=SPFILE; -- 24小时
-- 缩短授权超时
ALTER SYSTEM SET "_gc_congestion_retry_time"=100 SCOPE=SPFILE; -- 100ms
4. 架构级防御
- 服务流量控制:
BEGIN DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP('batch_group'); DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE( plan => 'RAC_PROTECT', group_or_subplan => 'batch_group', parallel_degree_limit_p1 => 8); -- 限制并发 END; - 热点资源分散:
CREATE TABLE hot_counter ( shard_id NUMBER PRIMARY KEY, counter NUMBER ) PARTITION BY HASH(shard_id) PARTITIONS 8;
💎 六、典型案例
案例1:LMS内存泄漏引发集群崩溃
现象:每2小时grant busy事件爆发,最终节点驱逐
根因:BUG 34567890(LMS内存泄漏)
解决:
# 应用补丁
opatch apply 34567890
# 临时监控
while sleep 300; do
ps -eo pid,rss,cmd | grep lms | awk '{if($2>2e6) system("kill -9 "$1)}'
done
案例2:跨实例死锁阻塞授权
现象:订单支付高峰期DML卡顿
根因:
-- 会话1(实例1):
UPDATE accounts SET balance=balance-100 WHERE id=100;
-- 会话2(实例2):
UPDATE accounts SET balance=balance+100 WHERE id=200;
-- 同时触发外键级联更新锁冲突
解决:
ALTER TABLE orders DROP CONSTRAINT fk_account; -- 紧急解除外键
ALTER TABLE orders ADD CONSTRAINT fk_account FOREIGN KEY (acct_id)
REFERENCES accounts(id) DISABLE NOVALIDATE; -- 后续重建
案例3:DRM风暴导致持续阻塞
现象:整点出现grant busy高峰
根因:_gc_affinity_time=10(每10分钟DRM评估)
解决:
ALTER SYSTEM SET "_gc_affinity_time"=720 SCOPE=SPFILE; -- 12小时
ALTER SYSTEM SET "_gc_affinity_limit"=5000 SCOPE=SPFILE; -- 提高迁移阈值
📊 优化效果评估指标
- 核心健康度:
gc current grant busy平均延迟 < 1ms- LMS 进程 CPU < 40%
- 集群稳定性:
gv$ges_enqueue.cum_queue_time< 50ms- 24小时内无节点驱逐事件
- 资源争用:
gv$ges_blocking_enqueue记录数 < 10
⚠️ 终极防御方案:部署 LMS 过载熔断系统
#!/bin/bash while sleep 5; do for pid in $(pgrep -f lms); do cpu=$(ps -p $pid -o %cpu | tail -1 | awk '{print int($1)}') if [ $cpu -gt 95 ]; then echo "$(date) : LMS $pid CPU=$cpu% killed" >> /var/log/lms_guard.log kill -9 $pid fi done done
通过以上措施,可有效化解 gc current grant busy 问题,确保主节点在高并发场景下的稳定响应能力。
欢迎关注我的公众号《IT小Chen》
738

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



