Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1699874
  • 博文数量: 136
  • 博客积分: 10021
  • 博客等级: 上将
  • 技术积分: 3261
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-22 11:26
文章分类

全部博文(136)

文章存档

2010年(1)

2009年(26)

2008年(109)

我的朋友

分类: Oracle

2008-04-14 11:20:55

我们系统中,又产生了一次ORA-04021错误。
 
该错误的产生,一般是在你试图更新一个存储过程的时候。具体现象就是:你试图更新一个存储过程,编译时会一直等待,当超过一定时间后,提示这个错误。
 
Oracle对这个错误的解释如下:
 

ORA-04021 timeout occurred while waiting to lock object stringstringstringstringstring

 

Cause: While waiting to lock a library object, a timeout is occurred.

 

Action: Retry the operation later.

 

这很有可能是因为其他会话在调用该后台包,此时该包在共享池中被锁住。查询v$session_wait时会发现你的会话处于“library cache pin”等待。下面我们先再现一下该错误:

 
session1:创建一个长期执行的过程(死循环),并执行。此时该过程被pinlibrary cache中。

请输入用户名:  yuechaotian/test

 

连接到:

Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production

With the Partitioning, OLAP and Oracle Data Mining options

JServer Release 9.2.0.1.0 - Production

 

SQL> select distinct sid from v$mystat;

 

       SID

----------

        11

 

SQL> CREATE OR REPLACE PROCEDURE prc_test_lock

  2  IS

  3  BEGIN

  4    WHILE TRUE LOOP

  5      NULL;

  6    END LOOP;

  7  END;

  8  /

 

过程已创建。

 

SQL> exec prc_test_lock;

...

--处于死循环中

...

 

session2:修改该过程的定义,则造成会话2处于library cache pin等待

请输入用户名:  yuechaotian/test

 

连接到:

Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production

With the Partitioning, OLAP and Oracle Data Mining options

JServer Release 9.2.0.1.0 - Production

 

SQL> select distinct sid from v$mystat;

 

       SID

----------

        12

 

SQL> CREATE OR REPLACE PROCEDURE prc_test_lock

  2  IS

  3    v_temp VARCHAR2(10);

  4  BEGIN

  5    WHILE TRUE LOOP

  6      NULL;

  7    END LOOP;

  8  END;

  9  /

...

 

-- 处于等待中,一段时间后,出现如下错误:

CREATE OR REPLACE PROCEDURE prc_test_lock
*
ERROR 位于第 1 行:
ORA-04021: 等待锁定对象 TEST.PRC_TEST_LOCK 时发生超时


SQL>

 

 

session3

SQL> conn / as sysdba
已连接。

SQL> select distinct sid from v$mystat;

 

       SID

----------

        19

 

SQL> select EVENT from v$session_wait where sid=12;

 

EVENT             

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

library cache pin  

 
这就需要我们在更新存储过程之前先查询一下,确定没有会话执行该过程。然后再更新。
我们接着在session3中查询(显示结果中的SYS为本次会话,可以排除):
 

SQL> SELECT DISTINCT '(' || s.sid || ')  -  ' || username AS "(session) - username"

  2    FROM V$SESSION s, sys.x$kglob o, sys.x$kglpn p

  3   WHERE upper(o.kglnaobj) LIKE upper('%prc_test_lock%')

  4     AND p.kglpnhdl = o.kglhdadr

  5     AND s.SADDR = p.kglpnuse;

 

(session) - username

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

(11)  -  TEST

(19)  -  SYS

 
这样,我们就知道过程“prc_test_lock”被11号会话调用,此时不能更新该过程。
 
若是由于Oracle的错误造成过程被pin到内存中一直都不能释放,则可以根据上面查询的SID,尝试kill掉11号进程。当然,之前你应该确定11号会话对你的系统来说已经没用了。
 
对于我的测试,当kill掉11号进程后,12号进程就可以更新该存储过程了。而11号进程的界面显示如下:

 

SQL> exec prc_test_lock;

BEGIN prc_test_lock; END;

 

*

ERROR 位于第 1 :

ORA-00028: 您的会话己被删去

 

 

SQL>

 

阅读(4024) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~