今天检查到一个奇怪的现场,Oracle存储过程执行时间过长,已经执行了2天,还在运行,这明显是不正常的。
把这次检查的经过记录,方便以后查看
1. 查询更在运行的Job
Select * From DBA_JOBS_RUNNING
发现 job:1542,sid:1352 从2018年3月30日,跑到至今(2018年4月3日)都未结束.
2.查询job执行的存储过程
Select * From DBA_JOBS where job = 1542
通过what字段,发现JOB1542,执行的存储过程为: pack_jigl_interface.auto_main_call(sysdate-1);
auto_main_call里面调用了4个过程,通过日志发现正在执行 PROC_E_MP_POWER_CURVE 过程.
3.查询有没有表死锁影响了过程执行
Select Distinct
b.owner, b.object_name ,
c.username,
a.Session_id,
c.serial#, c.status, pro.spid, d.job, e.what, c.Prev_exec_start,
a.Locked_mode, Round( (sysdate - c.Prev_exec_start)*24*60) DiffMinutes,
l.type, l.ctime , area.SQL_TEXT
From
v$locked_object a
join v$dba_objects b on a.object_id = b.object_id
join v$session c on a.session_id = c.SID
join v$lock l on a.Locked_mode = l.Lmode and l.SID = c.SID and l.type in ('TX','TM')
left join v$sqlarea area on c.SQL_HASH_VALUE = area.HASH_VALUE
left join v$process pro on pro.addr = c.paddr
left join v$dba_jobs_running d on d.sid = a.session_id and d.sid = c.sid
left join v$dba_jobs e on d.job = e.job
order by SESSION_ID;
没有发现过程中的表有死锁.
4.通过SID查找存储过程现在正在执行哪条语句
--通过sid,找到sql_id(sid通过上面的DBA_JOBS_RUNNING查到的)
Select SID,SQL_ID from V$SESSION where SID = 1352
--检查执行计划
Select * from V$SESSION_LONGOPS where SID = 1352 and sql_id = 'fjqaw14x82qba'
--检查正在执行的SQL
Select * from V$sql where sql_id = 'fjqaw14x82qba'
卡住的语句为使用表A向dblink的表B插入数据.
经过分析,有2种情况导致
1. DBLink的数据库有死锁.我方一直等待
2. 网络原因,断断续续连接DBLink
最后具体什么原因没找出来.使用
ALTER SYSTEM KILL SESSION 'SID,SERIAL#' IMMEDIATE
结束了进程.
另,https://www.cnblogs.com/harvey888/p/6710902.html 有一篇类似的文章,写得很好,复制过来,方便以后查阅:
1:查V$DB_OBJECT_CACHE
SELECT * FROM V$DB_OBJECT_CACHE WHERE name='CUX_OE_ORDER_RPT_PKG' AND LOCKS!='0';
注意:CUX_OE_ORDER_RPT_PKG 为存储过程的名称。
发现 locks=2
2:按对象查出sid的值
select /*+ rule*/ SID from V$ACCESS WHERE object='CUX_OE_ORDER_RPT_PKG';
注意:CUX_OE_ORDER_RPT_PKG 为存储过程的名称。
3:查sid,serial#
SELECT SID,SERIAL#,PADDR FROM V$SESSION WHERE SID='刚才查到的SID';
4、根据会话id(sid),此会话的等待事件:
- select * from v$session where sid=***;
event字段即为等待事件。查询后我们发现这个会话等待事件为SQL*Net message from dblink;在查看会话的logon_time为两天前。这个时间远超过我们估计时间。
5、根据会话id查看此会话正在执行的sql语句
- select sql_text from v$sqlarea where address= (select sql_address from v$session where sid=***);
查询后发现正在执行的sql语句为通过dblink到远程数据库上A表查询数据,插入到B表。
6、连接远程数据库,查询当前被锁的对象
- select * from v$locked_object lo ,
- all_objects ao where lo.OBJECT_ID= ao.object_id ;
查看后发现远程数据库中并没有涉及到A、B表被锁
7、查看远程数据的会话:
- select * from v$session where terminal like '%机器名%' and program='Oracle.exe'
使用dblink连接远程数据库,在远程数据库上的会话的program应该是是oracle.exe
查询后发现,两个远程库有时候根本没有相关会话,有时候可能有相关会话,但其等待事件是 SQL*Net message from client 远程库在等待本地Oracle给他发请求。
本地库等dblink远程库,远程库等待client消息。看来这个存储过程是不可能执行完了。
具体什么原因造成了,还不清楚。
---------------------------------------------------------------------------------------------------------------------------------