
DBがデッドロックした話
こんにちは!
エンジニアの藤田です。
今回はある案件でDBがデッドロックしてしまいました。
対応し、コードレビューをしてもらうと、「テーブルロックが原因なのでテーブルロックしないようにしてください。」といわれデータベース関連の知識がなかったため調べながらわかったことについてまとめようと思います。
1. デッドロックとは
デッドロックとは「複数の実行中のプログラムなどが互いに他のプログラムの結果待ちとなり、待機状態に入ったまま動かなくなる現象」です。
例)
クエリ1:テーブル1UPDATE(テーブル1ロック) → テーブル2UPDATE
クエリ2:テーブル2UPDATE(テーブル2ロック) → テーブル1UPDATE

2. 学んだこと
データベースのロックには指定した行のみをロックする「行ロック」、テーブル全体をロックする「テーブルロック」があります。
データベースに全く知識のない私は上記「行ロック」と「テーブルロック」がどのようにしてかかるのか全くわかっていませんでした。。。
テーブルロックがかかってしまう原因としてはインデックス、主キーが関係していて、またインデックスや主キーの順番も関係してきます。
今回の例)
主キー:カラム1、カラム2、カラム3
<span class="token keyword">SELECT</span> <span class="token operator">*</span>
<span class="token keyword">FROM</span> テーブル
<span class="token keyword">WHERE</span> カラム3 <span class="token operator">=</span> ’〇〇’<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span>
となっていたためテーブルロックになっていたみたいです。
これを行ロックにするためには
<span class="token keyword">SELECT</span> <span class="token operator">*</span>
<span class="token keyword">FROM</span> テーブル
<span class="token keyword">WHERE</span> カラム1 <span class="token operator">=</span> ’〇〇’
<span class="token operator">AND</span> カラム2 <span class="token operator">=</span> ’△△’
<span class="token operator">AND</span> カラム3 <span class="token operator">=</span> ’□□’<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span>
としなければいけません。
3. 対応策
上記で記載したとおりテーブルの主キーが現在
主キー:カラム1、カラム2、カラム3
の3つが設定されていました。
今回の例でいうとカラム1、カラム2が主キーになっているのがそもそもどうなの?という話になったためクエリを変更するのではなく
主キー:カラム3
インデックス:カラム1、カラム2
のように作り変える事により対応致しました。
4. まとめ
デッドロックはシステムエラーになる一つの原因です。
また、データベースのエラーはシステムのエラーとはまた別で知識により防げることが大いにあることを学びました。
影響範囲が大きくなるとうっかり漏れてしまうことがありそうなのでテストする際には注意して確認しなければいけません。
データベースの知識は自分でもまだまだだと思っているのでこれを機にしっかり学んでいこうと思います!