なぜPostgreSQLは「書く前」に書き出すのか?WALの深淵を覗く
「データベースがクラッシュした。でも、データは無事だった」
エンジニアとして、これほど心強い言葉はありませんよね。なぜPostgreSQLは突然の電源断やOSのパニックから、整合性を保って復旧できるのか。その心臓部にあるのが、今回解説するWAL(Write-Ahead Log)です。
教科書には「先行書き込みログ」なんて小難しいことが書いてありますが、現場の感覚で言えば、「本番のデータファイル(テーブルデータなど)をいじる前に、やりたいことをメモ帳にすべて書き残しておく仕組み」のことです。
今日は、このWALが裏側でどう動き、どう僕たちのシステムを守っているのか、現場目線で紐解いていきましょう。
—
なぜ「直接データ」を書き込まないのか?
「テーブルデータを書き換えるとき、その瞬間にディスクの該当箇所を更新すればいいじゃないか」と思うかもしれません。でも、考えてみてください。
データベースのデータファイルは巨大です。ランダムアクセスで少しずつ書き込むのは、ディスクI/Oの観点から見ると地獄のような低速処理になります。
そこでPostgreSQLは、「変更分をログ(WAL)としてシーケンシャルに書き出す」という手法をとります。ログを順番に追記するのは非常に速い。書き込みが終わった後に、メモリ上のデータをゆっくりと時間をかけてデータファイルへ反映(チェックポイント)させます。これが「書き込みを高速化しつつ、データの整合性を担保する」という、PostgreSQLの賢い戦略なんです。
WALの構成を覗いてみる
実際にPostgreSQLを触っているなら、`$PGDATA/pg_wal` ディレクトリを見たことはあるはずです。ここには `000000010000000000000001` といった名前のファイルが並んでいますね。これがWALセグメントファイルです。
デフォルトでは1つ16MB。この中に、DBで起きたあらゆる変更(INSERT, UPDATE, DELETEなど)がバイナリとして記録されています。
実践:WALの中身を覗いてみる
「本当に自分のクエリがログに書かれているのか?」と疑問に思ったら、`pg_waldump` コマンドを使ってみましょう。PostgreSQLに標準で入っているツールです。
特定のWALセグメントファイルを解析して表示する
$ pg_waldump -p /var/lib/postgresql/data/pg_wal 000000010000000000000001
これを叩くと、ズラズラと「どのトランザクションが、どのブロックに対して、どんな操作をしたか」が流れてきます。トラブルシューティングの際、原因特定に役立つ最終手段なので、覚えておいて損はありませんよ。
—
WALが「クラッシュリカバリ」を救う仕組み
もしPostgreSQLが書き込み途中でクラッシュしたらどうなるか?
1. 起動時: PostgreSQLは、データファイルとWALの「最終更新地点」のズレをチェックします。
2. REDO: WALに残っているログを最初から読み直し、データファイルに反映されていない操作を「再実行」します。
これで、データファイルが中途半端な状態で壊れていても、常に最新の整合性が取れた状態まで復旧できるわけです。
現場で気をつけるべき「WALの罠」
WALは便利ですが、運用をミスるとシステムを止めかねない爆弾でもあります。
- WALの肥大化とディスク枯渇:
レプリケーションが切れていたり、長すぎるトランザクションが残っていると、古いWALが削除できずにディスクを圧迫します。「WALファイルがいっぱいでDBが起動しない」というのは、DBAが一度は通る洗礼です。`max_wal_size` の設定と、レプリケーションの監視は徹底しましょう。
- アーカイブの遅延:
`archive_mode = on` にしている場合、WALを別のストレージに退避させますが、アーカイブ処理が遅れるとDB内部にWALが溜まり続けます。バックアップ先(S3など)の転送速度は、書き込み量に対して十分か、必ず見積もっておく必要があります。
—
まとめ:WALはDBの「魂」である
WALは単なるログファイルではなく、「データの一貫性」と「レプリケーションの伝送路」を支える心臓部です。
- 高速な書き込みのために、まずはログを信じろ。
- トラブル時はログ(WAL)を見ろ。
- ディスクの空き容量には常に敬意を払え。
最初は設定項目が多くて難しく感じるかもしれませんが、WALを理解すれば、PostgreSQLの挙動が今まで以上に鮮明に見えてくるはずです。
もし運用で詰まったら、まずは `pg_waldump` を叩いてみてください。PostgreSQLが何をしようとしていたのか、その足跡がすべてそこに刻まれています。
それでは、また次回の深掘りでお会いしましょう!
コメント