ora-00020错误根本解法是配置dbms_resource_manager的max_idle_time,而非调大processes;需为应用consumer group(如app_users)显式创建plan directive,设max_idle_time=1800秒,other_groups不生效。
ora-00020 错误不是调大 processes 就能解决的
看到 ora-00020: maximum number of processes(2000) exceeded,第一反应不该是改 processes 参数。实际排查中,两节点 rac 实例常有 1900+ 个 inactive 会话,真正 active 的才三四个——说明连接被应用长期占着不放,数据库已失去控制权。此时杀会话(alter system kill session)往往无效:sid/serial# 已失效;用 kill -9 又太粗暴,可能中断未提交事务。
PROFILE 的 IDLE_TIME 对 INACTIVE 会话完全不生效
很多人以为给用户配个 PROFILE、设 IDLE_TIME => 30 就能自动断开空闲连接,这是常见误解。Oracle 的 PROFILE 中的 IDLE_TIME 仅作用于**专用服务器模式下客户端主动断连后、服务端尚未清理的“假空闲”状态**,且只在下次该会话尝试执行语句时才检查。对大量长期挂起的 INACTIVE 会话(比如连接池维持的空闲连接),它根本不会触发断连。
-
IDLE_TIME不影响共享服务器(MTS)模式 - 它不检查网络层是否存活,只依赖会话是否发新请求
- RAC 环境中该设置不跨实例同步,无法统一管控
必须用 DBMS_RESOURCE_MANAGER 配 MAX_IDLE_TIME
真正能自动清理挂起连接的,只有资源管理器(Resource Manager)的 MAX_IDLE_TIME,且必须显式配置在具体 consumer group 的 plan directive 中:
- 不能设在
OTHER_GROUPS上——它是只读组,MAX_IDLE_TIME被忽略 - 必须为应用用户分配的 consumer group 单独创建 directive,例如
APP_USERS - 值以秒为单位,如
max_idle_time => 1800表示 30 分钟无活动即断开 - 该策略对新建立的会话立即生效;已有
INACTIVE会话需等下次被激活时才检查空闲时长
示例:
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;
为什么资源管理器比 PROFILE 更可靠
资源管理器不拦截连接,但能在会话建立后施加实时约束,且对 INACTIVE 状态也生效。它的触发机制基于数据库内部心跳检测,不依赖客户端行为或网络保活包。相比之下,PROFILE 是静态声明式策略,缺乏运行时干预能力。RAC 环境中,DBMS_RESOURCE_MANAGER 的 plan 和 directive 在所有节点一致生效,无需逐节点维护。真正难的是把应用用户正确映射到 consumer group——这一步漏掉,MAX_IDLE_TIME 就等于没配。











