resource manager是oracle唯一能在rac全集群范围内实时干预资源分配的机制;profile的resource_limit、cpu_per_session等参数仅作用于单实例初始连接阶段,不跨节点同步,且idle_time对连接池维持的inactive会话完全不生效。

为什么不能只靠PROFILE限制RAC中的资源抢占
PROFILE里的RESOURCE_LIMIT、CPU_PER_SESSION等参数在RAC里基本失效。它只作用于单实例会话的初始连接阶段,不跨节点同步,也不感知其他实例上的资源竞争。更关键的是:RAC中大量INACTIVE会话长期占着processes和内存,但PROFILE的IDLE_TIME对它们完全不触发清理——因为Oracle只在该会话下次发SQL时才检查,而连接池维持的空闲连接根本不会发SQL。
必须用DBMS_RESOURCE_MANAGER创建consumer group directive
Resource Manager是唯一能在RAC全集群范围内实时干预资源分配的机制。它通过consumer group + plan directive组合生效,且策略对新会话立即起效,已有会话在下次激活时即受控。
- 不能把
MAX_IDLE_TIME设在OTHER_GROUPS上——它是只读组,该参数被忽略 - 必须为应用用户显式分配consumer group(如
APP_USERS),再为其单独创建directive -
MAX_IDLE_TIME单位是秒,例如1800表示30分钟无任何活动(包括解析、执行、fetch)即断开 - 需配合
CPU_P1、PARALLEL_DEGREE_LIMIT_P1等参数协同限流,避免某group耗尽CPU或并行槽位
示例(在任意节点执行):
BEGIN
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
plan => 'DAYTIME_PLAN',
group_or_subplan => 'APP_USERS',
comment => 'Kill idle after 30 min',
max_idle_time => 1800,
cpu_p1 => 70,
parallel_degree_limit_p1 => 4
);
END;
启用plan并绑定到实例需两步操作
创建完directive只是定义规则,还需激活plan并确保它在所有RAC节点上运行。
- 先执行
DBMS_RESOURCE_MANAGER.SWITCH_PLAN('DAYTIME_PLAN')启用plan - 再用
ALTER SYSTEM SET RESOURCE_MANAGER_PLAN='DAYTIME_PLAN' SCOPE=BOTH SID='*'让所有实例加载该plan - 注意:如果之前启用了
_resource_manager_always_off=TRUE(常见于性能调优场景),必须先设为FALSE再重启实例,否则plan不生效
容易被忽略的RAC特有陷阱
RAC环境下Resource Manager的行为和单实例有本质差异:
- consumer group分配必须在登录时完成,不能靠中间件动态切换;应用连接串里要带
service_name对应正确service,否则默认落到OTHER_GROUPS - 私有网络延迟会影响GCS锁协调,导致
MAX_IDLE_TIME检测滞后——建议私网MTU设为9000并禁用THP - 若使用SCAN listener,需确认
remote_listener指向正确的SCAN地址,否则部分节点可能无法获取心跳信号 - 监控要用
V$RSRC_CONSUMER_GROUP而非V$SESSION,后者不反映跨实例的资源配额消耗











