Oracle
 sql >> Baza danych >  >> RDS >> Oracle

ORA-00054:zasób zajęty i pozyskiwanie za pomocą NOWIT określone

ORA-00054:zasoby zajęte i pozyskiwanie z określonym NOWAIT jest częstym błędem występującym w Oracle Database

Odniesienie: dokumentacja Oracle

Zwykle dzieje się tak, gdy próbujesz wykonać DDL na tabeli, która jest zablokowana przez transakcję. Dzieje się tak również, jeśli instrukcja select for update jest wykonywana z opcją NOWAIT

Przykład

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

Jak zapobiec błędowi ORA-00054

1. Wykonaj DDL w oknie konserwacji lub poza godzinami szczytu, gdy nie odbywa się żadna transakcja

2. Przy 11g mamy DDL_LOCK_TIMEOUT,

To po prostu określ, jak długo chcesz czekać na blokadę DDL

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

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

Table Altered

3.  Możemy zabić transakcję, która blokuje blokady Oracle, a następnie kontynuować

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'
/

Po znalezieniu sesji blokującej i podjęciu decyzji o zabiciu sesji oracle, możemy użyć poniższego zapytania, aby wygenerować sesję zabijania sql

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

4. Jeśli otrzymujesz ORA-00054:zajęty zasób i kup z określonym NOWAIT w formularzu zgłoszeniowym, a następnie postępuj jak poniżej

Mamy przypadek, w którym napotykamy ORA-00054:zasób zajęty i pozyskiwanie z NOWAIT określonym w formularzu wniosku. Teraz w tym przypadku znalezienie blokad staje się bardzo trudne, ponieważ aplikacja nie czeka na blokadę. Zwykle dzieje się tak, gdy problemy z aplikacją wybierają aktualizację bez opcji oczekiwania.Możemy znaleźć blokady za pośrednictwem dba_waiters, gdy sesja czeka na blokadę.Ponieważ blokowanie odbywa się za pomocą sesji nowait , nie możemy jej po prostu znaleźć.

Musimy znaleźć ślad Oracle SQL dla sesji i odtworzyć problem. Gdy ślad będzie dostępny. Musimy poszukać err=54 w pliku śledzenia

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)'

Wiersz, który pokazuje błąd i część powyżej, pokazuje stwierdzenie, które powoduje błąd

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

Teraz, aby znaleźć sesję blokującą, musimy uruchomić instrukcję w sqlplus z opcją NOWAIT

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 ;

Wtedy ta sesja będzie czekać i możemy łatwo znaleźć sesję blokującą od dba_waiters i zabić sesję blokującą.

5. Z Oracle 11g i Oracle 12c mamy wiele czynności DDL, które można wykonać online bez przerywania błędu ORA-00054

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

Począwszy od 12c, możesz używać słowa kluczowego ONLINE z poleceniami DROP INDEX, DROP CONSTRAINT, ALTER INDEX UNUSABLE i SET COLUMN UNUSED

Powiązane artykuły

Tabela lub widok ORA-00942 nie istnieje
ORA-28000 konto jest zablokowane
ORA-28002
ORA-00904:nieprawidłowy identyfikator
ORA-01017:nieprawidłowa nazwa użytkownika/hasło; Odmowa logowania
zmień sesję zabijania systemu


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zalecenia dotyczące obsługi Oracle i SQL Server w tej samej aplikacji ASP.NET z NHibernate

  2. SELECT z tabeli z listą Varying IN w klauzuli WHERE

  3. Sprawdź, czy bieżąca data jest między dwiema datami Oracle SQL

  4. jak zmienić datę na godzinę w Oracle 10g

  5. Konwertuj interwał na minuty