Oracle provides various methods for maintaining database tables and indexes. In most cases, the latest versions of Oracle provide syntax for online operations. However, in some cases it is necessary to perform offline maintenance operations that require exclusive access to a table or index. When doing so, an ORA-00054 error could occur.
Consider an example of reorganizing the index HR.EMP_EMP_PK.
In session A, run an active transaction:
update hr.employees set department_id=200 where department_id=100;
We’ll not invoke the commit clause yet.
In session B, run the command to rebuild the index
SQL> alter index hr.emp_emp_id_pk rebuild; alter index hr.emp_emp_id_pk rebuild * ERROR at line 1: ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
An error occured.
How to find the session(s) started a transaction?
We would find object IDs:
SELECT o.object_id FROM dba_objects o, dba_indexes i WHERE o.owner = i.table_owner AND o.object_name = i.table_name AND i.owner = 'HR' AND i.index_name = 'EMP_EMP_ID_PK' UNION ALL SELECT object_id FROM dba_objects WHERE owner = 'HR' AND object_name = 'EMP_EMP_ID_PK'; OBJECT_ID ---------- 81873 81875
Therefore session ID, season serial# and instance number:
SELECT s.inst_id, s.sid, s.serial#, s.username, s.osuser, 'ALTER SYSTEM KILL SESSION ''' || s.sid || ',' || s.serial# || ',@' || s.inst_id || ''';' FROM gv$session s, gv$locked_object lo WHERE s.inst_id = lo.inst_id AND s.sid = lo.session_id AND lo.object_id IN ( 81873, 81875 );
Knowing the attributes of the sessions, we can inform the user who run it or stop these sessions with the SYSDBA rights.