事务吞吐量卡在RAC高并发下,90%不是SQL本身慢,而是GC协调开销压垮私网和LMS进程;根本原因在于默认_gc_policy_time=300秒过长导致热点块滞留,引发跨节点频繁请求,需结合访问倾斜程度合理设为120秒或保持默认,而非盲目调小。
直接结论:事务吞吐量卡在 rac 高并发下,90% 不是 sql 本身慢,而是 gc 协调开销压垮了私网和 lms 进程。 调大并行度、加内存、换更快磁盘,都救不了——除非先稳住缓存融合链路。
为什么高并发下 gc current block 2-way 等待飙升
这是 RAC 最典型的“假瓶颈”:看起来是 SQL 执行慢,实际是节点 A 想读一个块,发现它在节点 B 的 buffer cache 里,于是发起跨节点请求;B 收到后要加锁、构造一致性读、发包——整个过程在高并发下被放大成网络+CPU+锁三重争抢。
- 常见错误现象:
gc current block 2-way和gc cr block busy在 AWR Top 5 中持续占位,V$SYSSTAT里global cache gets每秒超 5000,但physical reads很低 - 根本原因不是数据分布不均,而是默认的
_gc_policy_time=300(5 分钟)太长,导致热点块长期滞留某节点,其他节点只能反复远程拉取 - 盲目调小该参数到 60 或 30 秒,反而触发更频繁的锁迁移和缓存失效,
gc buffer busy acquire反而上升 - 真正有效的阈值是:若业务有明确访问倾斜(如按租户 ID 分区),可设为
120;若无明显倾斜,保持默认 300 更稳
如何让 LMS 进程真正跑在实时调度模式
LMS 不在 SCHED_FIFO 模式,等于让 GC 协调器用普通线程跑实时任务——延迟一上来,重试和堆积就停不下来。
- 检查命令:
ps -eo pid,comm,cls,pri,rtprio,%cpu --sort=-%cpu | grep LMS,若cls列是ts(即SCHED_OTHER),说明没生效 - 必须同时满足三个条件:
_highest_priority_processes参数含LMS*;/etc/security/limits.conf含oracle soft rtprio 99和hard rtprio 99;重启实例后执行kill -SIGUSR2 <LMS_PID>(19c 必须手动触发) - alert log 中必须看到
LMS1 started with pid=..., os id=... at elevated (RT) priority才算成功 - 别乱加
_lm_lms:2 节点集群设为 4 已足够,硬加到 8 会抬高 %sy(系统态 CPU),上下文切换反成瓶颈
怎样用 parallel_instance_group 控制并行不跨节点抢资源
很多人以为 PARALLEL_FORCE_LOCAL=TRUE 是“限制并行只在本地”,其实它是废弃参数,且效果是全局退化——所有并行从属进程全挤在 coordinator 节点上,把 CPU Ready 队列打满。
- 真正可控的方式是组合使用:
parallel_instance_group+ 各节点的instance_groups - 例如只想让某报表 SQL 在节点
rac1上完成全部并行:ALTER SESSION SET parallel_instance_group = 'rac1';,同时确保rac1实例的instance_groups包含'rac1'(通过ALTER SYSTEM SET instance_groups='rac1' SCOPE=SPFILE SID='rac1';设置) - 如果
parallel_instance_group设为一个任何节点都没配置的值(如'xyz'),SQL 直接报ORA-12850: Could not allocate parallel slaves - 注意:
PARALLEL_FORCE_LOCAL在 12c+ 已废弃,RAC 下行为不可靠,仅作调试基线用,生产环境禁用
最易被忽略的一点:GC 效率不取决于你调了多少参数,而取决于 SQL 是否带分区键、表是否做了 BUFFER_POOL KEEP、连接串是否误配了 SERVER=DEDICATED 却没开 CLUSTER_DATABASE=TRUE。这些比改隐含参数见效快得多,也更安全。


















