跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

如何限制用户CPU时间_CPU_PER_CALL与CPU_PER_SESSION设置

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

相关文章