Resource Manager 不能直接断开会话,它仅限资源分配与限制,如CPU、并行度、活动会话数等,不执行KILL SESSION;“自动断开”实为IDLE_TIME配合PROFILE实现,Resource Manager仅能通过switch_time切换组间接压制。
Resource Manager 能不能直接断开会话
不能。oracle resource manager 本身不提供「主动 kill session」的能力,它只做资源分配与限制,比如限制 cpu、并行度、活动会话数(active_sess_pool_p1),或在超时后自动取消排队中的请求(queueing_p1)。它不会触发 alter system kill session 这类操作。所谓“自动断开”,实际是通过资源限制间接实现的:当会话因超出 active_sess_pool_p1 被阻塞在队列中,又超过 queueing_p1 时限,就会被系统取消——但这不是 kill,而是拒绝执行,会话本身仍处于 inactive 状态并持续占用连接。
用 Resource Manager 限制空闲会话的正确方式
Resource Manager 对空闲会话真正有效的控制点只有一个:switch_time + switch_group 配合 idle_time Profile。但注意:idle_time 是 Profile 层级的限制,和 Resource Manager 无关;Resource Manager 只能基于「活跃时间(active time)」切换组,不能基于「空闲时间(idle time)」。
-
switch_time指的是会话在当前 consumer group 中**连续活跃**的最长时间(单位秒),不是空闲时间 - 一旦达到
switch_time,会话会被迁移到switch_group(如OTHER_GROUPS),而该组可被配置为极低资源配额,使其后续操作几乎无法执行 - 真正管“空闲多久就断开”的,仍是
IDLE_TIME参数,它依赖RESOURCE_LIMIT=TRUE才生效
为什么不能只靠 Resource Manager 实现自动断开
因为 Resource Manager 的设计目标是“资源调度”,不是“连接生命周期管理”。它不读取 v$session.last_call_et,也不响应空闲状态变化。你看到的“自动断开”效果,往往是以下组合的结果:
-
ALTER PROFILE DEFAULT LIMIT IDLE_TIME 30—— 空闲 30 分钟后,下次用户发语句时收到 ORA-02396 错误并中断 -
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(..., switch_time => 1800, switch_group => 'LOW_GROUP')—— 活跃满 30 分钟后切组,后续查询变极慢甚至超时 - 两者叠加使用时,用户可能先被切组卡住,再因空闲超时被拒绝新请求,但 session 本身仍留在
v$session中,状态为INACTIVE
真正干净地清理连接,仍需存储过程配合 v$session.last_call_et 查询 + ALTER SYSTEM KILL SESSION,Resource Manager 只能辅助压制,不能替代。
容易被忽略的关键细节
很多人在配置 Resource Manager 后发现“没生效”,问题通常出在这些地方:
- 没调用
DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA()和DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA(),导致 plan directive 未提交 - 没启用 resource plan:
ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = 'YOUR_PLAN_NAME',否则所有 directive 都不运行 - 会话未被正确分配到 consumer group:默认走
OTHER_GROUPS,而你只给自定义组设了switch_time -
switch_estimate => TRUE时,Oracle 会预估 SQL 执行时间来决定是否提前切换,但预估不准会导致行为不可控,生产环境建议保持FALSE
Resource Manager 是精细调控工具,不是兜底开关。想让空闲连接真正消失,Profile 的 IDLE_TIME 是第一道防线,存储过程才是最后一刀。











