Oracle 会话与进程管理

1.1、会话(Session)与连接(Connection)

在 Oracle 中,连接(Connection)是客户端与数据库之间的通信链路,会话(Session)是数据库为用户建立的状态上下文。一个连接可以对应多个会话(如连接池),一个会话也可以没有连接(如共享服务器模式)。

实例:连接与会话的概念区分

**S --- Situation(场景):**应用团队报告"数据库连接数满了",但 DBA 检查发现 PROCESSES 参数设置为 500,当前连接数只有 300。

**T --- Task(任务):**分析连接数与会话数的差异,找到真正的问题。

A --- Action(行动):

1、查看当前连接数和会话数:

-- 连接数(操作系统层面)

SELECT COUNT(*) FROM V$SESSION WHERE TYPE = 'USER';

2、查看会话数(数据库层面):

SELECT COUNT(*) FROM V$SESSION; -- 返回 450(包含后台进程会话)

3、查看各类型会话分布:

SELECT TYPE, COUNT(*) FROM V$SESSION GROUP BY TYPE;

-- USER: 300, BACKGROUND: 120, OTHER: 30

4、查看 PROCESSES 参数:

SHOW PARAMETER PROCESSES; --500

5、 分析:后台进程 + 用户会话 = 420,接近上限 500

-- 解决方案:增加 PROCESSES 或优化连接池

**R --- Result(结果):**问题是 PROCESSES 参数包含了所有进程(用户进程 + 后台进程 + 系统进程),不仅仅是用户连接。增加了 PROCESSES 到 800,并优化了应用连接池配置。

1.2、会话解控与管理

实例:定位并终止阻塞会话

**S --- Situation(场景):**某关键业务表被锁,大量 INSERT 操作挂起,应用报 ORA-00054: resource busy and acquire with NOWAIT specified。

**T --- Task(任务):**快速定位阻塞源并解除锁定。

A --- Action(行动):

1、查找阻塞会话:

SELECT s.SID, s.SERIAL#, s.USERNAME, s.STATUS,s.MACHINE, s.PROGRAM, s.LOGON_TIME,l.TYPE, l.ID1, l.ID2 FROM VSESSION s JOIN VLOCK l ON s.SID = l.SID WHERE l.BLOCK > 0;

2、查找被阻塞的会话

SELECT s.SID, s.USERNAME, s.STATUS, s.SQL_ID FROM V$SESSION s WHERE s.BLOCKING_SESSION IS NOT NULL;

3、查看阻塞会话正在执行的 SQL:

SELECT SQL_TEXT FROM VSQL WHERE SQL_ID = (SELECT SQL_ID FROM VSESSION WHERE SID = <blocking_sid>);

4、 终止阻塞会话:

ALTER SYSTEM KILL SESSION '<SID>,<SERIAL#>' IMMEDIATE;

-- IMMEDIATE 立即终止,无需等待

5、验证锁释放

SELECT * FROM V$LOCK WHERE BLOCK > 0; -- 无返回,阻塞已解除

**R --- Result(结果):**在 30 秒内定位阻塞源并终止会话,业务恢复正常。后续建立了锁等待告警,超过 60 秒自动通知 DBA。

1.3、进程限制与 PROCESSES 参数

实例:ORA-00020 错误排查

**S --- Situation(场景):**数据库突然拒绝新连接,报 ORA-00020: maximum number of processes exceeded。

**T --- Task(任务):**紧急处理并根治进程耗尽问题。

A --- Action(行动):

1、紧急处理:使用 SYSDBA 连接(SYSDBA 连接不受 PROCESSES 限制):

sqlplus / as sysdba

2、查看当前进程数和限制:

SELECT COUNT(*) FROM V$PROCESS;

SHOW PARAMETER PROCESSES;

3、找到占用大量连接的应用:

SELECT MACHINE, PROGRAM, COUNT(*) AS CNT FROM V$SESSION GROUP BY MACHINE, PROGRAM ORDER BY CNT DESC;

4、终止异常应用的空闲会话:

SELECT 'ALTER SYSTEM KILL SESSION "' || SID || ',' || SERIAL# || '" IMMEDIATE;' FROM V$SESSION WHERE MACHINE LIKE '<异常主机>%' AND STATUS = 'INACTIVE' AND LAST_CALL_ET > 3600;

5、长期解决方案:

-- 增加 PROCESSES 参数

ALTER SYSTEM SET PROCESSES = 1000 SCOPE=SPFILE;

-- 优化应用连接池配置

-- 设置 SQLNET.EXPIRE_TIME 检测死连接

**R --- Result(结果):**紧急恢复了数据库连接。长期通过增加 PROCESSES、优化连接池、配置死连接检测三管齐下,彻底解决了进程耗尽问题。

1.4、会话级参数调整

实例:会话集参数优化特定查询

**S --- Situation(场景):**某报表查询使用了错误的执行计划(全表扫描),需要临时增大该会话的 SORT_AREA_SIZE 以加速排序,同时不影响其他会话。

**T --- Task(任务):**在会话级别调整参数,优化特定查询。

A --- Action(行动):

1、创建专用会话并调整参数:

ALTER SESSION SET SORT_AREA_SIZE = 104857600; -- 100MB

ALTER SESSION SET HASH_AREA_SIZE = 104857600; -- 100MB

ALTER SESSION SET WORKAREA_SIZE_POLICY = MANUAL;

2、执行优化后的查询:

SELECT /*+ PARALLEL(4) */ department_id, SUM(salary) FROM employees GROUP BY department_id ORDER BY 2 DESC;

3、恢复默认参数:

ALTER SESSION SET WORKAREA_SIZE_POLICY = AUTO;

4、或者使用 SQL Profile 固定执行计划:

-- 使用 SQL Tuning Advisor

sql 复制代码
 DECLARE
  l_task VARCHAR2(30);
BEGIN
  l_task := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_id => '<SQL_ID>');
  DBMS_SQLTUNE.EXECUTE_TUNING_TASK(l_task);
END;

**R --- Result(结果):**会话级参数调整使排序操作在内存中完成,查询时间从 120 秒降至 8 秒。SQL Profile 固定了最优执行计划,后续无需手动调整。

相关推荐
ClouGence1 天前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
飞将1 天前
从零实现数据库(2)——HashIndex + IndexManager
数据库
Nturmoils2 天前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
渣波2 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
倔强的石头_3 天前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
倔强的石头_6 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
冬奇Lab6 天前
每日一个开源项目(第134篇):Zvec - 阿里开源的嵌入式向量数据库,向量搜索界的 SQLite
数据库·人工智能·llm
ClouGence7 天前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle
无响应de神7 天前
三、用户与权限管理
数据库·mysql
麦聪聊数据8 天前
数据服务化时代:企业数据能力输出的核心路径
数据库