Oracle 会话连接查询

created: 2026-04-22

updated: 2026-04-22


Oracle 会话连接查询笔记

场景:排查数据库 processes 即将达到上限 / 连接池泄漏 / 定位占用连接最多的应用模块。


一、基础背景

1.1 关键视图

视图 作用 说明
v$session 当前实例的会话信息 最核心视图
gv$session 跨 RAC 所有实例的会话 多实例必用
v$process OS 进程信息 与 session 一一对应
v$resource_limit 资源使用 vs 上限 查 processes/sessions 水位
v$active_services / gv$active_services 当前激活的 service 用于定位 service 所在实例
dba_services 数据库级注册的 service 静态配置
v$undostat UNDO 使用统计 排查 ORA-01555 / ORA-30036

1.2 关键字段

字段 含义
sid / serial# 会话唯一标识,kill 用
inst_id RAC 实例号(gv$ 视图才有)
username 数据库用户
osuser 操作系统用户
machine 客户端主机名(K8s 里是 Pod 名)
program 客户端程序(如 JDBC Thin Client
module 应用设置的模块名,最关键的定位字段
action 应用内细粒度动作名
service_name 会话通过哪个 service 进来
status ACTIVE 正在执行 / INACTIVE 空闲
last_call_et 距上次调用的秒数,判断空闲时长
logon_time 连接建立时间
type USER(业务) / BACKGROUND(后台进程)

过滤建议 :查业务连接务必加 WHERE type='USER',排除后台进程干扰。


二、查看总量和上限

sql 复制代码
-- 当前进程数 vs 参数上限
SELECT COUNT(*) FROM v$process;
SHOW PARAMETER processes

-- 一站式查 processes / sessions 水位
SELECT resource_name, current_utilization, max_utilization, limit_value
FROM v$resource_limit
WHERE resource_name IN ('processes','sessions');

判断依据:

  • current_utilization / limit_value > 85% → 预警
  • max_utilization 接近 limit_value → 曾经触顶
  • processes 静态参数,改动需重启

三、按不同维度聚合查询

3.1 按 module 汇总(最常用)

sql 复制代码
SELECT NVL(module,'(NULL)') AS module,
       COUNT(*)             AS sessions,
       SUM(DECODE(status,'ACTIVE',1,0))   AS active,
       SUM(DECODE(status,'INACTIVE',1,0)) AS inactive
FROM v$session
WHERE type='USER'
GROUP BY module
ORDER BY sessions DESC;

3.2 按 service_name 过滤后再看 module

sql 复制代码
SELECT NVL(module,'(NULL)')   AS module,
       NVL(program,'(NULL)')  AS program,
       NVL(username,'(NULL)') AS username,
       NVL(machine,'(NULL)')  AS machine,
       COUNT(*)               AS sessions,
       SUM(DECODE(status,'ACTIVE',1,0))   AS active,
       SUM(DECODE(status,'INACTIVE',1,0)) AS inactive
FROM v$session
WHERE type='USER'
  AND service_name='ccrb01'        -- 改成你要查的服务名
GROUP BY module, program, username, machine
ORDER BY sessions DESC;

3.3 按 machine(主机/Pod)聚合

sql 复制代码
SELECT machine,
       COUNT(*) sessions,
       COUNT(DISTINCT program) prog_cnt,
       LISTAGG(DISTINCT program, ', ') WITHIN GROUP (ORDER BY program) programs
FROM v$session
WHERE type='USER'
GROUP BY machine
ORDER BY sessions DESC
FETCH FIRST 30 ROWS ONLY;

3.4 按 service 汇总

sql 复制代码
SELECT service_name,
       COUNT(*) sessions,
       SUM(DECODE(status,'ACTIVE',1,0))   active,
       SUM(DECODE(status,'INACTIVE',1,0)) inactive
FROM v$session
WHERE type='USER'
GROUP BY service_name
ORDER BY sessions DESC;

3.5 多维聚合(module + machine + program)

sql 复制代码
SELECT NVL(module,'(NULL)')  AS module,
       NVL(program,'(NULL)') AS program,
       NVL(machine,'(NULL)') AS machine,
       COUNT(*)              AS sessions
FROM v$session
WHERE type='USER'
GROUP BY module, program, machine
ORDER BY sessions DESC
FETCH FIRST 50 ROWS ONLY;

3.6 RAC 场景:按实例 + module

sql 复制代码
SELECT inst_id,
       NVL(module,'(NULL)') AS module,
       COUNT(*) sessions
FROM gv$session
WHERE type='USER'
GROUP BY inst_id, module
ORDER BY inst_id, sessions DESC;

四、排查连接泄漏

4.1 长时间 INACTIVE 的空闲连接

sql 复制代码
-- 空闲超过 1 小时的会话,按 module + machine 聚合
SELECT module, machine,
       COUNT(*) cnt,
       MIN(last_call_et) min_idle_sec,
       MAX(last_call_et) max_idle_sec
FROM v$session
WHERE type='USER'
  AND status='INACTIVE'
  AND last_call_et > 3600
GROUP BY module, machine
ORDER BY cnt DESC;

4.2 按机器看空闲时长分布

sql 复制代码
SELECT machine,
       COUNT(*) cnt,
       MIN(last_call_et) min_idle,
       MAX(last_call_et) max_idle,
       ROUND(AVG(last_call_et)) avg_idle_sec
FROM v$session
WHERE type='USER'
  AND status='INACTIVE'
GROUP BY machine
ORDER BY cnt DESC;

4.3 按登录时间判断是否是启动即建

sql 复制代码
SELECT machine,
       TO_CHAR(MIN(logon_time),'YYYY-MM-DD HH24:MI') earliest,
       TO_CHAR(MAX(logon_time),'YYYY-MM-DD HH24:MI') latest,
       COUNT(*) cnt
FROM v$session
WHERE type='USER' AND module='Bootstrap'
GROUP BY machine
ORDER BY cnt DESC;
  • earliest ≈ latest → 启动时一次性建满,说明 minimum-idle 太大
  • earliest 和 latest 差距大 → 运行期逐步增长,可能真有业务压力

五、一站式诊断 SQL(首选)

sql 复制代码
SELECT NVL(username,'[SYS/BG]')   AS username,
       NVL(module,'(NULL)')       AS module,
       NVL(program,'(NULL)')      AS program,
       NVL(machine,'(NULL)')      AS machine,
       service_name,
       COUNT(*)                                  AS total,
       SUM(DECODE(status,'ACTIVE',1,0))          AS active,
       SUM(DECODE(status,'INACTIVE',1,0))        AS inactive,
       SUM(CASE WHEN status='INACTIVE' 
                 AND last_call_et>3600 
                THEN 1 ELSE 0 END)                AS idle_gt_1h
FROM v$session
WHERE type='USER'
GROUP BY username, module, program, machine, service_name
ORDER BY total DESC
FETCH FIRST 50 ROWS ONLY;

六、常见 module 名含义

module 值 来源 / 含义
Bootstrap Spring Boot 启动阶段线程名,多见于连接池初始化建立的连接
XxxBootApplication Spring Boot 应用主类名(如 ReceivableBootApplication
JDBC Thin Client 未设置 module,fallback 到 program 名
(NULL) 未设置 module
SQL*Plus sqlplus 客户端
oracle@hostname (XXX) 后台进程,不会出现在 type='USER' 查询里
TOAD / PLSQL Developer / Navicat 图形客户端
emagent / GoldenGate Oracle 自家组件

提示Bootstrap 并不是业务 module,而是 Spring Boot 在 bootstrap.yml / SpringApplication.run() 阶段建立连接时,JDBC Driver 用主线程名打的标签。即使后面业务线程(如 http-nio-xxx)复用了这些连接,module 也不会自动更新,除非代码显式调用 setClientInfo


七、应急处置

7.1 预览要 kill 的会话

sql 复制代码
-- 先看看长时间空闲的会话是谁
SELECT sid, serial#, inst_id, machine, module, 
       ROUND(last_call_et/3600,1) idle_h
FROM gv$session
WHERE type='USER'
  AND status='INACTIVE'
  AND last_call_et > 7200
ORDER BY last_call_et DESC
FETCH FIRST 100 ROWS ONLY;

7.2 生成批量 KILL 语句

sql 复制代码
SELECT 'ALTER SYSTEM KILL SESSION '''
       ||sid||','||serial#||',@'||inst_id||''' IMMEDIATE;' AS cmd
FROM gv$session
WHERE type='USER'
  AND module='Bootstrap'                    -- 改成你要处理的 module
  AND status='INACTIVE'
  AND last_call_et > 3600;

⚠️ IMMEDIATE 立即终止;不加 IMMEDIATE 会标记为 KILLED,等下次用到才真正释放。

⚠️ 连接池应用 kill 后会自动重建,治标不治本,必须配合应用侧调整 maximum-pool-size

7.3 临时上调 processes(需重启)

sql 复制代码
ALTER SYSTEM SET processes=2500 SCOPE=SPFILE;
-- 重启生效
-- 同步调整 sessions(通常 ≈ 1.5 * processes + 22)
ALTER SYSTEM SET sessions=3800 SCOPE=SPFILE;

还需要配合调整:OS 层 nproc / nofile limits、PGA_AGGREGATE_TARGET、SGA 大小。


八、service_name 查询注意事项

8.1 大小写敏感

v$session.service_name 按 PMON 注册时的原样存储,精确查不到时用模糊:

sql 复制代码
SELECT service_name, COUNT(*) cnt
FROM v$session
WHERE UPPER(service_name) LIKE '%CCRB01%'
GROUP BY service_name;

8.2 确认 service 是否存在

sql 复制代码
-- 监听器里注册的
SELECT name, inst_id, creation_date
FROM gv$active_services
WHERE UPPER(name) LIKE '%CCRB01%';

-- 数据库元数据里配置的
SELECT name, network_name FROM dba_services
WHERE UPPER(name) LIKE '%CCRB01%';

8.3 默认服务 vs 自定义服务

类型 举例 特征
默认服务 ccrb04ccrb04.domaindb_unique_name PMON 自动注册,无法 srvctl 管理,无角色属性
自定义服务 ccrb04_appccrb04_ro srvctl 创建,可设 -role PRIMARY / -role PHYSICAL_STANDBY

应用永远不要连默认服务,连自定义的 role-based service,Data Guard 切换才能透明。


九、判断连接池问题的信号

观测到的现象 大概率原因
ACTIVE=0INACTIVE 大量堆积 连接池预分配过大(maximum-pool-size / minimum-idle 太大)
同一 machine/Pod 占用 100+ 连接 连接池参数设置不合理
last_call_et 平均几小时 连接长期空闲未回收,idle-timeout 未设或过长
logon_time 集中在 Pod 启动时刻 minimum-idle 启动即建满
多个 XxxBootApplication 共存 多个微服务共用一个数据库,需分别排查

十、HikariCP 推荐参数(应用侧治本)

yaml 复制代码
spring:
  datasource:
    hikari:
      maximum-pool-size: 20         # 单 Pod 最大连接,别超 20~30
      minimum-idle: 5               # 常驻少量
      idle-timeout: 300000          # 5 分钟空闲回收
      max-lifetime: 1800000         # 30 分钟强制重建,避免连接老化
      connection-timeout: 30000
      validation-timeout: 5000
      keepalive-time: 150000        # 2.5 分钟心跳

估算数据库 processes 需求:

复制代码
总连接 ≈ 微服务数 × Pod副本数 × maximum-pool-size + 运维/监控会话 + 后台进程缓冲

HikariCP 官方观点:连接池不是越大越好 。池大小 = (2 × CPU核心) + 有效磁盘数 是经验起点,大多数场景 10~20 就够。


十一、主动埋点 module(应用侧)

应用代码里显式设置,使 v$session.module 有业务意义,便于日后排查:

Java (JDBC)

java 复制代码
Connection conn = ds.getConnection();
conn.setClientInfo("OCSID.MODULE", "OrderService");
conn.setClientInfo("OCSID.ACTION", "createOrder");

PL/SQL

sql 复制代码
BEGIN
  DBMS_APPLICATION_INFO.SET_MODULE('BatchJob', 'NightlyETL');
END;
/

MyBatis 拦截器、Spring AOP 可全局设置 module=服务名、action=方法名。


十二、常用组合命令速查

sql 复制代码
-- 1. 看水位
SELECT resource_name, current_utilization, max_utilization, limit_value
FROM v$resource_limit WHERE resource_name IN ('processes','sessions');

-- 2. 看 module 分布
SELECT module, COUNT(*) FROM v$session WHERE type='USER' GROUP BY module ORDER BY 2 DESC;

-- 3. 看特定 service 下的应用
SELECT module, machine, COUNT(*) FROM v$session 
WHERE type='USER' AND service_name='xxx' 
GROUP BY module, machine ORDER BY 3 DESC;

-- 4. 找泄漏
SELECT module, machine, COUNT(*) FROM v$session 
WHERE type='USER' AND status='INACTIVE' AND last_call_et>3600 
GROUP BY module, machine ORDER BY 3 DESC;

-- 5. 预览 KILL 语句
SELECT 'ALTER SYSTEM KILL SESSION '''||sid||','||serial#||''' IMMEDIATE;' 
FROM v$session WHERE <条件>;

相关推荐
2301_777599372 小时前
Oracle环境下的设置主键与自增列指南_特定语法与可视化配置
jvm·数据库·python
a9511416422 小时前
Golang怎么用go get添加依赖_Golang如何在项目中引入第三方库【入门】
jvm·数据库·python
老王谈企服2 小时前
[信创选型] 2026国产化替代进入应用层:有没有通过国产化认证、能在麒麟系统上跑的合规Agent?
数据库·人工智能·ai
4t4run2 小时前
1、clickhouse 安装
数据库·clickhouse
Gauss松鼠会2 小时前
【openGauss】openGauss 磁盘引擎之 ustore
java·服务器·开发语言·前端·数据库·经验分享·gaussdb
Chasing__Dreams2 小时前
Mysql--基础知识点--105--分布式事务
数据库·分布式·mysql
m0_676544382 小时前
Golang怎么解决nil pointer错误_Golang如何排查和修复空指针引用崩溃【避坑】
jvm·数据库·python
风兮雨露2 小时前
Windows 部署Redis免安装版以及客户端
数据库·windows·redis
与数据交流的路上2 小时前
mysql-通过binlog分析大事务
数据库·mysql