DBがデッドロックした話
こんにちは!
エンジニアの藤田です。
今回はある案件でDBがデッドロックしてしまいました。
対応し、コードレビューをしてもらうと、「テーブルロックが原因なのでテーブルロックしないようにしてください。」といわれデータベース関連の知識がなかったため調べながらわかったことについてまとめようと思います。
1. デッドロックとは
デッドロックとは「複数の実行中のプログラムなどが互いに他のプログラムの結果待ちとなり、待機状態に入ったまま動かなくなる現象」です。
例)
クエリ1:テーブル1UPDATE(テーブル1ロック) → テーブル2UPDATE
クエリ2:テーブル2UPDATE(テーブル2ロック) → テーブル1UPDATE
2. 学んだこと
データベースのロックには指定した行のみをロックする「行ロック」、テーブル全体をロックする「テーブルロック」があります。
データベースに全く知識のない私は上記「行ロック」と「テーブルロック」がどのようにしてかかるのか全くわかっていませんでした。。。
テーブルロックがかかってしまう原因としてはインデックス、主キーが関係していて、またインデックスや主キーの順番も関係してきます。
今回の例)
主キー:カラム1、カラム2、カラム3
SELECT *
FROM テーブル
WHERE カラム3 = ’〇〇’
となっていたためテーブルロックになっていたみたいです。
これを行ロックにするためには
SELECT *
FROM テーブル
WHERE カラム1 = ’〇〇’
AND カラム2 = ’△△’
AND カラム3 = ’□□’
としなければいけません。
3. 対応策
上記で記載したとおりテーブルの主キーが現在
主キー:カラム1、カラム2、カラム3
の3つが設定されていました。
今回の例でいうとカラム1、カラム2が主キーになっているのがそもそもどうなの?という話になったためクエリを変更するのではなく
主キー:カラム3
インデックス:カラム1、カラム2
のように作り変える事により対応致しました。
4. まとめ
デッドロックはシステムエラーになる一つの原因です。
また、データベースのエラーはシステムのエラーとはまた別で知識により防げることが大いにあることを学びました。
影響範囲が大きくなるとうっかり漏れてしまうことがありそうなのでテストする際には注意して確認しなければいけません。
データベースの知識は自分でもまだまだだと思っているのでこれを機にしっかり学んでいこうと思います!