ORA-00054 :ressource occupée et acquisition avec NOWAIT spécifié est une erreur courante rencontrée dans Oracle Database
Référence : Documentation Oracle
Cela se produit généralement lorsque vous essayez d'exécuter un DDL sur la table qui est verrouillée par une transaction. Cela se produit également si l'instruction select for update est exécutée avec l'option NOWAIT
Exemple
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
Comment éviter l'erreur ORA-00054
1.Faites le DDL dans la fenêtre de maintenance ou les heures creuses lorsqu'aucune transaction n'est en cours
2. Avec 11g, nous avons DDL_LOCK_TIMEOUT,
Ceci indique simplement combien de temps vous souhaitez qu'il attende le verrou DDL
SQL> alter session set ddl_lock_timeout = 600; Session altered. SQL> alter table emp add (middlename varchar2(15)); Table Altered
3. Nous pouvons tuer la transaction qui contient les verrous Oracle, puis continuer
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' /
Une fois que vous avez trouvé la session de blocage et décidé de tuer la session oracle, nous pouvons utiliser la requête ci-dessous pour générer la session kill sql
select 'alter system kill session '''||sid||','||serial#||''';' from v$session where sid=&1;
4.Si vous obtenez ORA-00054 :ressource occupée et acquisition avec NOWAIT spécifié dans le formulaire de demande, puis procédez comme ci-dessous
Nous avons un cas où nous rencontrons ORA-00054 :ressource occupée et acquise avec NOWAIT spécifié dans le formulaire de demande. Dans ce cas, il devient très difficile de trouver les verrous car l'application n'attend pas le verrou. Cela se produit généralement lorsque des problèmes d'application sélectionnent une mise à jour sans option d'attente. Nous pouvons trouver des verrous via dba_waiters lorsque la session attend le verrou. Comme il se verrouille avec nowait session , nous ne pouvons pas simplement le trouver.
Nous devrons trouver la trace Oracle SQL pour la session et reproduire le problème. Une fois la trace disponible. Nous devons rechercher err=54 dans le fichier de trace
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)'
La ligne qui montre l'erreur et la partie ci-dessus montre la déclaration qui donne l'erreur
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
Maintenant, pour trouver la session de blocage, nous devons déclencher l'instruction dans sqlplus avec l'option 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 ;
Ensuite, cette session attendra et nous pourrons facilement trouver la session de blocage à partir de dba_waiters et tuer la session de blocage.
5.Avec Oracle 11g et Oracle 12c, nous avons beaucoup d'activités DDL qui peuvent être effectuées en ligne sans interruption de l'erreur ORA-00054
SQL> create index emp_idx on emp(emp_no) online;
À partir de 12c, vous pouvez utiliser le mot-clé ONLINE avec les commandes DROP INDEX, DROP CONSTRAINT, ALTER INDEX UNUSABLE et SET COLUMN UNUSED
Articles connexes
ORA-00942 la table ou la vue n'existe pas
ORA-28000 le compte est verrouillé
ORA-28002
ORA-00904 :identifiant invalide
ORA-01017 :nom d'utilisateur/mot de passe invalide ; connexion refusée
alter system kill session