源地址:http://www.cnblogs.com/kerrycode/p/3636992.html

ORACLE数据库会话有ACTIVE、INACTIVE、KILLED、 CACHED、SNIPED五种状态。INACTIVE状态的会话表示此会话处于非活动、空闲、等待状态。例如PL/SQL Developer连接到数据库,执行一条SQL语句后,如果不继续执行SQL语句,那么此会话就处于INACTIVE状态。一般情况下,少量的INACTVIE会话对数据库并没有什么影响,如果由于程序设计等某些原因导致数据库出现大量的会话长时间处于INACTIVE状态,那么将会导致大量的系统资源被消耗,造成会话数超过系统session的最大值,出现ORA-00018:maximum number of sessions exceeded错误。

有时候需要清理那些长时间处于INACTIVE状态的会话。人为定期检查、杀掉这类会话肯定不太现实,要定期清理那些长时间处于INACTIVE的会话,只能通过作业来实现;另外需要注意,Kill掉这些会话需要需要谨慎,稍不注意,就有可能误杀了一些正常的会话。那么我们该如何定义这类会话呢?下面是我结合业务规则定义的:

1: 会话的Status必须为INACTIVE,如果会话状态为ACTIVE、KILLED、CACHED、SNIPED状态,不做考虑。

2: 会话必须已经长时间处于INACTIVE状态。例如,处于INACTIVE状态超过了两小时的会话进程,才考虑Kill。这个视具体业务或需求决定,有可能超过半小时就可以杀掉会话进程。至于如何计算处于INACTIVE会话状态的时间,这个可以 通过V$SESSION的LAST_CALL_ET字段来判别,需要查询处于INACTIVE状态两小时或以上的会话,就可以通过查询条件S.LAST_CALL_ET >= 60*60*2实现,当然最好写成 S.LAST_CALL_ET >= 7200

3: 连接到会话的程序。比如,某个特定的应用程序产生的INACTIVE会话才要清理。例如, Toad工具、PL/SQL Developer工具。关于PROGRAM这个需要根据当前项目的具体情况设置,下面仅仅使用TOAD.EXE、W3WP.EXE举例说明。

   1: SELECT SID, SERIAL#,MODULE, STATUS
   2: FROM V$SESSION S
   3: WHERE S.USERNAME IS NOT NULL
   4: AND UPPER(S.PROGRAM) IN ('TOAD.EXE', 'W3WP.EXE')
   5: AND S.LAST_CALL_ET >= 60*60*2
   6: AND S.STATUS = 'INACTIVE'
   7: ORDER BY SID DESC;

如果是RAC环境,那么最好使用下面SQL语句,使用全局视图GV$SESSION。

   1: SELECT SID, SERIAL#, INST_ID, MODULE,STATUS
   2: FROM gv$session S
   3: WHERE S.USERNAME IS NOT NULL
   4: AND UPPER(S.PROGRAM) IN ('TOAD.EXE', 'W3WP.EXE')
   5: AND S.LAST_CALL_ET >= 2 * 60*60
   6: AND S.STATUS = 'INACTIVE'
   7: ORDER BY INST_ID DESC

接下来创建存储过程SYS.DB_KILL_IDLE_CLIENTS. 方便调用该功能执行kill inactive 会话。注意:xxx部分用实际业务的PROGRAM来替代。

   1:  
   2: CREATE OR REPLACE PROCEDURE SYS.DB_KILL_IDLE_CLIENTS AUTHID DEFINER AS
   3:    job_no number;
   4:    num_of_kills number := 0;
   5: BEGIN
   6:  
   7:    FOR REC IN
   8:        (SELECT SID, SERIAL#, INST_ID, MODULE,STATUS
   9:         FROM gv$session S
  10:             WHERE S.USERNAME IS NOT NULL
  11:             AND UPPER(S.PROGRAM) IN ('xxx', 'xxx.EXE')   
  12:                  AND S.LAST_CALL_ET >= 2*60*60                              
  13:             AND S.STATUS= 'INACTIVE'
  14:         ORDER BY INST_ID ASC
  15:             ) LOOP
  16:          ---------------------------------------------------------------------------
  17:          -- kill inactive sessions immediately
  18:          ---------------------------------------------------------------------------
  19:          DBMS_OUTPUT.PUT('LOCAL SID ' || rec.sid || '(' || rec.module || ')');
  20:      execute immediate 'alter system kill session ''' || rec.sid || ', ' ||
  21:                             rec.serial# || '''immediate' ;
  22:      
  23:          DBMS_OUTPUT.PUT_LINE('. killed locally ' || job_no);
  24:          num_of_kills := num_of_kills + 1;
  25:    END LOOP;
  26:    DBMS_OUTPUT.PUT_LINE ('Number of killed xxxx system sessions: ' || num_of_kills);
  27: END DB_KILL_IDLE_CLIENTS;
  28: /

另外,由于kill session是直接将session kill掉,有可能出现导致事物回滚的现象,其实我们可以使用disconnect session完成当前事务并终止session。这种方式比alter system kill session跟安全可靠。

   1: CREATE OR REPLACE PROCEDURE SYS.DB_KILL_IDLE_CLIENTS AUTHID DEFINER AS
   2:    job_no number;
   3:    num_of_kills number := 0;
   4: BEGIN
   5:  
   6:    FOR REC IN
   7:        (SELECT SID, SERIAL#, INST_ID, MODULE,STATUS
   8:         FROM gv$session S
   9:             WHERE S.USERNAME IS NOT NULL
  10:             AND UPPER(S.PROGRAM) IN ('xxxx', 'xxxx')   
  11:                  AND S.LAST_CALL_ET >= 2*60*60                              
  12:             AND S.STATUS<>'KILLED'
  13:         ORDER BY INST_ID ASC
  14:             ) LOOP
  15:          ---------------------------------------------------------------------------
  16:          -- kill inactive sessions immediately
  17:          ---------------------------------------------------------------------------
  18:          DBMS_OUTPUT.PUT('LOCAL SID ' || rec.sid || '(' || rec.module || ')');
  19:          execute immediate 'alter system disconnect session ''' || rec.sid || ', ' ||
  20:                             rec.serial# || '''immediate' ;
  21:  
  22:          DBMS_OUTPUT.PUT_LINE('. killed locally ' || job_no);
  23:          num_of_kills := num_of_kills + 1;
  24:    END LOOP;
  25:    DBMS_OUTPUT.PUT_LINE ('Number of killed system sessions: ' || num_of_kills);
  26: END DB_KILL_IDLE_CLIENTS;
  27: /

然后,我们可以在作业(JOB)或Schedule里面定期调用该存储过程,也可以通过后台作业结合shell脚本实现定期清理空闲会话的功能。例如如下所示。

创建killSession.sh脚本,调用该存储过程SYS.DB_KILL_IDLE_CLIENTS

   1: #!/bin/bash
   2:  
   3:  
   4:  
   5: logfile=/home/oracle/cron/session/log/killSession.log
   6:  
   7: echo " " >> $logfile 2>&1
   8: echo "START ----`date`" >> $logfile 2>&1
   9: sqlplus /nolog <<STATS
  10: connect / as sysdba
  11: exec sys.db_kill_idle_clients;
  12: exit;
  13: STATS
  14:  
  15: echo "END ------`date`" >> $logfile 2>&1

在crontab里面配置后台作业,每隔15分钟运行一次,清理哪些满足条件的空闲会话。

0,15,30,45 * * * * /home/oracle/cron/session/bin/killSession.sh >/dev/null 2>&1

作者:潇湘隐者
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.

【转】ORACLE定期清理INACTIVE会话的更多相关文章

  1. ORACLE定期清理INACTIVE会话

      ORACLE数据库会话有ACTIVE.INACTIVE.KILLED. CACHED.SNIPED五种状态.INACTIVE状态的会话表示此会话处于非活动.空闲.等待状态.例如PL/SQL Dev ...

  2. 数据库会话数量过多,定期清理inactive会话

    1.1现象 存在一套11.2.0.4 RAC 2节点,数据库存在5000个会话数量,其中active正在执行的会话500个,其余均为非活跃会话. 大量inactive会话过多给Oracle数据库带来什 ...

  3. Oracle连接与会话

    连接(connection):连接是从客户端到oracle数据库实例的一条物理路径. 会话(session):会话是数据库实例中存在的一个逻辑实体. case1:一个连接可以有多个会话 SQL> ...

  4. Oracle session inactive状态临时表数据未清空问题

    问题描述:Oracle数据库,java代码使用某数据库实例,获取connection并在使用结束关闭,而session未销毁,而是状态变为inactive从而导致临时表数据未清空. Oracle临时表 ...

  5. 使用Oracle PROFILE控制会话空闲时间

    客户想实现对会话空闲时间的控制,下面是做的一个例子.Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation.保留所有权利 ...

  6. oracle 11G RAC会话故障转移测试

    目前接手的几个项目中,默认使用的oracle RAC数据库服务,均不能实现自动的会话转移,尤其是对于应用的长连接,一旦发生数据库故障,需要重启应用.实际11G具备会话迁移机制,为此做了如下配置测试,供 ...

  7. jdbctemplate 调用oracle 有返回(会话型临时表数据的)结果的存储过程

    注:本文为博主 原创. jdbctemplate 调用oracle存储过程 事务 临时表  有返回结果 1:java 代码 本逻辑代码本是想把 java 代码里的list<Strign>类 ...

  8. 【ORACLE】ORACLE session(会话)管理

    #查看当前不为空的连接select * from v$session where username is not null #查看不同用户的连接数 select username,count(user ...

  9. 如何杀掉(kill)Oracle中的会话(Session)

    Oracle中造成一些表被死锁或者会话异常退出,如执行了更新记录操作后,既没有commit也没有rollback,网络就断开了,也会造表或记录被锁住,待到超时后才会被解开,那样都会造成应用操作被阻塞. ...

随机推荐

  1. iOS 源代码管理工具之SVN

    源代码管理工具之SVN 源代码管理工具SVN是一款非常强大的源代码管理工具,现在国内70%-90%的公司都在使用SVN来管理源代码,下面就让小编给大家着重介绍一下SVN的使用,SVN的使用主要分为下面 ...

  2. 利用html5的画布canvas进行图片压缩处理

    在网上找的代码,按自己的需求改了下,忘记在哪找的了.这里记着方便自己以后学习. // 参数,最大高度 //var MAX_HEIGHT = 100; var MAX_WIDTH = 200; // 渲 ...

  3. maven - 安装与配置

    最近在了解maven的相关东西,在网上查了一些资料,现在简单整理一下. 一.maven 安装 1.先检查JDK ,Maven是一个java工具,所以请确保jdk环境已经正确安装在你的机器上. 2.点击 ...

  4. Android之AnimationDrawable初识

    Drawable animation可以加载Drawable资源实现帧动画.AnimationDrawable是实现Drawable animations的基本类. 这里用AnimationDrawa ...

  5. Flex box弹性布局 及 响应式前端设计的优化

    Flex box弹性布局 Flex box是CSS3新添加的一种模型属性,它的出现有力的打破了我们常常使用的浮动布局.实现垂直等高.水平均分.按比例划分,可以实现许多我们之前做不到的自适应布局.如果你 ...

  6. new date() 在Linux下引起的时间差问题

    java工程部署到Linux时,使用new date()获取的时间出现时间差,通过查阅资料,发现有可能是服务器时间设置问题,JVM问题,jdk问题: 1.服务器时间设置问题: 正确的时间显示 有 CS ...

  7. uva 12169

    /* 巨大的斐波那契数列_________________________________________________________________________________ #inclu ...

  8. cookie的详细解释

    突然看到网页上中英文切换的效果,不明白怎么弄得查了查 查到了cookie 并且附有详细解释 就copy留作 以后温习 http://blog.csdn.net/xidor/article/detail ...

  9. MFC编程 | 非模态对话框的定义

    因为课程需要,会用到MFC编程,所以讲一些经验总结下,以便日后使用查询. // 非模态对话框的定义 // 通过单文档菜单调用一个非模态窗口 1.首先在工程里插入一个对话框(如:IDD_DLG_TEST ...

  10. [原创]cocos2d-x研习录-第三阶 特性之物理引擎

    游戏物理引擎是指在游戏中涉及物理现象的逻辑处理,它用于模拟现实世界的各种物理规律(如赛车碰撞.子弹飞行.物体掉落等),让玩家能够在游戏中有真实的体验. Cocos2D-x中支持Box2D和Chipmu ...