RAC全局锁争用90%以上源于数据分布与业务访问模式不匹配共享缓存架构,需优先检查v$ges_enqueue定位HW/TX锁阻塞链,控制段扩展节奏、合理分区、统一UNDO及私网配置。
ORA-600 [kjbmprlst:shadow] 或大量 gc buffer busy acquire 等待?先查锁类型和持有者
rac 中的全局锁争用,90% 以上不是应用层死锁,而是底层资源同步机制暴露了设计或负载问题。直接看 v$ges_enqueue 和 v$lock 混合视图比猜更有效。
-
v$ges_enqueue显示跨实例持有的全局队列(如TX、HW、US),重点关注REQUESTED和GRANT_LEVEL不一致的行 - 别只盯着
TX行锁——HW队列争用常被误判为“慢 SQL”,实际是并发 insert 触发高水位线推进冲突 - 用
select * from v$ges_blocking_enqueue快速定位阻塞链起点,它比gv$session的blocking_session更准,尤其对瞬时 GC 等待
INSERT 高并发下 HW 锁飙升?控制段扩展节奏比加 freelist 有用
Oracle 11gR2+ 默认启用 ASSM 后,HW 队列争用本质是多个实例同时申请新区(extent)或推进段高水位线(HWM)导致的跨节点协调开销。freelist 在 RAC 下几乎无效,反会放大争用。
- 优先用
ALTER TABLE ... STORAGE (INITIAL 8M NEXT 8M)避免频繁 extent 分配;小表可预分配 10–20 个 extent - 对日志表、流水表等纯追加场景,启用
NOLOGGING + APPEND并配合分区(按天/按月),把 HWM 推进限制在单个子分区内部 - 禁用
ALTER TABLE ... SHRINK SPACE—— 它会强制重置 HWM 并触发全表范围的全局锁同步,RAC 下极易卡住
TX 行锁跨实例传播慢?检查 undo 表空间和 _gc_read_mostly_locking 隐含参数
当事务在实例 A 修改某行、实例 B 同时查询该行(且未提交),B 实例需从 A 获取一致性读镜像,这依赖 undo 数据的远程访问路径。延迟或失败会表现为 gc cr block busy 或长时间 enq: TX - row lock contention。
- 确认所有实例使用同一共享
UNDO表空间(非 local undo),且undo_retention设置合理(至少 > 最长查询预计运行时间) - 若业务以只读为主、写入集中,可尝试开启
_gc_read_mostly_locking=TRUE(需 Oracle 12.1.0.2+),它让读多写少对象的块在本地缓存中降级为“只读锁定模式”,减少 TX 全局锁升级频率 - 避免在 RAC 中使用
SELECT FOR UPDATE NOWAIT做乐观锁兜底——NOWAIT 不会跳过全局锁协商,反而因快速失败重试加剧 GC 流量
AWR 报告里 gc current/cr block 2-way 时间异常高?先隔离网络与存储路径
GC 等待时间高,不等于数据库配置有问题。RAC 节点间通信走私网(通常是万兆 IB 或高速以太),一旦交换机丢包、MTU 不匹配或存储响应抖动,gc current block 2-way 就会暴涨,掩盖真实锁逻辑问题。
- 用
oifcfg getif确认私网接口绑定正确,再用ping -M do -s 8972 <peer_ip>测试 jumbo frame 是否通(Oracle 默认 GC 包大小约 9KB) - 查
GV$CLUSTER_INTERCONNECTS确认 interconnect 使用的是专用网卡,而非混用 public 网络 - 对比
DBA_HIST_SYSSTAT中gc cr blocks received和gc current blocks served的比率:若远高于 1.5,说明大量块在节点间反复传递,大概率是应用未合理分区数据(如所有实例都在更新同一张维度表主键区间)
HW 和 TX 锁背后真正难调的,从来不是参数,而是数据分布与业务访问模式是否天然适配 RAC 的共享缓存架构。一个没做 range 分区的订单表,在 4 节点 RAC 上跑 OLTP,再怎么调 _gc_policy_time 都是掩耳盗铃。










