Oracle
 sql >> Datenbank >  >> RDS >> Oracle

ORA-00054:Ressource ausgelastet und erwerben mit angegebenem NOWAIT

ORA-00054:Ressource ausgelastet und Erwerb mit angegebenem NOWAIT ist ein häufiger Fehler in Oracle Database

Referenz: Oracle-Dokumentation

Dies passiert im Allgemeinen, wenn Sie versuchen, eine DDL für die Tabelle auszuführen, die durch eine Transaktion gesperrt ist. Es passiert auch, wenn die select for update-Anweisung mit der NOWAIT-Option ausgeführt wird

Beispiel

SQL> alter table emp add (middlename varchar2(15));
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified

SQL> create index  emp_idx on emp(emp_no);

*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified

SQL> Select * from emp for update NOWAIT;

*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified

So verhindern Sie den ORA-00054-Fehler

1. Führen Sie die DDL im Wartungsfenster oder außerhalb der Stoßzeiten durch, wenn keine Transaktionen stattfinden

2.  Bei 11g haben wir DDL_LOCK_TIMEOUT,

Geben Sie einfach an, wie lange auf die DDL-Sperre gewartet werden soll

SQL> alter session set ddl_lock_timeout = 600;
Session altered.

SQL> alter table emp add (middlename varchar2(15));

Table Altered

3.  Wir können die Transaktion beenden, die die Orakelsperren enthält, und dann damit fortfahren

column sid_ser format a12 heading 'session,|serial#'; 
column username format a12 heading 'os user/|db user'; 
column process format a9 heading 'os|process'; 
column spid format a7 heading 'trace|number'; 
column owner_object format a35 heading 'owner.object'; 
column locked_mode format a13 heading 'locked|mode'; 
column status format a8 heading 'status'; 
select 
    substr(to_char(l.session_id)||','||to_char(s.serial#),1,12) sid_ser, 
    substr(l.os_user_name||'/'||l.oracle_username,1,12) username, 
    l.process, 
    p.spid, 
    substr(o.owner||'.'||o.object_name,1,35) owner_object, 
    decode(l.locked_mode, 
             1,'No Lock', 
             2,'Row Share', 
             3,'Row Exclusive', 
             4,'Share', 
             5,'Share Row Excl', 
             6,'Exclusive',null) locked_mode, 
    substr(s.status,1,8) status 
from 
    v$locked_object l, 
    all_objects     o, 
    v$session       s, 
    v$process       p 
where 
    l.object_id = o.object_id 
and l.session_id = s.sid 
and s.paddr      = p.addr 
and s.status != 'KILLED'
/

Sobald Sie die blockierende Sitzung gefunden und sich entschieden haben, die Oracle-Sitzung zu beenden, können wir die folgende Abfrage verwenden, um die Kill-Session-SQL zu generieren

select 'alter system kill session '''||sid||','||serial#||''';' from v$session where sid=&1;

4.Wenn Sie ORA-00054:Ressource ausgelastet und erwerben mit angegebenem NOWAIT erhalten im Bewerbungsformular, dann gehen Sie wie folgt vor

Wir haben einen Fall, in dem wir auf ORA-00054 stoßen:Ressource ausgelastet und erwerben mit NOWAIT, das im Antragsformular angegeben ist. In diesem Fall wird es jetzt sehr schwierig, die Sperren zu finden, da die Anwendung nicht auf die Sperre wartet. Dies geschieht im Allgemeinen, wenn Anwendungsprobleme die Aktualisierung ohne Warteoption auswählen. Wir können Sperren über dba_waiters finden, wenn die Sitzung auf die Sperre wartet. Da sie mit nowait session gesperrt wird, können wir sie nicht einfach finden.

Wir müssen den Oracle-SQL-Trace für die Sitzung finden und das Problem reproduzieren. Sobald die Ablaufverfolgung verfügbar ist. Wir müssen in der Trace-Datei nach err=54 suchen

PARSING IN CURSOR #18446744071497070208 len=167 dep=1 uid=173 oct=3 lid=173 tim=3315832569154 hv=817497356 ad='31afc8bcd0' sqlid='6gvfwr8sbn18c'
SELECT GROUP_MARK_ID FROM MTL_INV_SERIAL_NUMBERS WHERE CURRENT_ORGANIZATION_ID = :B3 AND INVENTORY_ITEM_ID = :B2 AND SERIAL_NUMBER = :B1 FOR UPDATE OF GROUP_MARK_ID NOWAIT
END OF STMT
PARSE #18446744071497070208:c=53,e=52,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=1,plh=1906360410,tim=3315832569152
BINDS #18446744071497070208:
Bind#0
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1206001 frm=00 csi=00 siz=80 off=0
kxsbbbfp=ffffffff7c203028 bln=22  avl=03  flg=05
value=23
Bind#1
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1206001 frm=00 csi=00 siz=0 off=24
xsbbbfp=ffffffff7c203040 bln=22  avl=05  flg=01
value=11111
Bind#2
oacdty=01 mxl=32(30) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1206001 frm=01 csi=871 siz=0 off=48
kxsbbbfp=ffffffff7c203058 bln=32  avl=08  flg=01
value="1222333"
EXEC #18446744071497070208:c=1167,e=1167,p=0,cr=9,cu=1,mis=0,r=0,dep=1,og=1,plh=1906360410,tim=3315832570599
ERROR #18446744071497070208:err=54 tim=3315832570735
STAT #18446744071497070208 id=1 cnt=0 pid=0 pos=1 obj=0 op='FOR UPDATE  (cr=0 pr=0 pw=0 time=0 us)'

Die Zeile, die den Fehler anzeigt, und der Abschnitt darüber zeigt die Anweisung, die den Fehler ausgibt

SELECT GROUP_MARK_ID FROM MTL_INV_SERIAL_NUMBERS WHERE CURRENT_ORGANIZATION_ID = :B3 AND INVENTORY_ITEM_ID = :B2 AND SERIAL_NUMBER = :B1 FOR UPDATE OF GROUP_MARK_ID NOWAIT

Um nun die blockierende Sitzung zu finden, müssen wir die Anweisung in sqlplus mit der NOWAIT-Option

auslösen
SELECT GROUP_MARK_ID FROM MTL_INV_SERIAL_NUMBERS WHERE CURRENT_ORGANIZATION_ID = :B3 AND INVENTORY_ITEM_ID = :B2 AND SERIAL_NUMBER = :B1 FOR UPDATE OF GROUP_MARK_ID ;

Dann wartet diese Sitzung und wir können die blockierende Sitzung leicht von dba_waiters finden und die blockierende Sitzung beenden.

5. Mit Oracle 11g und Oracle 12c haben wir viele DDL-Aktivitäten, die online ohne Unterbrechung des Fehlers ORA-00054 durchgeführt werden können

SQL> create index  emp_idx on emp(emp_no) online;

Ab 12c können Sie das Schlüsselwort ONLINE mit den Befehlen DROP INDEX, DROP CONSTRAINT, ALTER INDEX UNUSABLE und SET COLUMN UNUSED verwenden

Verwandte Artikel

ORA-00942 Tabelle oder Ansicht existiert nicht
ORA-28000 Das Konto ist gesperrt
ORA-28002
ORA-00904:Ungültige Kennung
ORA-01017:Ungültiger Benutzername/Passwort; Anmeldung verweigert
System-Kill-Session ändern