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

转载于:https://www.cnblogs.com/littleCode/p/4193454.html

ORACLE定期清理INACTIVE会话相关推荐

  1. 【DBA笔记2】Oracle之定期清理inactive会话

    目录 背景 例子 1.超60秒会话 2.建存储过程 2.1.直接kill 2.2.完成当前事务后kill 背景 ORACLE数据库会话有ACTIVE.INACTIVE.KILLED. CACHED.S ...

  2. oracle锁表会话超时时间,ORACLE快速彻底Kill掉的会话,防止锁表

    ORACLE快速彻底Kill掉的会话,防止锁表 2020-05-30 编程之家收集整理的这篇文章主要介绍了ORACLE快速彻底Kill掉的会话,防止锁表,编程之家小编觉得挺不错的,现在分享给大家,也给 ...

  3. oracle+锁+杀不死,oracle kill -9 会话

    ORACLE快速彻底Kill掉的会话 - 潇湘隐者 - 博客园 2014年10月19日 在ORACLE数据库当中,有时候会使用ALTER SYSTEM KILL SESSION 'sid,serial ...

  4. oracle平均活动会话数,Oracle11g r2的活动会话数问题解决

    如果你在Oracle11g r2的活动会话数的实际操作中,你对Oracle11g r2的活动会话数有不解之处时,你可以通过以下的文章对其的实际应用与功能有所了解,以下是文章的具体介绍,望你浏览完以下的 ...

  5. Oracle:select 或 inactive 会话语句产生锁?

    最近发生的几起 enq: TX - row lock contention 等待事件很怪,通过 blocking session id 查看,不是语句是 select,就是会话是 inactive 的 ...

  6. oracle最大空闲时间,使用Oracle PROFILE控制会话空闲时间

    Oracle推荐PROFILE和SQLNET.EXPIRE_TIME一起使用,但由于PL/SQL工具本身的特点,它会在SESSION的状态变成SNIPED(PROFILE IDLE_TI 客户想实现对 ...

  7. MySQL空闲会话_使用Oracle PROFILE控制会话空闲时间

    Oracle推荐PROFILE和SQLNET.EXPIRE_TIME一起使用,但由于PL/SQL工具本身的特点,它会在SESSION的状态变成SNIPED(PROFILE IDLE_TI 客户想实现对 ...

  8. 查看oracle会话空闲时间,使用Oracle PROFILE控制会话空闲时间

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

  9. oracle终止用户会话

    1.创建两个测试用户进行实验 执行命令如下: create user test1 identified by 1; create user test2 identified by 1; grant d ...

最新文章

  1. SpringSecurity的简单应用(一)
  2. Linux同步自己的配置,Linux学习心得之——Rsync同步配置
  3. Spring OXM-XStream快速入门
  4. 24-Thief小偷-Crime犯罪
  5. [云炬创业基础笔记]第一章创业环境测试6
  6. Ant-Design-Vue和Icon按需加载方案 - JeecgBoot实战
  7. 【小程序】当前“页面B”动态更改title,点击返回按钮,更改的标题会显示在“来源页面A”...
  8. 疫情之后,人工智能该如何走?
  9. c语言课程主要目的和内容,C语言程序设计课程教学大纲
  10. 小网站静态资源CDN加速实践记录
  11. mysql数据库更新数据库语句_MySQL数据库之UPDATE更新语句精解
  12. Kubernetes网络flannel之host-gw模式分析
  13. pytorch例子学习——NEURAL TRANSFER USING PYTORCH神经迁移
  14. 百练_2801:填词
  15. vnc连接linux使用教程_远程管理之VNC 详解
  16. 外包 | LBP/HOG/CNN 实现对 CK/jaffe/fer2013 人脸表情数据集分类
  17. ArangoDB AQL中的图形绘制遍历
  18. nacos注册成功但是服务管理界面没有内容
  19. matlab绘制散点拟合图
  20. Tensorflow创建循环神经网络

热门文章

  1. 想问问你们都是什么时候考驾照的?
  2. 路由器太远手机接收不到信号怎么办
  3. 为什么你说的话别人不愿意听?
  4. 搭建私域流量池实施落地——四大运营步骤
  5. 做业务千万不要把鸡蛋放在一个篮子里
  6. 为什么好多人都要给Typec叫华为充电线?
  7. 学校如何把表格里的成绩,让学生以二维码的方式去扫描查询呢?
  8. 如何用MobaXterm查看日志信息以及xml
  9. Qt4_中央窗口部件
  10. Sentinel总结(个人笔记)