Oracle储存过程长时间运行检查

今天检查到一个奇怪的现场,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 有一篇类似的文章,写得很好,复制过来,方便以后查阅:

查看Oracle中存储过程长时间被卡住的原因

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),此会话的等待事件:

  1. select * from v$session where sid=***;  

event字段即为等待事件。查询后我们发现这个会话等待事件为SQL*Net message from dblink;在查看会话的logon_time为两天前。这个时间远超过我们估计时间。

5、根据会话id查看此会话正在执行的sql语句

  1. select sql_text from v$sqlarea where address= (select   sql_address  from v$session where sid=***);  

查询后发现正在执行的sql语句为通过dblink到远程数据库上A表查询数据,插入到B表。

6、连接远程数据库,查询当前被锁的对象

  1. select * from v$locked_object lo ,   
  2. all_objects  ao    where lo.OBJECT_ID= ao.object_id ;  

查看后发现远程数据库中并没有涉及到A、B表被锁

7、查看远程数据的会话:

  1. select * from v$session where terminal like '%机器名%'  and program='Oracle.exe'  

使用dblink连接远程数据库,在远程数据库上的会话的program应该是是oracle.exe

查询后发现,两个远程库有时候根本没有相关会话,有时候可能有相关会话,但其等待事件是 SQL*Net message from client 远程库在等待本地Oracle给他发请求。

 

本地库等dblink远程库,远程库等待client消息。看来这个存储过程是不可能执行完了。

具体什么原因造成了,还不清楚。

---------------------------------------------------------------------------------------------------------------------------------

发布了35 篇原创文章 · 获赞 61 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/woailyoo0000/article/details/79800301