Tihiroの頭を休めるIT教室

少しだけ頭使って後は根性

PostgreSQLのデッドロックについて。

概要

PostgreSQLデッドロックについての解説記事です。 行レベルロック、テーブルレベルロックと解説しましたので、ついでというわけではないですがデッドロックについても少しだけ。

検証したバージョンはPostgreSQL9.6.3です。

デッドロックとは

画像で表すと

f:id:r_tihiro:20170818081135p:plain
デッドロック

な感じ。

※画像は拾い物です。

赤い車も青い車のどちらも、お互いに待っていて動けません。これがデッドロックだ!!

PostgreSQLでのデッドロック

PostgreSQLではデッドロックが発生した際に、自動的に一方のトランザクションがアボートします。

公式ドキュメント(https://www.postgresql.jp/document/9.6/html/explicit-locking.html)を確認しますと

PostgreSQLでは、自動的にデッドロック状況を検知し、関係するトランザクションの一方をアボートすることにより、この状況を解決し、もう一方のトランザクションの処理を完了させます (どちらのトランザクションをアボートするかを正確に予期するのは難しく、これに依存すべきではありません)。

と、ありますように、アボートするトランザクションはランダムなようですが、経験的に「後に実行したSQLトランザクション」がアボートするパターンが多いです。

デッドロックの検出について

PostgreSQLでは自動的にデッドロックを検出してくれますが、その検出間隔デフォルトで1秒間隔となっています。

この検出間隔を変えたい場合は、設定ファイルのpostgresql.conf内の

deadlock_timeout

を変更します。

例えば、1分間隔にしたい場合は

deadlock_timeout = 60s

というような感じです。

設定はリロードで読み込まれるみたいです。

pg_ctl reload

です。

まとめ

デッドロックの検出処理は比較的、重たい部類の処理という話らしいので、できるだけdeadlock_timeoutの値は大きくしておきたいものです。 具体的にどれくらい重たい処理なのでしょうね? 機会があれば調べてみたいと思います。