- ブラウザURL入力
- DNS名前→IP
- ルータ経路選択
- ロードバランサ振り分け
- Nginx受け口
- アプリ処理
- DB保存今ここ
前のレッスンで、データファイルを書き換える前にログを先に永続化するという順序の約束を扱いました。今回は、そのログをどこまで遡れば済むのかを決める印の話です。
まず結論
チェックポイントは、復旧をどこから始めればよいかを決める**印**です。印があると、落ちたあとログを遡る範囲が限られます。印より前の変更は *guaranteed to be already on disk* ——すでにディスクに載っていると保証されるからです。
ただし印を打つ作業そのものが高価です。公式は **fairly expensive** と書き、全ダーティバッファの書き出しとその後の WAL 増加という2つの理由を挙げます。だから **頻繁にすると重く、間隔を空けると復旧が長くなる**——どちらにも代償があります。
チェックポイントの間隔を長くすると、何が起きると公式は書いているでしょうか。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
印がないと、どこまで戻ればよいか決まらない
前のレッスンで、データファイルを書き換える前にログを先に永続化するという順序の約束を見ました。落ちても本体に当たっていない変更はログから当て直せる——だからコミットのたびに本体を書かなくて済む、という交換でした。
するとすぐ問題が出ます。落ちたあと、ログをどこまで遡ればよいのでしょうか。 手掛かりがなければ先頭まで戻るしかありません。そこで打たれるのが印です。以下は PostgreSQL 18 時点の記述です。
Checkpoints are points in the sequence of transactions at which it is guaranteed that the heap and index data files have been updated with all information written before that checkpoint. At checkpoint time, all dirty data pages are flushed to disk and a special checkpoint record is written to the WAL file.
読みどころは it is guaranteed です。その点より前に書かれた情報は、データファイルに反映済みだと保証される。保証のために all dirty data pages are flushed to disk ——変更済みのページを全部ディスクへ出し、印そのもの(a special checkpoint record)を WAL に書きます。この印が復旧の出発点です。
In the event of a crash, the crash recovery procedure looks at the latest checkpoint record to determine the point in the WAL (known as the redo record) from which it should start the REDO operation. Any changes made to data files before that point are guaranteed to be already on disk. Hence, after a checkpoint, WAL segments preceding the one containing the redo record are no longer needed and can be recycled or removed.
the latest checkpoint record を見て redo record と呼ばれる開始点を決める。それより前は guaranteed to be already on disk なので、遡る必要がありません。
帰結がもう1つ。開始点より前のログは no longer needed and can be recycled or removed ——再利用または削除できます。印は遡る範囲を切るだけでなく、古い記録を片付ける根拠にもなります。
クラッシュ復旧のとき、どこから REDO を始めればよいかを決める材料は何だと公式は書いていますか。
いつ打たれるのか、既定値はどうなっているのか
きっかけは2つで、公式が既定値とともに書いています。
A checkpoint is begun every checkpoint_timeout seconds, or if max_wal_size is about to be exceeded, whichever comes first. The default settings are 5 minutes and 1 GB, respectively.
whichever comes first ——先に来たほうです。時間で来ることも、量で来ることもあります。設定側の記述も見ます。まず時間のほう。
Maximum time between automatic WAL checkpoints. If this value is specified without units, it is taken as seconds. The valid range is between 30 seconds and one day. The default is five minutes (
5min). Increasing this parameter can increase the amount of time needed for crash recovery.
既定は five minutes (5min)、範囲は30秒から1日まで。続く一文がこの回で最も大事な因果です——Increasing this parameter can increase the amount of time needed for crash recovery。増やすと、復旧に必要な時間が増えうる。
checkpoint_timeout The default is five minutes (5min)max_wal_size The default is 1 GB ← soft limitmin_wal_size The default is 80 MBcheckpoint_completion_target The default is 0.9 ← 古い資料の 0.5 とは異なる
ハイライトした2行が、通説とずれやすいところです。
通説とのずれ その1 — max_wal_size は上限ではない
名前が Maximum で始まるので、止まる線に見えます。しかし公式の書き方は違います。
Maximum size to let the WAL grow during automatic checkpoints. This is a soft limit; WAL size can exceed
max_wal_sizeunder special circumstances, such as heavy load, a failingarchive_commandorarchive_library, or a highwal_keep_sizesetting. If this value is specified without units, it is taken as megabytes. The default is 1 GB. Increasing this parameter can increase the amount of time needed for crash recovery.
This is a soft limit と明記され、超えうる状況も列挙されています。
heavy load 高負荷a failing archive_command or archive_library アーカイブの失敗a high wal_keep_size setting wal_keep_size が大きい
つまり「1 GB に設定したから 1 GB で止まる」という前提の見積りは外れます。特に2行目は、WAL を運び出す仕組みが失敗している間は溜まり続けるという意味で、平常時には出てこない事情です。なお min_wal_size の既定は 80 MB です。
通説とのずれ その2 — 既定値は 0.9
もう1つは、書き出しをどれだけ時間に広げるかの設定です。
The default is 0.9, which spreads the checkpoint across almost all of the available interval
既定は 0.9。almost all of the available interval ——利用可能な間隔のほぼ全体に広げます。
気を付けたいのは、古い教材や記事には 0.5 と書かれていることがある点です(PostgreSQL 13 の文書など)。現行の公式記述は 0.9(PostgreSQL 18 時点)。古い記事から持ってきた値は「動くけれど想定と違う」形で出るので気付きにくい。使っているバージョンの公式ドキュメントで確かめるのが確実です。
広げる意味も読めます。印を打つ作業は writing out all currently dirty buffers でした。一気にやればディスクが詰まる。間隔のほぼ全体に延ばせば山が低くなります。代償を消すのではなく、平らにする発想です。
公式がチェックポイントを fairly expensive と書く理由として挙げている2つは何ですか。
間隔を詰める(印を頻繁に打つ)
遡る範囲が短くなり、古い WAL セグメントも早く片付きます。公式は印より前を “guaranteed to be already on disk” とし、開始点より前のセグメントは “can be recycled or removed” と書いています。代償は印そのものの費用——“fairly expensive, first because they require writing out all currently dirty buffers, and second because they result in extra subsequent WAL traffic”。
軽くなる 復旧時に遡る範囲 / 古いセグメントの滞留重くなる ダーティバッファの書き出し頻度重くなる 印のあとの WAL トラフィック痛むのは 平常時
間隔を空ける(印を控える)
印を打つ回数が減るので、全ダーティバッファの書き出しもその後の WAL 増加も起きにくくなります。代償は公式が明記しています——“Increasing this parameter can increase the amount of time needed for crash recovery.” 印が復旧の開始点なので、間隔が空けば当て直す範囲が伸びます。
軽くなる 印を打つ頻度とその費用重くなる クラッシュ復旧に必要な時間注意 max_wal_size 側の契機で先に来ることもある痛むのは 落ちたあと
印を頻繁に打つ場合と控える場合。公式はどちらにも代償を書いています。この選択は結局何を決めているのでしょうか。
軽くなる場面と重くなる場面が、時間軸のどこにあるかを並べてください。
この章のまとめ
- チェックポイントは復旧の開始点を決める印。その点より前は 反映済みだと保証される。
- 復旧は 最新のチェックポイントレコードから redo record を決めて REDO を始める。開始点より前のセグメントは can be recycled or removed。
- 印は無料ではない。公式は fairly expensive とし、理由は all currently dirty buffers の書き出しと extra subsequent WAL traffic の2つ。
- 契機は2つで whichever comes first。既定は five minutes (
5min) と 1 GB。 max_wal_sizeは soft limit。「1 GB で止まる」は誤りで、公式は高負荷・アーカイブの失敗・wal_keep_sizeが大きい場合という超過条件を列挙している。min_wal_sizeの既定は 80 MB。checkpoint_completion_targetの既定は 0.9(古い資料の 0.5 とは異なる)。間隔のほぼ全体に広げて山を低くする方向。checkpoint_timeoutを延ばすと 復旧に必要な時間が増えうると公式が明記。印の間隔は「代償をいつ払うか」の配分。- 以上は PostgreSQL 18 時点の公式記述に基づく。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
「max_wal_size を 1 GB にしてあるので、WAL が 1 GB を超えることはない」。この説明を公式の記述に照らして評価してください。
用語集(4語)
- Checkpoints
- 公式の定義は “points in the sequence of transactions at which it is guaranteed that the heap and index data files have been updated with all information written before that checkpoint”。その時点より前に書かれた情報が、データファイルに反映済みだと保証される点。
- redo record
- 公式の言い方は “the point in the WAL (known as the redo record) from which it should start the REDO operation”。復旧が REDO を開始する位置。最新のチェックポイントレコードから決まる。
- soft limit
- `max_wal_size` について公式が使う語。“This is a soft limit; WAL size can exceed `max_wal_size` under special circumstances, such as heavy load, a failing `archive_command` or `archive_library`, or a high `wal_keep_size` setting.” 絶対的な上限ではない。
- dirty buffers
- チェックポイントが高価な理由の1つ目として公式が挙げる対象。“they require writing out all currently dirty buffers”。メモリ上で変更済みのページを、すべてディスクへ書き出す。