ORA-00054:リソースがビジーで、NOWAITを指定して取得 Oracleデータベースで見られる一般的なエラーです
参照:Oracleドキュメント
これは通常、トランザクションによってロックされているテーブルでDDLを実行しようとしたときに発生します。また、selectforupdateステートメントが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セッションでロックされているため、それを見つけることはできません。
セッションのoraclesqlトレースを見つけて、問題を再現する必要があります。トレースが利用可能になったら。トレースファイルで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
次に、ブロッキングセッションを見つけるために、NOWAITオプションを使用してsqlplusでステートメントを起動する必要があります
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. Oracle11gおよびOracle12cを使用すると、エラーORA-00054
を中断することなくオンラインで実行できる多くのDDLアクティビティがあります。SQL> create index emp_idx on emp(emp_no) online;
12c以降では、DROP INDEX、DROP CONSTRAINT、ALTER INDEX UNUSABLE、およびSETCOLUMNUNUSEDコマンドでONLINEキーワードを使用できます
関連記事
ORA-00942テーブルまたはビューが存在しません
ORA-28000アカウントがロックされています
ORA-28002
ORA-00904:識別子が無効です
ORA-01017:ユーザー名/パスワードが無効です。ログオンが拒否されました
システム強制終了セッションの変更