必须启用 resource_manager_plan(如 DEFAULT_PLAN)且会话所属 consumer group 正确,CPU 限制才生效;否则 cpu_per_session 等参数仅告警不中断。
不启用 resource manager,所有用户级 cpu 限制都无效——这是最常被卡住的第一步。
确认 CDB 是否已启用 resource_manager_plan
Oracle 默认不开启资源管理,哪怕你后续给用户、PDB 或 consumer group 配了各种参数,只要 resource_manager_plan 是空的,就等于没设。
在 CDB$ROOT 中执行:
SELECT value FROM v$parameter WHERE name = 'resource_manager_plan';
如果返回空值或 '',说明没开。必须先启用一个支持用户级控制的 plan,比如 Oracle 自带的 DEFAULT_PLAN:
ALTER SYSTEM SET resource_manager_plan = 'DEFAULT_PLAN' SCOPE=BOTH;
-
DEFAULT_PLAN支持 PDB 级和 consumer group 级指令;自定义 plan 若没显式包含PDB_DIRECTIVE或GROUP_OR_SUBPLAN,配了也白配 - 改完后查
DBA_RSRC_PLANS确认状态:SELECT plan, status FROM DBA_RSRC_PLANS WHERE status = 'ACTIVE'; - 注意:只改
cpu_per_session或cpu_per_call这类 profile 参数,不启用 Resource Manager,完全不生效
给用户分配 consumer group 并设置 CPU 百分比(EMPHASIS 模式)
Resource Manager 不直接限制“某个用户”,而是把用户映射到 consumer_group,再通过 plan directive 分配 CPU 资源。EMPHASIS 是最常用、也最稳妥的分配方式。
例如,想让运维账号 maint_user 在高负载时仍能抢到至少 20% 的 CPU:
BEGIN
DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();
DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP(
CONSUMER_GROUP => 'MAINT_GROUP',
COMMENT => 'For maintenance users'
);
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
PLAN => 'DEFAULT_PLAN',
GROUP_OR_SUBPLAN => 'MAINT_GROUP',
COMMENT => 'Guarantee min CPU',
CPU_P1 => 20 -- 级别 1,最高优先级,固定占 20%
);
DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA();
DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();
END;
/-
CPU_P1到CPU_P8表示 8 个优先级层级,数值是该层级内可分配的百分比上限;未用完的部分会下放给低一级 - 必须调用
GRANT_SWITCH_CONSUMER_GROUP才能让用户实际切换过去:DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP('maint_user', 'MAINT_GROUP', FALSE); - 用户登录后默认不会自动进 group,需显式执行:
EXEC DBMS_SESSION.SWITCH_CONSUMER_GROUP('MAINT_GROUP');,或配置SET_CONSUMER_GROUP_MAPPING实现自动映射
用 profile + Resource Manager 控制单次调用或会话总 CPU 时间
CPU_PER_SESSION 和 CPU_PER_CALL 是硬性超时机制,单位是“十分之一秒”(如 300 = 30 秒),但它们只在 Resource Manager 启用且用户属于某个 consumer group 时才起作用。
创建 profile 示例:
CREATE PROFILE heavy_job LIMIT CPU_PER_SESSION 600 -- 60 秒 CPU_PER_CALL 100 -- 10 秒 CONNECT_TIME 1440; -- 24 小时
再把用户和 profile 绑定:
ALTER USER batch_user PROFILE heavy_job;
- 这个 profile 必须配合 Resource Manager 使用——否则
CPU_PER_SESSION只会触发警告(ORA-02392),不会强制中断 - 真正中断依赖于 consumer group 的 plan directive 中是否启用了
SWITCH_GROUP或SWITCH_TIME;否则超限后只是记录告警,会话继续运行 -
CPU_PER_CALL对 PL/SQL 匿名块、单条 SQL 执行有效;对长事务中的多次 fetch 不累计,每次 fetch 算一次 call
常见失效场景与排查重点
很多配置看似正确却不起作用,问题往往出在链路断点上:
- 查用户当前 consumer group:
SELECT resource_consumer_group FROM v$session WHERE username = 'BATCH_USER';,为空说明没映射成功 - 查 plan 是否真在运行:
SELECT name, cpu_managed FROM v$rsrc_plan;,CPU_MANAGED为YES才表示 CPU 调度已接管 -
cpu_count是实例级参数,它限制的是整个实例可用的线程数,不是用户级;不要把它和CPU_PER_SESSION混用 - 如果用了 RAC,plan 必须在每个 instance 上单独启用:
ALTER SYSTEM SET resource_manager_plan = 'DEFAULT_PLAN' SCOPE=BOTH SID='*';
最关键的检查项永远只有两个:当前 session 是否落在正确的 consumer_group,以及 v$rsrc_plan.CPU_MANAGED 是否为 YES。其他所有参数都是在这两个前提下才开始计算的。


















