- 现象描述
2017年1月8日,某系统应用人员反映JOB异常,没有正常运行,相关表无数据。
- 问题分析
Job异常通过PL/SQL工具登录数据库, job的登录模式一般为’DBMS_SCHEDULER’,
运行如下语句进行查看。
select S.STATUS,
S.INST_ID,
S.SID,
S.PADDR,
S.SQL_ID,
S.SQL_EXEC_START,
S.ACTION,
S.LAST_CALL_ET,
S.BLOCKING_INSTANCE,
S.BLOCKING_SESSION,
/* S.BLOCKING_SESSION_STATE,*/
S.EVENT,
S.WAIT_CLASS
from gv$session S
where module = 'DBMS_SCHEDULER';
查询到一个被kill的job,状态为killed,并未释放,通过下面的语句查询到spid后,通过登录后台kill -9 的方式杀掉了系统进程。
Select p.spid from v$session s,v$processes p where p.addr=s.paddr and s.sid=508
之后让应用再次发起job,但job依然无法执行,通过后台发现该job发生了等待事件row cache lock,等待会话为1209,P1值为11,通过下面的语句查看无返回结果,不能定位row cache lock发生在哪里
Select * from v$rowcache where cache#=11;
查询1209会话发现为系统后台进程CJQ n, CJQn和Jnnn均为为oracle作业队列进程,后台进程为什么会锁正常的job呢?
应用人员通过PL/SQL提供的JOB任务发现存在如下异常现象,
当前运行很多job,但没有都没有session_id,感觉像是僵尸job,既然无法通过会话杀掉job,我们尝试通过dbms_scheduler包进行停止,但无法停止,而且依然出现了row cache lock事件,依然被1209后台进程锁住。
Row cache lock无法通过P1定位到具体的锁对象,后台进程为什么会锁住job呢,通过上面的结果初步分析是因为之前有很多僵死的job没有被正常停止,导致再次发起同样的job任务或对该job进行处理就会出现锁的情况,而且是被后台进程CJQn锁住。
进一步分析
登录后台通过DEBUG命令收集相关信息分析
- 问题定位
通过相关关键字row cache lock cjq在metlink搜索查看,最终定位到了一个BUG16994952 –Unable to unscheduled propagation due to CJQ self-deadlock/hang。
- 问题处理
Kill the hung CJQ process,杀掉CJQ进程
再次通过dbms_scheduler包进行停止,可以正常停止,依次停止僵死的job后,应用可以再次正常发起job,恢复正常。
按照上面的操作依次停止僵死的job。