最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何限制Oracle用户的会话数和资源消耗
时间:2026-08-24 09:24:51 编辑:袖梨 来源:一聚教程网
根本原因是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;
注意:该参数修改后立即生效,无需重启。
其他常见干扰项:
- 连接池(如 HikariCP、Druid)维持大量空闲连接,但 Oracle 看到的是复用的会话——
SESSIONS_PER_USER统计的是“活跃会话数”,不是连接池里配置的maxPoolSize;需确保两者匹配,否则第 6 次连接就报ORA-02391 - 已存在的会话不受新 PROFILE 限制影响,只对后续新建会话生效
- DBA 用户或拥有
RESTRICTED SESSION权限者完全绕过该限制 - 通过
ALTER SESSION SET CURRENT_SCHEMA切换 schema 不产生新用户会话,仍计入原用户名的计数
PROFILE 能否限制 CPU 或 IO 占用
不能硬性限制。比如设了 CPU_PER_SESSION = 3600(即 36 秒),一个运行中的大查询不会被中断或降频——它只在语句执行完后累计检查,超限则断开会话;对 IO 更是无效:LOGICAL_READS_PER_SESSION 统计的是逻辑读块数,不等于物理 IO 带宽,也不触发实时流控。
真正能做 CPU/IO 实时调度的只有 Resource Manager,但它必须三要素齐备:
- 消费者组(
CONSUMER_GROUP):不能直接改DEFAULT_CONSUMER_GROUP,得新建 - 资源计划(
PLAN):用DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE显式指定CPU_P1和(PDB 环境下才生效的)MAX_IOPS/MAX_MBPS - 映射规则(
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),控制最大并发用户会话数。两者不是独立开关:
- 只改
SESSIONS不碰PROCESSES,可能因进程槽位不足导致ORA-00020,尤其在连接池场景下 -
PROCESSES必须用SCOPE=SPFILE修改,且需重启实例才生效;改之前确认 OS 层ulimit -u≥ 新值,否则实例起不来 -
SESSIONS在 19c+ 可SCOPE=BOTH动态调,但仅当未超当前PROCESSES限额时才真生效 - 手动设死
SESSIONS容易脱钩,默认值更稳妥;若真要调,别超过1.5 * PROCESSES,老版本(12c 以前)可能出结构异常
Resource Manager 在 PDB 下限制 IO 的真实条件
MAX_IOPS 和 MAX_MBPS 这两个参数只在 PDB 级别设置才对用户 IO 生效,且有两个前提缺一不可:
- 目标 PDB 的
resource_manager_plan参数非空(查:SELECT value FROM v$parameter WHERE name = 'resource_manager_plan') - 该 PDB 已显式启用资源管理器,不能依赖 CDB$ROOT 的设置——CDB 里设的只是新 PDB 的默认继承值,不影响现有 PDB 内用户
验证时别只看 PROFILE 是否分配成功,重点查用户实际归属组:SELECT resource_consumer_group FROM v$session WHERE username = 'XXX';如果返回 OTHER_GROUPS,说明映射或计划没生效,IO 限制形同虚设。