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 固定了最优执行计划,后续无需手动调整。

相关推荐
shark-chili1 小时前
基于claude code的redis慢查询指令复刻实践
数据库·redis·缓存
@我漫长的孤独流浪1 小时前
数据库完整性约束与安全机制全解析
数据库
px不是xp2 小时前
Docker部署Qdrant向量数据库,初始化向量数据库,重构RAG逻辑
数据库·docker·微信小程序·重构·qdrant
funnycoffee1232 小时前
Cisco Firewpower 4100 9300 FXOS change management ip address
linux·数据库·tcp/ip
Chase_______2 小时前
Java 基础语言 ③:流程控制与数组——从条件分支到数组遍历,一篇通关
java·数据库·python
2501_921939262 小时前
MySQL(备份恢复、主从复制读写分离)
数据库·mysql
阿kun要赚马内2 小时前
SQLAlchemy的类型定义语法
数据库·oracle
星纬智联技术2 小时前
给 Amp 配置自定义 API:CLIProxyAPI 接入教程
运维·服务器·数据库
浩~~2 小时前
极客大挑战2019-LoveSQL
数据库