やあ。最近、PostgreSQLの運用周りで「バックアップの自動化」を任された若手エンジニアが増えてきたから、今日は少し深掘りした話をしようと思う。
「WALアーカイビング」。名前だけ聞くと小難しそうだけど、これこそがPostgreSQLにおける「究極の保険」なんだ。これが理解できていないと、いざという時に「昨日の夕方までのデータに戻してくれ!」という泣きつかれた要求に、冷や汗を流すことになる。
今日は、教科書には載っていない「現場の肌感覚」を交えながら解説していくよ。
—
WALアーカイビングって、結局なんなの?
PostgreSQLは、データ更新のたびに「WAL(Write Ahead Log)」というログを書き出す。これは、クラッシュした時にデータを復旧させるための備忘録だね。
でも、このWALファイルは一定サイズ(デフォルトだと16MB)に達すると書き換えられて、いずれ消えてしまう。そこで登場するのがWALアーカイビングだ。
簡単に言えば、「使い終わって満杯になったWALファイルを、消される前に別の安全な場所(S3やNFSなど)にコピーしておく仕組み」のこと。これがあるから、僕たちは「任意の時点(Point-in-Time)」までデータベースを巻き戻すことができるんだ。
設定は「3つの魔法の呪文」を唱えるだけ
postgresql.confをいじる作業だ。最低限、この3つを覚えておけば大丈夫。
1. アーカイブモードをONにする
archive_mode = on
2. 完了したWALをどこに投げるか(コマンド)
%p は元のパス、%f はファイル名
archive_command = ‘test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f’
3. WALのレベルを「replica」以上に設定(必須!)
wal_level = replica
ここで現場のワンポイントアドバイス
`archive_command` の `test ! -f …` って何のためにあるか分かる?
実は、ネットワークの瞬断なんかでコピーが失敗した時、PostgreSQLは同じコマンドを何度も再試行するんだ。もしコピー先にもうファイルがあったら、`cp` コマンドがエラーを吐いて、WALが溜まり続け、最終的にディスク溢れを起こす。この「存在確認」を入れるのが、現場で生き残るための定石だよ。
PITR(ポイントインタイムリカバリ)への応用
さて、ここからが本番。アーカイビングしたWALファイルがあれば、こんなことができる。
1. ベースバックアップをリストアする(昨日の深夜のバックアップを戻す)
2. `recovery.signal` を配置する
3. `postgresql.auto.conf` に `restore_command` を書く
具体的にはこんな感じだ:
リストア時に、バックアップ先からWALを引っ張ってくる命令
restore_command = ‘cp /mnt/server/archivedir/%f %p’
ここで「何時何分に戻したいか」を指定する
recovery_target_time = ‘2023-10-27 10:00:00’
これを設定してPostgreSQLを再起動すると、データベースは過去のバックアップから立ち上がり、そこからアーカイブしておいたWALを次々と読み込んで「指定した時間」まで高速で追いついてくれる。まるで映画の「巻き戻し」を見ているようで、何度やっても感動するよ。
—
運用で死なないための「教訓」
最後に、先輩としてこれだけは伝えておきたい。
- 監視をサボるな: アーカイブが失敗し続けると、WALが大量に生成されてディスクを食いつぶす。`archive_command` の終了ステータスを監視して、失敗したら即座に通知が飛ぶようにしておこう。
- アーカイブ先は「別」に置け: データベースと同じサーバーの別のディレクトリにコピーしても、サーバーそのものが死んだら意味がない。S3などのオブジェクトストレージに飛ばすのが、今の時代の正解だ。
- テストは「一度」で済ませるな: 復旧手順は、定期的にテスト環境で試してくれ。いざという時に `restore_command` のパスを間違えていた、なんて事故は笑えないからね。
WALアーカイビングは、PostgreSQL運用の「守りの要」だ。これがしっかり構築できていれば、どんなトラブルが起きても「まあ、最悪戻せばいいか」という精神的余裕が生まれる。
技術は、使いこなして初めて自分の武器になる。まずは今の開発環境で、`archive_mode` をONにするところから始めてみようぜ。応援してるよ。
コメント