
ハングしてPostgreSQLを再起動した後に、何がハングの原因か調査するには
PostgreSQL がハング(応答しなくなる)した後、再起動後に原因を調査するための方法をいくつか紹介します。
🔹 1. ログファイルを確認
ハングの原因を特定するため、まずは PostgreSQL のログをチェックします。
ログのパスは postgresql.conf の log_directory で指定されています。
cat /var/lib/pgsql/data/log/postgresql.log | tail -n 100
確認するポイント:
FATAL や ERROR のメッセージ
could not write block や deadlock detected のようなメッセージ
out of shared memory などのメモリ不足メッセージ
canceling statement due to statement timeout のようなクエリタイムアウト
🔹 2. pg_stat_activity の履歴を確認
再起動後は pg_stat_activity の情報はリセットされますが、ハング前に監視していた場合、ログに記録されているかもしれません。
SELECT pid, usename, application_name, state, query_start, query
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY query_start;
ポイント
state = 'active' で長時間実行されていたクエリがないか
query_start が異常に古い(数時間前など)クエリがないか
もし pg_stat_activity を事前に監視していた場合、ハング時の情報がログに残っている可能性があります。
🔹 3. pg_locks を調査
ハングの原因がロック競合の場合、pg_locks の情報を確認するのが重要です。
再起動後なので直接 pg_locks は見れませんが、事前にログに記録していた場合は、以下のような SQL を使ってハングの原因を特定できます。
SELECT pid, relation::regclass, mode, granted
FROM pg_locks
WHERE NOT granted;
ポイント
granted = false のロックが発生していたか
relation::regclass でどのテーブルがロックされていたか
もしログに残っているなら、ハングの原因が特定できるかもしれません。
🔹 4. pg_stat_statements で負荷の高いクエリを調査
pg_stat_statements 拡張が有効なら、実行されたクエリの履歴が確認できます。
SELECT query, calls, total_time, mean_time
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 10;
ポイント
total_time の大きいクエリが異常に長時間実行されていたか
calls の回数が異常に多いクエリがないか
長時間実行されるクエリが原因でハングした可能性もあるため、これを確認します。
🔹 5. メモリ・CPU の状態を調査
PostgreSQL がハングした原因がリソース不足の場合、OS のログや監視ツールの履歴を確認する必要があります。
メモリ使用量の確認
dmesg | grep -i oom
Out of memory: Kill process ... のログがあれば、メモリ不足で PostgreSQL が強制終了された可能性が高い
CPU負荷の確認
grep -i "postgres" /var/log/syslog
または、監視ツール(top や htop)を使って事前に負荷を監視していれば、ハング前に CPU 負荷が高騰していたかを確認できます。
🔹 6. ディスク I/O 負荷を調査
PostgreSQL のパフォーマンスがディスク I/O に依存しているため、I/O 負荷が原因でハングした可能性もあります。
iostat -x 1 10
await(I/O の待ち時間)が異常に長い場合、ディスク I/O がボトルネック
dmesg | grep -i "ext4\|xfs"
Buffer I/O error のようなエラーがある場合、ディスク障害の可能性あり
🔹 7. autovacuum の影響を調査
autovacuum が重すぎると、パフォーマンスに悪影響を及ぼし、ハングの原因になることがあります。
SELECT relname, last_autovacuum, n_dead_tup
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 10;
n_dead_tup が異常に大きいテーブルがないか
last_autovacuum の実行時間が長くないか
autovacuum の影響でディスク I/O 負荷が上がり、ハングにつながった可能性もあります。
🔹 8. ネットワーク接続の問題を調査
ネットワークの問題でクライアントからの接続が詰まることもあります。
netstat -anp | grep postgres
TIME_WAIT や CLOSE_WAIT が大量にあると、接続が詰まっていた可能性あり
ss -tuna | grep 5432
5432 ポートの接続が異常に多くなっていないか
🔹 9. pg_wal(WAL ログ)の異常を確認
WAL(Write-Ahead Logging)のサイズが異常に大きくなっていた場合、ディスクがいっぱいになり、PostgreSQL がハングすることがあります。
du -sh /var/lib/pgsql/data/pg_wal/
/pg_wal/ のサイズが異常に大きい場合、WAL の蓄積が原因の可能性
ログに WARNING: archive_command failed のようなエラーがある場合、WAL のアーカイブ処理が詰まっていた可能性あり。
🔹 まとめ
ログ (postgresql.log) を確認
pg_stat_activity でハング前のクエリを確認
pg_locks でロック競合を確認
pg_stat_statements で負荷の高いクエリを特定
dmesg でメモリ不足 (OOM Killer) を確認
iostat でディスク I/O 負荷を調査
pg_stat_user_tables で autovacuum の影響を確認
netstat でネットワークの詰まりを確認
pg_wal のサイズを確認
これらを総合的に調べることで、ハングの原因を特定できる可能性が高いです。
もし特定のエラーメッセージがあれば、それを詳しく調査するのが最善の方法です!