问题描述:
        在一些情况下,我们不可以查看修改代码的软件、工程由于一些个别原因,造成oracle 中的 v$session 中的会话数不断地增加,超过了最大连接数  maxsession(具体属性名称我记不清了),这种情况下我们考虑从数据库层面解决问题,之前寻找了一些资料,其中一种是写一个 job +  produce 定时通过alter system kill session "id,seial";清理  inative状态的session,但是被kill的session只是状态会变成 “killed" 而资源并不会释放,状态被kill的session的"addr"信息也会指向一个统一的地址码,如果想要彻底清理掉“killed”状态的session,还需要在操作系统层,执行 C:\>orakill   sid    spid  命令(这里我们假设是windows环境);如果我们希望能够自动按时周期的清理oracle中的Inactive状态的session我们就有两个问题。1、如何实现周期性的清理(比如每天的某个时刻);
2、如何实现自动的进行清理;小弟分数不多,但是相信这个问题不少人都遇到过,大家讨论一下谢谢 各位大牛哥。

解决方案 »

  1.   

    在服务器的sqlnet.ora中设置:sqlnet.expire_time= n
    单位是分钟,要>0。看看效果。
      

  2.   

    试过了 不过好像没有达到预期的效果 status = inactive 的 session数并没有减少。
      

  3.   

    我按照您说的修改了sqlnet.ora 文件中的 sqlnet.expire = 10 我用测试软件,连接数据库,之后模拟无力短网,就像预想的那样session数上升了并且变成了 active 状态,之后我等待了很长时间,这部分会话资源也没有被回收。 高人指条明路吧 
      

  4.   

    你是在服务器端的sqlnet.ora设置的吧?
    你上面说的sqlnet.expire = 10是笔误吧?
    设置后客户端连上数据库后断网,客户端的会话在数据库中仍是active状态?
    -------
    这样的话就奇怪了,你的pmon进程应该是正常的吧?可以在os层面写个脚本定时kill.
      

  5.   

    你是在服务器端的sqlnet.ora设置的吧? 
    答:是
    你上面说的sqlnet.expire = 10是笔误吧?
    答:是  slqnet.expire_time = 10 笔误 嘿嘿。 
    设置后客户端连上数据库后断网,客户端的会话在数据库中仍是active状态?
    答:是inactive 状态 但是 我断网30秒后 ,连上网线 等了很久 会话也没被回收。 
    ------- 
    这样的话就奇怪了,你的pmon进程应该是正常的吧?可以在os层面写个脚本定时kill.我理解是不是必须短网 10分钟以上,会话才会被回收?
      

  6.   

    --作用:建立JOB定期清理KILLED的SESSION
    --注意:此脚本必须以SYS用户授予当前用户select on v_$session权限
    --创建JOB
    DECLARE
    n_job NUMBER;
    BEGIN 
    dbms_job.submit(job => n_job, 
            what => 'BEGIN
                                                        FOR rc IN (SELECT  sid,serial# FROM v$session WHERE status = ''KILLED'') LOOP
                                                            EXECUTE IMMEDIATE ''ALTER SYSTEM KILL SESSION '''':sid,:serial#'''' IMMEDIATE'' USING rc.sid,rc.serial#;
                                                        END LOOP;
                                                    END;',
         next_date =>SYSDATE, --现在开始
                                    INTERVAL => 'SYSDATE+10/(24*3600)'); --每10秒执行一次                               
    COMMIT;                                
    END;
    /
    --移除JOB
    BEGIN
      DBMS_JOB.REMOVE(65);
        COMMIT;
    END;
    /
    --确认是否正常运行
    SELECT last_sec,failures FROM user_jobs WHERE job = 65;
      

  7.   

    您好:
        首先感谢大家对我遇到问题的关注。
    楼上的朋友提出的办法,我尝试过,但是使用这种办法kill  session  session的status 会变成killed状态但是系统的pmon进程并不会立刻将其回收,最终还是会出现  session数量超出上限的问题。
      

  8.   

    那就在os层面写个脚本定时kill你已在数据库中kill过对应session的进程。
      

  9.   


    楼主,请注意是:EXECUTE IMMEDIATE ''ALTER SYSTEM KILL SESSION '''':sid,:serial#'''' IMMEDIATE''
    而不是
    EXECUTE IMMEDIATE ''ALTER SYSTEM KILL SESSION '''':sid,:serial#''''该脚本我测试过的,能正常执行,immediate是立即kill,不会有status 会变成killed状态的,不信的话,你kill immediate,然后去v$session里查,应该不会有记录的。
    另外假如你正在执行一个很大事务的语句,把它KILL,你得给它时间释放相关的资源嘛
      

  10.   

    PS:工作中曾碰到一位开发人员写了一段代码在循环语句里打开了一个游标,结果没正常关闭, 达到参数open_cursors的上限,这个时候kill immediate就派上用场了(不带immediate的kill,session状态只是从inactive状态变成killed状态,并未清理):把那个应用打开的游标全部清理掉(当然后面得把这个程序bug修正)
      

  11.   

    我试了 可以 以前我也写过类似的job但是好像没加 immediate关键字  谢谢 朋友 么么。