ORA-00054 错误原因分析

时间:2024-03-31 18:30:04

在检查数据库的时候,发现有个job 出错,提示ORA-00054错误。看到这个错误,初步猜测是当Job执行DDL操作的时候,刚好有其他sesion对该表进行DML操作(未提交),导致锁存在,导致后续的DML操作失败。

下面来模拟下该错误

在session1中,对表进行插入数据,但是并不commit

[email protected]>desc trunc
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 A                                                  DATE

[email protected]>select * from trunc;

no rows selected

[email protected]>insert into trunc values(sysdate);

1 row created.

[email protected]>
[email protected]>select sid from v$mystat where rownum<2;

       SID
----------
        17

[email protected]>

在session 2 中,对表进行truncate ,这个时候,就会提示ORA-00054错误

[email protected]>truncate table trunc;
truncate table trunc
               *
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired


[email protected]>
[email protected]>select sid from v$mystat where rownum<2;

       SID
----------
        21

[email protected]>

接下来,分析实际的环境。

实际的环境中,Job是对一个表进行truncate,该JOb是在22:00运行的,在alert log中提示是22:03发现的错误

execute immediate 'truncate table XXX_SORT_INFO_HISTORY';

查看v$active_session_history视图 ,发现在22:03分有两个动作,一个是delete,一个是insert,对应的sqlid是atug58q7k54vc,gmzcp4fkm9tkc,

ORA-00054 错误原因分析

查看这个gmzcp4fkm9tkc这个sqlid对应的sql ,是一个存储过程XXX_sort_h_insert

ORA-00054 错误原因分析

查看这个存储过程,可以发现这个存储过程是对表XXX_sort_info_history进行插入

ORA-00054 错误原因分析

到此,这个问题应该清楚了。Job要truncate表的时候,正好有程序对该表进行insert操作,可能没有insert完毕,导致阻塞了truncate动作。

 

END。