CPU_PER_CALL和CPU_PER_SESSION是Oracle资源管理器中限制单次调用或会话累计CPU时间的硬配额,单位为十分之一秒(如200=20秒),仅在启用Resource Manager并为consumer group显式配置时生效。
Oracle 中
和
是什么
这两个参数是 oracle resource manager(资源管理器)里用于限制单次调用或整个会话 cpu 使用量的硬性配额,单位是“十分之一秒”(centiseconds)。不是百分比,也不是毫秒,容易误读成“100 = 1 秒”,实际是
—— 因为 100 × 0.1s = 10s。
它们只在启用 Resource Manager 并分配了对应 consumer group 的情况下才生效;单纯在 profile 里设没用,这点常被忽略。
:限制单条 SQL 或 PL/SQL 调用(比如一次
、一次
)最多能用多少 CPU 时间,超时直接报
:限制整个会话生命周期内累计可用的 CPU 时间,超限后会话被强制断开,错误通常是
(注意错误码不同)
两者不叠加生效:
先触发就先报错,不会等累计到
怎么设置才真正生效
必须走 Resource Manager 流程,不能靠
或初始化参数。常见错误是改了 profile 却发现完全没限制效果——因为 profile 里的
字段在 12c+ 已废弃,仅保留兼容性,实际不生效。
创建 resource plan:
定义 consumer group(比如叫
),并把用户映射过去:
在 plan directive 中显式指定:
(或
等)配合
和
值,例如:
表示最多 20 秒
启用 plan:
没执行最后一步
,前面全白配。
为什么设置了还是被绕过
几个高频漏点导致限制形同虚设:
用户属于
,而 plan directive 没给它配任何
值(默认不限制)
用了
或后台 job,job 默认运行在
,不受你配的 plan 约束
DBA 用户(如
、
)即使被映射到受限 group,Oracle 也会跳过资源限制(这是硬编码行为,无法关闭)
并行查询(
)的 CPU 计算方式特殊:按 coordinator + 所有 slave 进程的总 CPU 累加,但
只检查 coordinator 的单次调用耗时,容易误判“没超限”
性能和监控怎么看是否起作用
别只看会不会报错,要确认真实压制效果。关键视图是
和
:
里
突增,说明 session 在等 CPU 配额释放,限制已介入
的
和
能看出 group 是否排队
查
的
字段,确保当前 session 真的落在你配的 group 里(不是
)
测试时用
真正难的是并行场景下的配额解释权在 Oracle 内部调度器手里,文档没写清怎么分摊,实测值常和理论值偏差较大。
CPU_PER_CALLCPU_PER_SESSION100 = 10 秒CPU_PER_CALLSELECTEXECUTEORA-02392: exceeded session limit on CPU usageCPU_PER_SESSIONORA-02393: exceeded call limit on CPU usageCPU_PER_CALLCPU_PER_SESSIONALTER PROFILECPU_PER_CALLBEGIN DBMS_RESOURCE_MANAGER.CREATE_PLAN(plan => 'LIMIT_CPU_PLAN'); END;low_cpu_groupDBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPINGCPU_P1CPU_P2CPU_PER_CALLCPU_PER_SESSIONCPU_PER_CALL => 200ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = 'LIMIT_CPU_PLAN'ALTER SYSTEMDEFAULT_CONSUMER_GROUPCPU_PER_*DBMS_SCHEDULERSYS_GROUPSYSSYSTEMPXCPU_PER_CALLV$RSRC_SESSION_INFOV$RSRC_CONSUMER_GROUPV$RSRC_SESSION_INFOCPU_WAIT_TIMEV$RSRC_CONSUMER_GROUPACTIVE_SESSIONSEXECUTION_WAITERSV$SESSIONRESOURCE_CONSUMER_GROUPOTHER_GROUPSSELECT /*+ NO_PARALLEL */ COUNT(*) FROM big_table CONNECT BY LEVEL 这类纯 CPU 消耗语句,避免 I/O 干扰判断