如何限制Oracle用户的会话数和资源消耗

作者:袖梨 2026-08-24

根本原因是RESOURCE_LIMIT参数为FALSE,导致所有PROFILE资源限制(含SESSIONS_PER_USER)失效;需执行ALTER SYSTEM SET resource_limit=TRUE SCOPE=BOTH启用,且连接池空闲会话、INACTIVE残留会话及DBA权限用户均不受限。

SESSIONS_PER_USER 为什么设了没反应

根本原因通常是 RESOURCE_LIMIT 参数为 FALSE,所有 PROFILE 里的资源限制(包括 SESSIONS_PER_USER)全部失效。查一下:

SHOW PARAMETER resource_limit,如果返回 FALSE,必须执行:

ALTER SYSTEM SET resource_limit = TRUE SCOPE = BOTH;

注意:该参数修改后立即生效,无需重启。

其他常见干扰项:

  1. 连接池(如 HikariCP、Druid)维持大量空闲连接,但 Oracle 看到的是复用的会话——SESSIONS_PER_USER 统计的是“活跃会话数”,不是连接池里配置的 maxPoolSize;需确保两者匹配,否则第 6 次连接就报 ORA-02391
  2. 已存在的会话不受新 PROFILE 限制影响,只对后续新建会话生效
  3. DBA 用户或拥有 RESTRICTED SESSION 权限者完全绕过该限制
  4. 通过 ALTER SESSION SET CURRENT_SCHEMA 切换 schema 不产生新用户会话,仍计入原用户名的计数

PROFILE 能否限制 CPU 或 IO 占用

不能硬性限制。比如设了 CPU_PER_SESSION = 3600(即 36 秒),一个运行中的大查询不会被中断或降频——它只在语句执行完后累计检查,超限则断开会话;对 IO 更是无效:LOGICAL_READS_PER_SESSION 统计的是逻辑读块数,不等于物理 IO 带宽,也不触发实时流控。

真正能做 CPU/IO 实时调度的只有 Resource Manager,但它必须三要素齐备:

  1. 消费者组(CONSUMER_GROUP):不能直接改 DEFAULT_CONSUMER_GROUP,得新建
  2. 资源计划(PLAN):用 DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE 显式指定 CPU_P1 和(PDB 环境下才生效的)MAX_IOPS/MAX_MBPS
  3. 映射规则(SET_CONSUMER_GROUP_MAPPING):优先级要设对,否则用户名映射被 service_name 覆盖,用户进 OTHER_GROUPS——而该组默认无配额

所有操作前必须调 DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA(),提交前必须 SUBMIT_PENDING_AREA(),否则全是内存草稿。

PROCESSES 和 SESSIONS 参数改哪个、怎么改

PROCESSES 是底层硬限制,决定实例最大 OS 进程数;SESSIONS 是推导值(默认 1.1 * PROCESSES + 5),控制最大并发用户会话数。两者不是独立开关:

  1. 只改 SESSIONS 不碰 PROCESSES,可能因进程槽位不足导致 ORA-00020,尤其在连接池场景下
  2. PROCESSES 必须用 SCOPE=SPFILE 修改,且需重启实例才生效;改之前确认 OS 层 ulimit -u ≥ 新值,否则实例起不来
  3. SESSIONS 在 19c+ 可 SCOPE=BOTH 动态调,但仅当未超当前 PROCESSES 限额时才真生效
  4. 手动设死 SESSIONS 容易脱钩,默认值更稳妥;若真要调,别超过 1.5 * PROCESSES,老版本(12c 以前)可能出结构异常

Resource Manager 在 PDB 下限制 IO 的真实条件

MAX_IOPSMAX_MBPS 这两个参数只在 PDB 级别设置才对用户 IO 生效,且有两个前提缺一不可:

  1. 目标 PDB 的 resource_manager_plan 参数非空(查:SELECT value FROM v$parameter WHERE name = 'resource_manager_plan'
  2. 该 PDB 已显式启用资源管理器,不能依赖 CDB$ROOT 的设置——CDB 里设的只是新 PDB 的默认继承值,不影响现有 PDB 内用户

验证时别只看 PROFILE 是否分配成功,重点查用户实际归属组:SELECT resource_consumer_group FROM v$session WHERE username = 'XXX';如果返回 OTHER_GROUPS,说明映射或计划没生效,IO 限制形同虚设。

相关文章

精彩推荐