数据库连接数问题处理

来源:互联网 发布:嵌入式linux怎么学 编辑:程序博客网 时间:2024/06/11 11:14


 

 

1.     提示process 数过大,当前的进程连接数超过数据库的最大阀值(本为350),导致报警;时间过长错误号码记不清了

 

处理过程

1.Select  count(*)  from  V$session;

2.Select  count(*) from V$prosess;

3. SQL> show parameter process

 

NAME                                 TYPE        VALUE

----------------------------------------------- ------------------------------

aq_tm_processes                      integer     0

db_writer_processes                   integer    1

gcs_server_processes                  integer    0

job_queue_processes                       integer     20

log_archive_max_processes             integer    10

processes                                            integer     400

 

查询数据库当前的session 数和数据库最高时的session

SQL> select SESSIONS_MAX ,SESSIONS_WARNING,SESSIONS_CURRENT,SESSIONS_HIGHWATER , USERS_MAX from V$license;

 

SESSIONS_MAX SESSIONS_WARNING SESSIONS_CURRENT SESSIONS_HIGHWATER  USERS_MAX

------------ ---------------- ----------------------------------

           0                0            232              361         

 

[oracle@ora2~]$  ps -ef | grep LACAL=NO|wc –l 

1

[oracle@ora2~]$  ps -ef |grep ora_|wc -l

17

数据库的当前的process 数= ps -ef | grep LACAL=NO|wc –l+ ps -ef | grep ora_|wc -l

sessions = processes *1.1 +5

 

 

查询那些应用的连接数此时是多少



SQL>  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;

   

 

 

 

 

 

 

手动杀掉INACTIVR进程(但是这种kill方式并没有完全释放资源)

ALTER SYSTEM KILL SESSION方式,会话的状态也只会变成SNIPPED而不会释放,需要在数据库主机上用KILL方式杀掉对应的进程。(kill  -9 spid)

 

SELECT'alter system kill session '''||s.sid||','||s.serial#||''';','execsys.kill_session('||s.sid||','||s.serial#||');'
 FROM v$session s
 WHERE s.USERNAME='SCOTT' AND S.STATUS='INACTIVE';

 

SELECT 'alter system kill session'''||s.sid||','||s.serial#||''';','exec sys.kill_session('||s.sid||','||s.serial#||');'
 FROM v$session s;

 

 

常用的脚本:

*********************************查询session信息以及process信息*********************************

--根据username查询sid和后台spid

selecta.username,a.sid,a.serial#,b.spid,a.STATUS,a.OSUSER,a.MACHINE,a.PROGRAM fromv$session a,v$process b where a.PADDR=b.ADDR and

a.username=&USERNAME;

 

--根据后台spid查询sid

select username,sid,serial#,STATUS,OSUSER,MACHINE,PROGRAM from v$session where paddr = (select addr from v$process where spid = 9848);

 

--根据sid查询后台spid

select spid from v$process where addr = (select paddrfrom v$session where sid = &SID);

 

--查询自己session的后台spid

selecta.username,a.sid,a.serial#,b.spid,a.STATUS,a.OSUSER,a.MACHINE,a.PROGRAM fromv$session a,v$process b where a.PADDR=b.ADDR and

a.sid=(select distinct sid from v$mystat);

 

 

 

set line 132

col program for a20

col TERMINAL for a10

SELECT 

   P.PID,P.SPID,P.USERNAME,P.TERMINAL,

  P.PROGRAM,P.BACKGROUND,P.PGA_ALLOC_MEM ALLOCPGA,

   P.PGA_USED_MEMUSEDPGA,P.PGA_MAX_MEM MAXPGA

  FROM V$PROCESS P

  WHERE NOT EXISTS(SELECT 'X ' FROM 

    V$SESSION WHEREPADDR = P.ADDR AND STATUS <> 'KILLED')

    AND P.PID<> 1;

 

conn scott/tiger

 

查看scott用户的sid,serial# 序列号

SQL> select sid,serial# from V$session whereusername='SCOTT';

 

       SID    SERIAL#

---------- ----------

       204        157

 

SQL> alter system kill session '204,157';

 

System altered.

 

查看status 为inactive  的相关信息

set  line 132

set  pagesize 9999

col  OSUSER   for a13

col  PROGRAM  for a25

col  MACHINE  for a15

col  username fora10

selecta.username,a.sid,a.serial#,b.spid,a.STATUS,a.OSUSER,a.MACHINE,a.PROGRAM fromv$session a,v$process b where a.PADDR=b.ADDR;

 

 

 

参考资料

http://www.cnblogs.com/chinhr/archive/2009/12/02/1615071.html

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

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

1.select count(*) from v$session;
  select count(*) fromv$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.PROGRAMorder 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。

 

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

另外一种解决方法:

selectA.SID,B.SPID,A.SERIAL#,a.lockwait,A.USERNAME,A.OSUSER,a.logon_time,a.last_call_et/3600LAST_HOUR,A.STATUS,
'orakill '||sid||' '||spidHOST_COMMAND,
'alter system kill session'''||A.sid||','||A.SERIAL#||'''' SQL_COMMAND
from v$session A,V$PROCESS Bwhere 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 selectsid,serial# from v$session where type!='BACKGROUND' and status='INACTIVE' andlast_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_transactionimmediate';
                                                               execute immediate killer;
                                       end loop;
               dbms_output.PUT_LINE(cursor_session_info%rowcount||' users withidle_time>2700s have been killed!');
               close cursor_session_info;
END;
/

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

 

 

 

 

 

 

 

 

原创粉丝点击