クラッシュ後のPostgreSQL「FATAL: lock file postmaster.pid already exists」を修正する

beginner🐘 PostgreSQL2026-06-19| PostgreSQL 14(systemd管理)のUbuntu/Debian環境。同様のLinuxディストリビューションのPostgreSQL 12〜16にも適用可能

Error Message

FATAL: lock file "/var/run/postgresql/14-main.pid" already exists HINT: Is another postmaster (PID 12345) running in data directory "/var/lib/postgresql/14/main"?
#起動#ロックファイル#postmaster#クラッシュ#pid

何が起きたのか

サーバーがクラッシュしました — 停電、OOMキル、カーネルパニック、原因は何であれ — 今やPostgreSQLが起動を拒否しています。表示されているエラーは次のとおりです:

FATAL:  lock file "/var/run/postgresql/14-main.pid" already exists
HINT:  Is another postmaster (PID 12345) running in data directory "/var/lib/postgresql/14/main"?

PostgreSQLは起動時にPIDをpostmaster.pidへ書き込みます。正常シャットダウン時にはそのファイルを削除します。クラッシュした場合は?削除の機会がありません。古いファイルが残り続け、次回の起動時にそれを検出して、別のインスタンスがすでに実行中だと判断して起動を拒否します。

修正には2分もかかりません。ただし最初に、何かを触る前にPostgreSQLが実際に動いていないことを確認してください。

ステップ1:実際に何も動いていないことを確認する

何かを削除する前に、PostgreSQLプロセスが本当に生きている可能性を排除します:

# postgresプロセスが存在するか確認
ps aux | grep postgres

# デフォルトポートでリッスンしているものがあるか確認
sudo ss -tlnp | grep 5432

アクティブなpostgresプロセスやポート5432にバインドされているものがある場合は作業を止めてください — 2つのインスタンスが衝突している可能性があります。他の作業を行う前にpg_lsclusters(Debian/Ubuntu)で調査してください。

何も表示されませんか?PIDファイルは確実に古くなっています。続行してください。

ステップ2:PIDファイルの内容を確認する

cat /var/run/postgresql/14-main.pid

最初の行は、PostgreSQLが最後に起動したときに記録したPIDです。これをクロスチェックします:

ps -p 12345

No such process — またはそのPIDをたまたま引き継いだまったく無関係なプログラム — が表示された場合、ファイルは古くなっており安全に削除できます。

ステップ3:古いロックファイルを削除する

sudo rm /var/run/postgresql/14-main.pid

データディレクトリ自体の中にも2つ目のロックファイルがあります。確認してください:

sudo ls -la /var/lib/postgresql/14/main/postmaster.pid

見つかりましたか?こちらも削除します:

sudo rm /var/lib/postgresql/14/main/postmaster.pid

/var/run/postgresql/はinitシステムのコピーを保持し、データディレクトリはPostgreSQL自身の内部ロックを保持します。クラッシュ後は、両方が古くなります。

ステップ4:PostgreSQLを起動する

sudo systemctl start postgresql@14-main

# または、汎用サービス名を使用している場合:
sudo systemctl start postgresql

すぐにログを確認します:

sudo journalctl -u postgresql@14-main -n 50 --no-pager

database system is ready to accept connectionsが表示されるのを確認してください。表示されましたか?完了です。

ステップ5:修正を確認する

# サービスがアクティブであることを確認
sudo systemctl status postgresql@14-main

# 接続して簡単な動作確認を実行
sudo -u postgres psql -c "SELECT version();"

新しいPIDファイルが正しく書き込まれたことを確認します:

cat /var/run/postgresql/14-main.pid

新しく起動したプロセスのPIDが含まれているはずです。実行中のpostgresと一致することを確認します:

ps aux | grep postgres | head -5

PIDファイルを削除してもPostgreSQLが起動しない場合

古いPIDファイルがクラッシュの唯一の被害というわけではありません。手がかりを得るためにPostgreSQLのログを確認してください:

sudo tail -100 /var/log/postgresql/postgresql-14-main.log

よくある二次的な問題:

  • 共有メモリが解放されていない — 古いバージョンのPostgreSQLは共有メモリセグメントを残すことがありました。ipcs -mでリストアップし、孤立したエントリを削除します:ipcrm -m <shmid>(例:ipcrm -m 327681)。
  • データディレクトリの回復が必要 — ログにdatabase system was not properly shut downが表示されるのはクラッシュ後では正常です。PostgreSQLはWALをリプレイして自動的に回復します。そのまま実行させてください — ほとんどのデータベースは1分以内に完了します。
  • パーミッションが変更された — データディレクトリがまだpostgresによって所有されているか確認します:ls -la /var/lib/postgresql/14/。所有者が間違っていますか?sudo chown -R postgres:postgres /var/lib/postgresql/14/mainで修正してください。

クイックリファレンス:PIDファイルの場所

  • Ubuntu/Debian PG 14/var/run/postgresql/14-main.pid
  • RHEL/CentOS/Fedora/var/run/postgresql/postmaster.pid
  • データディレクトリのロック/var/lib/postgresql/14/main/postmaster.pid(またはPGDATAが指す場所)
  • カスタムインストールPGDATA環境変数を確認するか、pg_lsclustersを実行してください

なぜこれが繰り返されるのか(そして発生を減らす方法)

根本原因は常に不正なシャットダウンです。対処する価値のあることがいくつかあります:

  • データベースサーバー用のUPS — 開発環境やステージング環境で最もよく省略されます。このエラーが発生するのはまさにそのような場所です。
  • systemdのTimeoutStopSec — フラッシュに時間がかかりすぎてPostgreSQLが再起動中にキルされていますか?停止タイムアウトを増やしてください。sudo systemctl edit postgresql@14-mainでサービスユニットにTimeoutStopSec=120を追加します。
  • OOMキラー — PostgreSQLがOOMキルされている場合、それはまったく別の問題です。クラッシュ後にdmesg | grep -i oomを実行して確認してください。
  • VMスナップショット — 実行中のVMをスナップショットに戻すと、毎回古いPIDファイルが残ります。スナップショットを取る前にクリーンにシャットダウンするか、各リバート後にこの修正手順を実行することを覚悟してください。

この修正はリスクが低いです。PostgreSQLのWALベースのクラッシュリカバリが独自にデータの整合性を処理します。PIDファイルを削除するのは、クラッシュが残した管理上の痕跡を消去するだけです。

Related Error Notes