見出し画像

ハングして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 のアーカイブ処理が詰まっていた可能性あり。


🔹 まとめ

  1. ログ (postgresql.log) を確認

  2. pg_stat_activity でハング前のクエリを確認

  3. pg_locks でロック競合を確認

  4. pg_stat_statements で負荷の高いクエリを特定

  5. dmesg でメモリ不足 (OOM Killer) を確認

  6. iostat でディスク I/O 負荷を調査

  7. pg_stat_user_tables で autovacuum の影響を確認

  8. netstat でネットワークの詰まりを確認

  9. pg_wal のサイズを確認


これらを総合的に調べることで、ハングの原因を特定できる可能性が高いです。
もし特定のエラーメッセージがあれば、それを詳しく調査するのが最善の方法です!

いいなと思ったら応援しよう!