データベースのマイグレーション・スクリプトの実行中、またはデータベース・スキーマの変更中に、エラーを受け取りました。
症状
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired というエラーを受け取りました。
なぜこのエラーが発生するのでしょうか、またどのように回避できますか?
原因
データ定義言語 (DDL) を使用してデータベース・スキーマが定義され、データ操作言語 (DML) を使用してデータベース内の表が変更されます。
データ保全性を保持するために、データベースは表またはその表内の行にロックを掛けてから、その更新や読み取りを行います (読み取り、書き込み、排他的などの各種モード)。
DDL および DML は表内のすべての行に影響を与えるため、排他的ロックが必要であり、その表内のいずれかの行に既存のロックが掛けられている場合は、障害が発生します。
Oracle では、DDL および DML がロックを検出すると、ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired というエラーを受け取ります。
問題の解決
DDL またはデータベースのマイグレーションは、ダウン時間にのみ実行すべきです。
$TOP/bin/go/stop_local.sh を使用してすべての製品サービスを完全にオフにしておく必要があり、データベースが使用中であってはなりません。
その他の代替方法として、以下のようなものがあります。
- 排他ロックを妨げているセッションを見つけて停止します。
- Oracle 11g では、ddl_lock_timeout を設定できます。
例えば、以下のように待機する時間の長さを指定するだけで、オブジェクトが使用可能になるまで DDL が待機できるようになります。
SQL> alter session set ddl_lock_timeout = 600;
Session altered.