Oracle
 sql >> база данни >  >> RDS >> Oracle

ORA-00054:ресурсът е зает и придобива с указано NOWAIT

ORA-00054:ресурсът е зает и придобиване с указано NOWAIT е често срещана грешка, наблюдавана в Oracle Database

Справка: Документация на Oracle

Това обикновено се случва, когато се опитате да изпълните DDL върху таблицата, която е заключена от транзакция. Също така се случва, ако операторът select for update се изпълнява с опция NOWAIT

Пример

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

Как да предотвратим грешката ORA-00054

1. Направете DDL в прозореца за поддръжка или извън пиковите часове, когато не се извършва транзакция

2.  С 11g имаме DDL_LOCK_TIMEOUT,

Това просто указва колко дълго искате да изчака заключването на DDL

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

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

Table Altered

3.  Можем да прекратим транзакцията, която държи ключалките на оракула, и след това да продължим с нея

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

След като намерите блокиращата сесия и решите да убиете сесията на oracle, можем да използваме заявката по-долу, за да генерираме sql сесия за убийство

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

4. Ако получавате ORA-00054:ресурсът е зает и придобийте с указано NOWAIT във формуляра за кандидатстване, след това продължете както следва

Имаме случай, когато срещаме ORA-00054:ресурсът е зает и придобиваме с NOWAIT, посочен във формуляра за кандидатстване. Сега в този случай става много трудно да се намерят ключалките , тъй като приложението не чака заключване. Това обикновено се случва, когато проблемите на приложението избират за актуализиране без опция за изчакване. Можем да намерим ключалки чрез dba_waiters, когато сесията чака заключване. Тъй като се заключва с nowait сесия, не можем просто да я намерим.

Ще трябва да намерим следата на oracle sql за сесията  и да възпроизведем проблема. След като следата е налична. Трябва да потърсим err=54 във файла за проследяване

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

Редът, който показва грешката, а частта по-горе показва изявлението, което дава грешката

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

Сега, за да намерим блокиращата сесия, трябва да задействаме изявлението в sqlplus с опция 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 ;

Тогава тази сесия ще изчака и лесно можем да намерим блокиращата сесия от dba_waiters и да прекратим блокиращата сесия.

5. С Oracle 11g и Oracle 12c имаме много DDL дейности, които могат да се извършват онлайн без прекъсване на грешката ORA-00054

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

Започвайки от 12c, можете да използвате ONLINE ключова дума с команди DROP INDEX, DROP CONSTRAINT, ALTER INDEX UNUSABLE и SET COLUMN UNUSED

Сродни статии

ORA-00942 таблица или изглед не съществува
ORA-28000 акаунтът е заключен
ORA-28002
ORA-00904:невалиден идентификатор
ORA-01017:невалидно потребителско име/парола; Отказано влизане
променете сесията за унищожаване на системата


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Какъв е размерът по подразбиране на въвеждане на varchar2 в съхранената процедура на Oracle и може ли да бъде променен?

  2. Предайте списък с цели числа от C# в съхранената процедура на Oracle

  3. Oracle:Как да конвертирам шестнадесетичен в десетичен в Oracle SQL?

  4. Бавна миграция към облак

  5. Как да форматирате числа в Oracle