暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle Getting ora-00054 when I truncate a table

DB小榴莲 2019-07-22
2088

SQL> truncate table sys.login_log;

truncate table sys.login_log

                   *

ERROR at line 1:

ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

 


Why am I getting ora-00054 error when I truncate a table?

 

The table i truncate is login_log,which record the information of each session connect to database.for example, session A connect to database, the table login_log should be updated.


So,when I was trying to truncate login_log,it was already locked by some session or some query by "select for update" and have not yet committed/rollbacked. 

 


Why the ddl operation have to wait the dml lock?

 


oracle said that "DDL_LOCK_TIMEOUT specifies a time limit for how long DDL statements will wait in a DML lock queue. The default value of zero indicates a status of NOWAIT. The maximum value of 1,000,000 seconds will result in the DDL statement waiting forever to acquire a DML lock.


If a lock is not acquired before the timeout period expires, then an error is returned.

"



What can we do?

 

Look up the sql,username,machine,port information and get to the actual process which holds the connection, and then kill them.


SELECT O.OBJECT_NAME, 

S.SID, 

S.SERIAL#, 

P.SPID, 

S.PROGRAM,

S.USERNAME,

S.MACHINE,

S.PORT,

S.LOGON_TIME,

SQ.SQL_FULLTEXT 

FROM V$LOCKED_OBJECT L, DBA_OBJECTS O, V$SESSION S, 

V$PROCESS P, V$SQL SQ 

WHERE L.OBJECT_ID = O.OBJECT_ID 

AND L.SESSION_ID = S.SID AND S.PADDR = P.ADDR 

AND S.SQL_ADDRESS = SQ.ADDRESS;

 

Maybe you are going to wait some minutes, The session that was killed was in the middle of a transaction and updated lots of records. These records have to be rollbacked and some background process is taking care of that. 


Another word,When you killed the session, the session hangs around for a while in "KILLED" status while oracle cleans up after it. 


If urgent,you can also kill the os process as well (look up the process id from v$process.spid), which would release any locks it was holding on to. 


From the internet,i find a script that could take this error just one step


BEGIN FOR 

C IN (SELECT S.SID SID, S.SERIAL# SERIAL FROM V$LOCKED_OBJECT L, V$SESSION S WHERE L.SESSION_ID = S.SID) 

LOOP    

EXECUTE IMMEDIATE ('ALTER SYSTEM KILL SESSION ''' || C.SID || ',' || C.SERIAL || ''''); 

END LOOP; 

END;

最后修改时间:2021-06-23 11:11:06
文章转载自DB小榴莲,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论