oracle中job长时间执行没有结束

一些项目中使用了job定期执行sql语句。如果要执行的sql语句是基于dblink对远程数据库的访问,那么有时候就会出现该sql语句长时间执行一直不结束的情况。并且这时在远程数据库上并没有锁导致该sql语句等待(这可能是由于网络问题触发的oracle的一个bug吧,远程数据库与本地数据之间有防火墙时比较容易出现这个现象)。

下面总结了如何判断该job是否长时间执行没结束,并说明了处理步骤。


1)、观察job情况。
   system用户下执行语句select * from  dba_jobs;找到有问题的job,记录下该job在查询结果中job列的取值,该取值称为job号。
   broken字段为N,且this_date字段的时间比当前时间减去执行周期要晚(根据interval字段判断),则job是正常的。如果this_date字段没有值,一般认为job当前没有在执行。
   如果broken字段N,并且this_date时间不对(例如是几个小时以前,甚至几天以前),则说明该job某一次周期一直没有执行完。
   如果出现这种现象,就说明该job可能出问题了。
     
2)、查找该job目前正在执行时的会话编号sid
   select * from  dba_jobs_running where job='刚才查到的job号';
   在返回结果中记录sid列的取值

3)、查看该会话
   select * from v$session where sid='刚才查到的sid'
   记录下返回结果的 serial#列(会话序列号),paddr列(线程地址)

4)、 取得会话的线程号
select spid from  v$process  where   addr='刚才查到的线程地址' ;
记录下列spid,称为线程号

5)、使用oracle命令杀会话
     alter system kill session '会话编号sid,会话序列号serial#';

6)、查看是否成功杀掉该会话(方法与步骤一相同,多执行几次select * from  dba_jobs;观察结果)

7)、如果没有杀掉会话,就是用操作系统命令杀线程(或进程)
    这里给出windows下杀oracle会话占用的线程的方法  
    登录到数据库所在的操作系统中,打开windows命令行,键入命令:  orakill 数据库sid  刚才查到的线程号spid

   例如 orakill orcl  12345

 

 

这里给出一个自动清理问题job的存储过程,由于是存储过程,只能使用alter system kill 来杀会话,有时候会话只被标记为killed,并不能真正结束,job也无法启动下一个周期。

 

CREATE OR REPLACE PROCEDURE SYS.PRO_KILL_JOB AS
  /*清理job567 568 569 长期执行不结束的情况*/
  /*30分钟超时*/
 CURSOR   MYCUR     IS 
   select     ' ALTER SYSTEM KILL SESSION '''||s.sid ||','||  s.SERIAL#||''' immediate '   AS SQL_KILL   , J.JOB
      from dba_jobs_running j,v$session s  
      where   j.sid=s.sid and
       this_date <(sysdate-30/24/60) and 
       s.sid is not null and s.serial# is not null 
       and 
       ( j.job= 567 
         or j.job=568 
         or j.job=569  ) ;

  V_SQL_KILL  VARCHAR2(500);
  V_JOB NUMBER ;


BEGIN
   OPEN MYCUR;
  LOOP
    FETCH MYCUR
      INTO V_SQL_KILL , V_JOB;
    EXIT WHEN MYCUR%NOTFOUND;
    dbms_output.put_line(v_sql_kill);
    execute immediate  v_sql_kill ;
    COMMUNICATION.SP_DB_LOG('PRO_KILL_JOB', 1, NULL, V_JOB||' IS KILLED');
    COMMIT;
  END LOOP;
  CLOSE MYCUR;
EXCEPTION
  WHEN OTHERS THEN
    COMMUNICATION.SP_DB_LOG('PRO_KILL_JOB', 1, SQLCODE, SQLERRM);
    COMMIT;
END PRO_KILL_JOB;


 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值