前書き
アプリケーションのRDBMSでデッドロックが発生した際に、なんらかの手段(JP1とか)でアラートを上げる設定をすることがあります。
実際にアラートが上がるかテストする必要があるわけですが、Oracle環境でさくっとデッドロックを発生させる手順をまとめました。
デッドロックの仕組み
デッドロックは2つ以上のユーザが同じテーブルの同じ複数行に対し更新をかけ、両方ともがお互いを待っている状態です。
図にすると以下のような具合です。
パワポ感満載ですが、気にしないでください。
上図を実際に実行すると、簡単にデッドロックを発生できます。では早速やってみます。
デッドロック発生手順
-
sqlplusでログインし、テスト用テーブルを作成
sqlplus user1/xxxxx
CREATE TABLE TEST_TBL1(
test_id INT NOT NULL,
name CHAR(8) NOT NULL
)
tablespace HOGE;
-
データの挿入
insert into TEST_TBL1 values(1,'test001');
insert into TEST_TBL1 values(2,'test002');
commit;
-
別々のターミナルを立ち上げSQLPLUSを起動し、順番に実行
(1)ターミナル1で実行
update TEST_TBL1 set name='test003' where test_id=1;
(2)ターミナル2で実行
update TEST_TBL1 set name='test004' where test_no=2;
(3)ターミナル2で実行
update TEST_TBL1 set name='test006' where test_id=1;
(4)ターミナル1で実行
update TEST_TBL1 set name='test005' where test_id=2;
実際に実行してみたところ
SQL> update TEST_TBL1 set name='test005' where test_id=2;
update TEST_TBL1 set name='test005' where test_id=2
*
行1でエラーが発生しました。:
-
※両方のsqlplusで実施
roll back;
-
アラートログにデッドログのログが発生していること確認
/var/logs/oracle/diag/rdbms/xxx/xxxx/trace $ tail -200 alert_xxx.log
以下メッセージでていればOK
ORA-00060: Deadlock detected. More info in file /var/logs/oracle/diag/rdbms/xxx/xxxx/trace/xxxx_ora_27984084.trc.
以上です。さくっとできました。