Oracle session连接数和inactive的问题记录(清除方法)

本文针对Oracle数据库出现的maxsession问题进行分析,介绍了如何检查当前会话情况,包括查询总会话数、查找死锁以及会话状态等。此外,还提供了几种解决方法,如调整最大会话数、清理无效会话等。

从上周起,服务器Oracle数据库出现问题,用不到半天,就会报maxsession(150)的问题,肯定是数据库的会话超过最大数了。
由于服务器跑的是文件传输应用,占用的请求和会话肯定很大,因此用户数不大就已经让oracle的会话数达到最大值。
处理方式不外乎两种:扩大oracle最大session数以及清除inactive会话,当然还有,就是从数据库连接池和程序bug上面下手。

从各处收集了一些查看当前会话的语句,记录一下:

1.select count(*) from v$session;
select count(*) from v$process;
查看当前总会话数和进程数,这两个视图就是跟会话及进程有关的重要视图啦,信息都是从这里面取的。

2.查询那些应用的连接数此时是多少
select b.MACHINE, b.PROGRAM , count(*) from v$process a, v$session b where a.ADDR = b.PADDR and b.USERNAME is not null   group by b.MACHINE , b.PROGRAM order by count(*) desc;

3.查询是否有死锁
select * from v$locked_object;
如果查询结果为no rows selected,说明数据库中没有死锁。否则说明数据库中存在死锁。


接下来说明一下会话的状态:
1.active 处于此状态的会话,表示正在执行,处于活动状态。
2.killed 处于此状态的会话,表示出现了错误,正在回滚,当然,也是占用系统资源的。还有一点就是,killed的状态一般会持续较长时间,而且用windows下 的工具pl/sql developer来kill掉,是不管用的,要用命令:alter system kill session 'sid,serial#' ;
3.inactive 处于此状态的会话表示不是正在执行的,比如select语句已经完成。我一开始以为,只要是inactive状态的会话,就是该杀,为什么不释放呢。其 实,inactive对数据库本身没有什么影响,但是如果程序没有及时commit,那么就会造成占用过多会话。解决inactive的方法最好的就是在 oracle中直接设置超时时间,也是有两种方法,区别暂时还不清楚:

1.修改sqlnet.ora文件,新增expire_time=x(单位是分钟)  
我的sqlnet.ora位置在D:\oracle\ora92\network\admin

2.通过ALTER PROFILE DEFAULT LIMIT IDLE_TIME 10; 命令修改,记得重启下oracle。

===============

另外一种解决方法:

select A.SID,B.SPID,A.SERIAL#,a.lockwait,A.USERNAME,A.OSUSER,a.logon_time,a.last_call_et/3600 LAST_HOUR,A.STATUS,
'orakill '||sid||' '||spid HOST_COMMAND,
'alter system kill session '''||A.sid||','||A.SERIAL#||'''' SQL_COMMAND
from v$session A,V$PROCESS B where A.PADDR=B.ADDR AND SID>6

================

一个自动杀 的job
CREATE OR REPLACE PROCEDURE "KILL_SESSION" AS
        v_sid number;
        v_serial number;
                killer varchar2(1000);
        CURSOR cursor_session_info is select sid,serial# from v$session where type!='BACKGROUND' and status='INACTIVE' and last_call_et>2700 and username='ICWEB' and machine='orc';
BEGIN
        open cursor_session_info;
        loop
                fetch cursor_session_info into v_sid,v_serial;
                exit when cursor_session_info%notfound;
                               
                                killer:='alter system disconnect session '''||v_sid||','||v_serial||''' post_transaction immediate';
                                                                execute immediate killer;
                                        end loop;
                dbms_output.PUT_LINE(cursor_session_info%rowcount||' users with idle_time>2700s have been killed!');
                close cursor_session_info;
END;
/

这样做其实还是治标不治本,最好能够解决连接池自动释放idle进程的问题

<think>嗯,用户遇到了Oracle数据库连接数突然增大导致无法连接的问题,我需要帮他们解决这个问题。首先,我得回忆一下相关的解决方案。根据之前的引用内容,比如引用[2]中提到,修改jdbc配置中的数据库连接池最大连接数可能有效,因为当应用服务配置的连接池太大,多个服务同时运行时会占用大量连接,导致总数超过Oracle的processes参数限制。所以首先应该检查应用服务器的连接池配置,看看是否有不合理的设置。 然后,用户可能需要检查数据库当前的连接数配置的最大连接数。通过执行`show parameter processes`可以查看processes的值,而`select count(*) from v$process`可以查看当前占用的进程数。如果占用数接近或达到最大值,说明确实存在连接数过多的问题。这时候需要找到占用连接的原因,比如是否有未释放的空闲会话,或者某些应用没有正确关闭连接。 另外,引用[3][4]提到了Oracle的连接释放机制。可能需要设置会话的超时时间,比如SQLNET.EXPIRE_TIME,来自动断开不活动的连接,防止它们长时间占用资源。同时,检查数据库中的profile设置,限制IDLE_TIME,这样长时间空闲的会话会被自动终止。 还有,用户可能需要优化应用逻辑,比如使用连接池时确保连接在使用后正确释放,避免连接泄露。此外,如果有多个服务连接到同一个数据库,适当减少每个服务的连接池大小,总就不会超过数据库的限制。 最后,如果临时需要快速释放连接,可以手动kill掉一些不活跃的会话,但这只是应急措施,长期还需要从配置代码层面解决问题。可能还需要调整Oracle的processessessions参数,但这需要谨慎操作,避免影响数据库稳定性。 总结下来,解决方案应该分步骤进行:检查当前连接情况,调整应用配置,设置超时参数,优化代码,以及必要时调整数据库参数。需要确保用户按照这些步骤逐步排查解决问题,避免遗漏关键点。</think>### Oracle数据库连接数突增导致无法连接的解决方案 #### 一、排查当前连接状态 1. **查看数据库连接配置** ```sql show parameter processes; -- 最大进程数 show parameter sessions; -- 最大会话数 ``` 若`processes`值过低(如默认150),需调整参数[^2]。 2. **实时监控连接占用** ```sql select count(*) from v$process; -- 当前进程数 select sid, serial#, username, status from v$session where status='INACTIVE'; -- 查看空闲会话 ``` 若发现`INACTIVE`会话过多,可能是连接未释放导致资源耗尽[^3]。 #### 二、紧急处理措施 1. **手动释放空闲连接** ```sql alter system kill session 'sid,serial#'; -- 强制终止指定会话 ``` 2. **重启占用过高的服务** 如引用[2]案例,临时停止部分应用服务可快速释放连接池资源。 #### 三、根本性优化 1. **调整数据库参数** ```sql alter system set processes=1000 scope=spfile; -- 根据硬件配置调整上限 alter system set sessions=1105 scope=spfile; -- sessions = 1.1 * processes + 5 ``` 修改后需重启数据库生效。 2. **配置连接超时机制** 修改`sqlnet.ora`文件: ``` SQLNET.EXPIRE_TIME=10 -- 每隔10分钟检测空闲连接 ``` 并设置用户PROFILE限制空闲时间: ```sql alter profile default limit idle_time 30; -- 30分钟无操作自动断开 ``` 3. **优化应用连接池** - JDBC配置示例(Tomcat): ```xml <Resource name="jdbc/oracleDS" maxTotal="20" -- 最大连接数 minIdle="5" testOnBorrow="true" validationQuery="SELECT 1 FROM DUAL"/> ``` 多服务部署时需控制各服务连接池总不超过数据库限制[^2]。 #### 四、长期监控 ```sql -- 创建监控视图 create view conn_usage as select resource_name, current_utilization, max_utilization from v$resource_limit where resource_name in ('processes','sessions'); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啊_sdf12

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值