- ブラウザURL入力
- DNS名前→IP
- ルータ経路選択
- ロードバランサ振り分け
- Nginx受け口
- アプリ処理
- DB保存今ここ
本番のデータを複数の場所に持つ仕組みが、何から守り、何から守らないのかを分けて見ます。
まず結論
レプリカは主の変更記録をそのまま再生するので、誤った DELETE も同じように再生します。守れるのは機械や拠点を失う故障で、誤操作や不具合で消えた行は守れません。
適用をわざと遅らせる遅延スタンバイは猶予を作りますが、本教材の実演で救えたのは、猶予の間に適用を止めて読み出したときだけでした。そのまま昇格させると、誤りごと本番になりました。
主で誤って全行を DELETE しました。適用を30秒遅らせたスタンバイにはまだ100件残っています。このスタンバイを数秒後にそのまま昇格させて新しい主にすると、昇格直後の件数はどうなったでしょうか(PostgreSQL 18.6 の実演)。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
レプリカは、主が何をしたかを区別せずに再生する
冗長化で単一障害点をなくし、壊れたら予備へ引き継がせる。この考え方は正しく、主の機械が止まってもレプリカがあればサービスを続けられます。
問題は、予備が「何を」引き継ぐかです。PostgreSQL の文書はスタンバイの動きを次のように書きます。
By default, a standby server restores WAL records from the sending server as soon as possible.
WAL は第6期で扱ったとおり、何をどう書き換えたかの記録です。そこには「正しい更新」と「誤った DELETE」の区別がありません。スタンバイは届いた記録を順に再生するだけなので、誤りも正しい変更と同じ速さで複製されます。
SRE Book 第26章はこれを一文で言います。
In designing a data integrity program, it’s important to recognize that replication and redundancy are not recoverability.
少し後の段落は、自動で同期するデータストアでは壊れた行や誤った削除が全ての複製へ押し出される(likely before you can isolate the problem)と書いています。
- ・遅延は「いつ届くか」を変えるだけで、「届くかどうか」は変えない
本教材の実演の出力(スクリプト非掲載)
Docker 上の PostgreSQL 18.6 で、主1台とスタンバイ2台を立てました。1台は既定のまま、もう1台は recovery_min_apply_delay を30秒にしています(複製の認証は実演用に省いており、設定例ではありません)。主に100行入れてから全行を DELETE し、数秒後に各台で件数を数えました。
=== replica.sh run 1 2026-09-26 09:29:15primary: 0standby(即時): 0standby(30s遅延): 10030秒後 standby(30s遅延): 0
即時のスタンバイは、数えた時点ですでに0件です。届くまでの時間は測っていないので、言えるのは「この環境で試した回はいずれも数秒以内に届いた」までです。SRE Book も、DB の層では1つのトランザクションの複製は on the order of seconds かかりうると書いています。
遅延スタンバイには100件残っています。ただし最後の行(実際は32秒待ってから数えた行)で0件になりました。猶予が過ぎれば、遅延スタンバイも即時と同じです。
「主の障害に備えてレプリカを置いてあるので、誤って消した行もレプリカから取り戻せる」という考えは妥当ですか。
遅延は猶予を作るだけで、使い方は人が決める
第12期では複製の遅れを、書いた直後に読めない困りごととして扱いました。ここでは遅れをわざと作ります。文書はこの設定の目的をこう書きます。
It may be useful to have a time-delayed copy of the data, offering opportunities to correct data loss errors.
opportunities(機会)であって保証ではありません。遅延には条件が付いています。
- 既定は0(
The default is zero, adding no delay.)。設定しなければ猶予は無い。 - 遅らせるのはコミットのレコードだけ(
The delay occurs only on WAL records for transaction commits.)。 - 昇格すると待たない(
until the standby is promoted or triggered. After that the standby will end recovery without further waiting.)。
3つ目が落とし穴です。猶予の内に誤りに気づいても、スタンバイを主に切り替えるいつもの復旧手順を当てはめると、猶予は消えます。 救うには、昇格ではなく適用を止めることです。文書は停止関数について While recovery is paused, no further database changes are applied. と書き、同時に A request doesn't mean that recovery stops right away. と、止まったことは状態で確かめるよう求めています。
止めた場合と、昇格させた場合
同じ構成で、DELETE の数秒後に遅延スタンバイの適用を止めました。
=== run 1 2026-09-26 09:45:24primary: 0standby(即時): 0standby(30s遅延): 100standby(30s遅延) で pg_wal_replay_pause() を実行32秒後 standby(30s遅延・停止中): 100 state=paused32秒後 standby(即時): 0pg_wal_replay_resume() を実行再開3秒後 standby(30s遅延): 0
止めている間は、猶予を過ぎても100件です。この間に行を読み出せば取り戻せます。再開すると、3秒後には0件でした。止めている間に読み出さなければ、何も救えません。
次は、止めて paused を確かめてから昇格させた場合です。
=== MODE paused-promote run 1 2026-09-26 09:49:34primary: 0standby(即時): 0standby(30s遅延): 100pause state after 26s: paused rows=100pg_promote(): t昇格後 standby(30s遅延だったもの): 0 in_recovery=f2026-09-26 00:50:16.072 UTC [25] LOG: recovery has paused2026-09-26 00:50:17.075 UTC [25] LOG: received promote request2026-09-26 00:50:17.076 UTC [25] LOG: redo done at 0/4057288 system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 33.20 s2026-09-26 00:50:17.080 UTC [25] LOG: selected new timeline ID: 22026-09-26 00:50:17.108 UTC [25] LOG: archive recovery complete
昇格の直前は100件、直後は0件です。redo done の位置まで適用を進めてから新しいタイムラインに移っています。昇格の仕方を「そのまま」「停止を要求した1秒後」「paused を待ってから」の3通り、各2回試して、6回とも0件でした。
文書には If a promotion is triggered while recovery is paused, the paused state ends and promotion continues. とあります。「昇格すると残りの WAL をすべて適用する」と明記した一文は確認できた範囲では見つかっておらず、ここは実測として受け取ってください。目標時点を指定して回復し直す手順は、この遅延スタンバイでは試していません。
30秒遅延のスタンバイがあり、誤った DELETE に猶予の内に気づきました。本教材の実演で100件のまま残せた対処はどれですか。
即時スタンバイ
受け取りしだい適用します。実演では DELETE の数秒後に0件でした。主の機械を失ったときの引き継ぎ先としては働きますが、誤った削除から行を取り戻す場所にはなりません。
時点 件数DELETE の数秒後 0その32秒後 0
30秒の遅延スタンバイ
コミットの適用を30秒遅らせます。数秒後は100件でしたが、待てば0件、昇格させても0件でした。止めた間だけ100件が残り、そこから読み出せます。
時点・操作 件数DELETE の数秒後 100その32秒後 0適用を止めて32秒後 100昇格の直後 0
即時と遅延。守れる時間は違って見えますが、最後に行き着く状態に共通するものは何でしょうか。
「何もしなかったとき」に、それぞれ最終的に何件になったかを比べてください。
この章のまとめ
- スタンバイは主の WAL を再生する。誤った DELETE も同じく届き、実演では数秒以内に0件。
- 複製は機械や拠点の喪失から守る。
replication and redundancy are not recoverability。誤操作からは守らない。 - 遅延スタンバイは
opportunities to correct data loss errors。既定は0で、猶予が過ぎれば即時と同じ。 - 昇格すると遅延は効かない。実演では、止めてから昇格しても6回とも0件。
- 猶予の内にやることは、適用を止め、paused を確かめ、読み出すこと。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
SRE Book 第26章は、複製(replication)が守れるものとして何を挙げていますか。
用語集(3語)
- スタンバイ(レプリカ)
- 主から WAL レコードを受け取って再生し、同じ内容を持ち続ける DB。既定では受け取りしだい適用する。
- recovery_min_apply_delay
- スタンバイがコミットの適用を指定時間だけ遅らせる PostgreSQL の設定。既定は0。遅らせたスタンバイを本教材では遅延スタンバイと呼ぶ。
- 昇格(promote)
- スタンバイが回復を終え、書き込みを受け付ける主になること。遅延はこの時点で効かなくなる。
出典(一次ソース)
- PostgreSQL 18 Documentation — 19.6. Replication(recovery_min_apply_delay) ↗
- PostgreSQL 18 Documentation — 9.28. System Administration Functions(Recovery Control Functions) ↗
- Site Reliability Engineering, Chapter 26 — Data Integrity: What You Read Is What You Wrote(Copyright © 2017 Google, Inc. / CC BY-NC-ND 4.0) ↗