Chuyển đến nội dung chính

レッスン 15: 障害が発生したノードの回復

pg_rewind メカニズムを使用して、障害が発生したプライマリをクラスターに再結合し、必要に応じてバックアップからレプリカを再構築します。

🔒 DevSecOps — レッスン 15 レッスン 15: 障害が発生したノードの回復

Patroni と PostgreSQL の高可用性etcd

パート 3: クラスター管理

xdev.asia_

目標

このレッスンの後、次のことを行います:

  • フェールオーバー後に古いプライマリに再参加_
  • pg_rewind を使用してデータを再同期
  • レプリカを再構築するpg_basebackup_
  • タイムラインの相違を処理
  • スプリット ブレイン シナリオから回復_
  • Patroni で回復を自動化

1。ノード回復の概要

1.1。回復シナリオ_

いつノードを回復する必要がありますか?

シナリオ 1: フェールオーバー後の古いプライマリ_

Before:
node1 (primary) → FAILS
node2 (replica) → promoted to primary

After: node1: Needs rejoin as replica node2: Current primary

シナリオ 2: レプリカ切断済み

Before:
node3 (replica) → Network partition / Crash

After: node3: Needs to catch up with primary

シナリオ 3: ハードウェアの交換

Before:
node2: Disk failure

After: node2: New disk, needs full rebuild

シナリオ 4: タイムラインの相違

Before:
node1 accepted writes AFTER losing leader lock

After: node1: Diverged timeline, conflicts with cluster

1.2。回復方法_

_ ___HTMLTAG_139_ __
方法いつ使用する時間データ損失_
自動再参加ノードがクリーンアップされましたシャットダウン~10sなし
pg_rewindタイムライン分岐~1~5分なし
pg_basebackup_主要破損 / 完全な再構築_~30分+なし_
手動回復複雑なスプリットブレインシナリオさまざま可能

2.自動再参加 (Patroni のデフォルト)

2.1。自動再参加の仕組み_

ノードがオンラインに戻ったとき:

1. Patroni starts
2. Checks DCS for cluster state
3. Finds current leader (e.g., node2)
4. Compares local timeline with cluster timeline
5. If compatible → auto-rejoin as replica
6. If diverged → need pg_rewind or reinit

2.2。例: クリーンな再結合

Setup:

# Current cluster state
patronictl list postgres

+ Cluster: postgres ----+----+-----------+

| Member | Host | Role | State | TL | Lag in MB |

+--------+-------------+---------+---------+----+-----------+

| node1 | 10.0.1.11 | Leader | running | 2 | |

| node2 | 10.0.1.12 | Replica | running | 2 | 0 |

| node3 | 10.0.1.13 | Replica | running | 2 | 0 |

+--------+-------------+---------+---------+----+-----------+

ノード 3 をシミュレートする失敗:

# On node3: Stop Patroni cleanly
sudo systemctl stop patroni

Cluster now:

| node1 | 10.0.1.11 | Leader | running | 2 | |

| node2 | 10.0.1.12 | Replica | running | 2 | 0 |

| node3 | 10.0.1.13 | - | stopped | - | | ← Down

回復:_

# On node3: Start Patroni
sudo systemctl start patroni

Watch logs

sudo journalctl -u patroni -f

ログ出力_:

2024-11-25 10:00:00 INFO: Starting Patroni...
2024-11-25 10:00:01 INFO: Connected to DCS (etcd)
2024-11-25 10:00:02 INFO: Cluster timeline: 2, local timeline: 2 ✅
2024-11-25 10:00:03 INFO: Current leader: node1
2024-11-25 10:00:04 INFO: Rejoining as replica
2024-11-25 10:00:05 INFO: Starting PostgreSQL in recovery mode
2024-11-25 10:00:08 INFO: Replication started, streaming from node1
2024-11-25 10:00:10 INFO: Successfully rejoined cluster ✅

検証___HT MLTAG_195___:

patronictl list postgres

+ Cluster: postgres ----+----+-----------+

| Member | Host | Role | State | TL | Lag in MB |

+--------+-------------+---------+---------+----+-----------+

| node1 | 10.0.1.11 | Leader | running | 2 | |

| node2 | 10.0.1.12 | Replica | running | 2 | 0 |

| node3 | 10.0.1.13 | Replica | running | 2 | 0 | ← Rejoined!

+--------+-------------+---------+---------+----+-----------+

時間: ~10 秒✅

2.3。自動再参加の構成

# In patroni.yml
postgresql:
use_pg_rewind: true  # Enable automatic pg_rewind if needed
remove_data_directory_on_rewind_failure: false  # Safety
remove_data_directory_on_diverged_timelines: false  # Safety

Patroni will attempt:

1. Auto-rejoin (if timelines match)

2. pg_rewind (if timeline diverged but recoverable)

3. Full reinit (if pg_rewind fails and auto-reinit enabled)

3。 pg_rewind

3.1 を使用します。 pg_rewind とは何ですか?

pg_rewind = 現在のタイムラインから分岐 の PostgreSQL インスタンスを再同期するツール。

いつ必要:

Scenario: Old primary received writes AFTER failover

Timeline: T+0: node1 (primary), node2 (replica) T+1: Network partition T+2: node2 promoted (timeline: 1 → 2) T+3: node1 still thinks it's primary, accepts writes (timeline: 1) T+4: Network restored T+5: Conflict! node1 timeline=1, cluster timeline=2

Solution: pg_rewind node1 to match node2's timeline

仕組み:

1. Find common ancestor (last shared WAL position)
2. Replay WAL from new primary
3. Overwrite conflicting blocks
4. Node rejoins as replica on new timeline

3.2。 pg_rewind

要件:

# In patroni.yml → postgresql.parameters
wal_log_hints: 'on'  # Required! (or use full_page_writes)

Or use data checksums (set during initdb):

initdb --data-checksums

Also ensure:

max_wal_senders: 10 # For replication wal_level: replica # For replication

__ _HTMLTAG_228___その理由wal_log_hints?

Without wal_log_hints:
pg_rewind cannot determine which blocks changed
→ Cannot resync
→ Must use full rebuild (pg_basebackup)

With wal_log_hints: PostgreSQL tracks all block changes → pg_rewind can identify divergence → Fast resync ✅

Trade-off: ~1-2% write performance overhead

3.3。手動 pg_rewind_

シナリオ: ノード 1 (古いプライマリ) はフェイルオーバー後に再同期する必要があります。

ステップ 1: PostgreSQL を停止するnode1_

# On node1
sudo systemctl stop patroni
sudo systemctl stop postgresql

ステップ 2: pg_rewind の実行_

# On node1: Rewind to match node2 (current primary)
sudo -u postgres pg_rewind 
--target-pgdata=/var/lib/postgresql/18/data
--source-server="host=10.0.1.12 port=5432 user=replicator dbname=postgres"
--progress
--debug

Output:

connected to server

servers diverged at WAL location 0/3000000 on timeline 1

rewinding from last common checkpoint at 0/2000000 on timeline 1

reading source file list

reading target file list

reading WAL in target

need to copy 124 MB (total source directory size is 2048 MB)

creating backup label and updating control file

syncing target data directory

Done!

ステップ 3: 作成standby.signal_

# On node1: Mark as standby
sudo -u postgres touch /var/lib/postgresql/18/data/standby.signal

ステップ 4:primary_conninfo を更新

# On node1: Point to new primary (node2)
sudo -u postgres tee /var/lib/postgresql/18/data/postgresql.auto.conf <<EOF
primary_conninfo = 'host=10.0.1.12 port=5432 user=replicator password=replica_password'
EOF

ステップ 5:開始PostgreSQL_

# On node1
sudo systemctl start patroni

Patroni will start PostgreSQL in recovery mode

ステップ 6: 確認_

patronictl list postgres

node1 should now be a Replica following node2 ✅

時間: ~1 ~ 5 分 (相違に応じて)サイズ)

3.4。自動 pg_rewind (Patroni)

有効にするpatroni.yml:

# Patroni will automatically run pg_rewind if needed
postgresql:
use_pg_rewind: true

parameters: wal_log_hints: 'on' # Required!

動作:

When node rejoins after failover:

  1. Patroni detects timeline divergence
  2. Automatically runs pg_rewind
  3. Restarts PostgreSQL as replica
  4. Node rejoins cluster

No manual intervention needed! ✅

例ログ_:

2024-11-25 10:05:00 INFO: Local timeline 1, cluster timeline 2
2024-11-25 10:05:01 WARNING: Timeline divergence detected
2024-11-25 10:05:02 INFO: use_pg_rewind enabled, attempting rewind...
2024-11-25 10:05:03 INFO: Running pg_rewind...
2024-11-25 10:05:45 INFO: pg_rewind completed successfully
2024-11-25 10:05:46 INFO: Starting PostgreSQL as replica
2024-11-25 10:05:50 INFO: Rejoined cluster ✅

4。 pg_basebackup

4.1 を使用して完全に再構築します。 pg_basebackup を使用する場合

ユースケース:

  1. pg_rewind 失敗_ - データも分岐_
  2. 破損が検出されました - データの整合性の問題_
  3. メジャーバージョンアップグレード - 異なる PostgreSQLバージョン_
  4. 新しいノード_ - クラスターに新しいレプリカを追加
  5. ディスクを交換 - 空のデータディレクトリ_
  6. 偏執的な安全性 - クリーンな状態を保証したい

トレードオフ: 速度は遅くなりますが (大規模な DB の場合は約 30 分~2 時間)、保証されています

4.2。手動 pg_basebackup

ステップ 1: ノードの停止とクリーン

# On node to rebuild (e.g., node3)
sudo systemctl stop patroni
sudo systemctl stop postgresql

Remove old data directory

sudo rm -rf /var/lib/postgresql/18/data/*

ステップ 2: ベース バックアップの取得プライマリ_

# On node3: Backup from current primary (node2)
sudo -u postgres pg_basebackup 
-h 10.0.1.12
-p 5432
-U replicator
-D /var/lib/postgresql/18/data
-Fp
-Xs
-P
-R

Flags:

-h: Host (primary)

-U: Replication user

-D: Target data directory

-Fp: Plain format (not tar)

-Xs: Stream WAL during backup

-P: Show progress

-R: Create standby.signal and replication config

出力:_

Password: [enter replicator password]
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/4000000 on timeline 2
pg_basebackup: starting background WAL receiver
24567/24567 kB (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 0/4000168
pg_basebackup: syncing data to disk ...
pg_basebackup: base backup completed

ステップ 3: 構成の確認

# On node3: Check standby.signal created
ls /var/lib/postgresql/18/data/standby.signal

Check primary_conninfo

cat /var/lib/postgresql/18/data/postgresql.auto.conf | grep primary_conninfo

ステップ 4: ノードの開始

# On node3
sudo systemctl start patroni

Node will rejoin as replica

ステップ 5: _

patronictl list postgres

node3 should be streaming from primary ✅

Time: ~30分~2時間(データベースのサイズによって異なります)

4.3を確認します。 Patroni の自動再初期化

有効にする自動再初期化:

# In patroni.yml
postgresql:
use_pg_rewind: true

If pg_rewind fails, auto-reinit

remove_data_directory_on_rewind_failure: true remove_data_directory_on_diverged_timelines: true

WARNING: Data directory will be DELETED and recreated

Only enable if you trust automation!

動作:

When node rejoins:

  1. Try auto-rejoin → FAILED (diverged)
  2. Try pg_rewind → FAILED (corruption)
  3. Automatically remove data directory
  4. Run pg_basebackup from current primary
  5. Rejoin as replica

Fully automated! But destructive! ⚠️

4.4。 Patroni 再初期化コマンド_

手動トリガー:

# Force reinit on node3
patronictl reinit postgres node3

Patroni will:

1. Stop PostgreSQL on node3

2. Remove data directory

3. Run pg_basebackup from leader

4. Start as replica

Prompt:

Are you sure you want to reinitialize members node3? [y/N]: y

Monitor進行状況_:

# On node3: Watch logs
sudo journalctl -u patroni -f

Expected:

INFO: Removing data directory...

INFO: Running pg_basebackup...

INFO: Backup completed (24 GB in 15 minutes)

INFO: Starting PostgreSQL...

INFO: Rejoined cluster ✅

5。タイムラインの相違の解決

5.1。タイムラインについて

タイムライン = 履歴ブランチカウンター

Initial:
Timeline 1 (all nodes)

After first failover: Old primary: Timeline 1 New primary: Timeline 2 ← Incremented

After second failover: Timeline 3 ← Incremented again

タイムラインを使用する理由存在:

Prevent data conflict:
If two nodes both think they're primary,
they write on different timelines.
→ Conflict detected
→ Manual intervention required

5.2。タイムラインの相違の検出

ローカル タイムラインを確認:

# On any node
sudo -u postgres psql -c "
SELECT timeline_id
FROM pg_control_checkpoint();
"

Example:

timeline_id

------------

2

クラスターを確認タイムライン_:

# Via Patroni
patronictl list postgres | head -2

+ Cluster: postgres (7001234567890123456) ----+----+-----------+

↑ Timeline in cluster ID

Or via REST API

curl -s http://10.0.1.12:8008/patroni | jq '.timeline'

Output: 2

比較:_

# If node timeline ≠ cluster timeline

→ Node needs pg_rewind or reinit

5.3。シナリオ: スプリット ブレイン後のタイムラインの分岐_

セットアップ_:_

T+0: 3-node cluster, node1 = primary (timeline 2)
T+1: Network partition splits node1 from node2/node3
T+2: node1 thinks it's still primary (timeline 2)
T+3: node2/node3 elect node2 as primary (timeline 3)
T+4: Both node1 and node2 accept writes!

  • node1: timeline 2, accepting writes ❌
  • node2: timeline 3, accepting writes ✅
  • Split-brain! ⚠️ T+5: Network restored T+6: Conflict detected

解決__ HTMLTAG_403__:

# Step 1: Verify which timeline is "correct"
patronictl list postgres

+ Cluster: postgres ----+----+-----------+

| Member | Host | Role | State | TL | Lag in MB |

+--------+-------------+---------+---------+----+-----------+

| node1 | 10.0.1.11 | - | stopped | 2 | | ← WRONG timeline

| node2 | 10.0.1.12 | Leader | running | 3 | | ← CORRECT

| node3 | 10.0.1.13 | Replica | running | 3 | 0 |

+--------+-------------+---------+---------+----+-----------+

Step 2: Save diverged data from node1 (if needed)

sudo -u postgres pg_dumpall -h 10.0.1.11 > /backup/node1-diverged-data.sql

Step 3: Rewind node1 to match timeline 3

If pg_rewind works:

patronictl reinit postgres node1

If pg_rewind fails (likely due to significant divergence):

Manual pg_basebackup required

sudo systemctl stop patroni # On node1 sudo rm -rf /var/lib/postgresql/18/data/* sudo -u postgres pg_basebackup -h 10.0.1.12 -D /var/lib/postgresql/18/data -U replicator -R -P sudo systemctl start patroni

Step 4: Manually reconcile diverged data (if important)

Review /backup/node1-diverged-data.sql

Manually merge important transactions into node2

予防:_

# Configure Patroni to prevent split-brain
bootstrap:
dcs:
# Primary loses leader lock → immediately demote
ttl: 30
retry_timeout: 10

postgresql: parameters: # Prevent writes if not sure about leadership synchronous_commit: 'remote_apply' # Requires sync replica

6。スプリット ブレインの予防と回復

6.1。 Patroni によるスプリット ブレインの防止方法

メカニズム: DCS リーダー ロック

Primary MUST hold leader lock in DCS:

If primary loses DCS connection:

  1. Cannot renew leader lock
  2. TTL expires (e.g., 30 seconds)
  3. Primary DEMOTES itself (becomes read-only)
  4. Replicas detect no leader
  5. Election begins

Key: Primary NEVER operates without DCS lock ✅

コード フロー(疑似):

while True:
if is_leader:
if can_renew_leader_lock():
# Still leader, continue
accept_writes()
else:
# Lost DCS connection!
log.error("Lost leader lock, DEMOTING!")
demote_to_replica()
reject_writes()

sleep(loop_wait)

6.2。フェンシングメカニズム_

PostgreSQL レベルのフェンシング:

-- When demoted, set read-only
ALTER SYSTEM SET default_transaction_read_only = 'on';
SELECT pg_reload_conf();

-- All new transactions will fail: -- ERROR: cannot execute INSERT in a read-only transaction

OS レベルのフェンシング(上級):

# STONITH (Shoot The Other Node In The Head)

Via callbacks in patroni.yml

callbacks: on_start: /var/lib/postgresql/callbacks/on_start.sh on_stop: /var/lib/postgresql/callbacks/on_stop.sh on_role_change: /var/lib/postgresql/callbacks/on_role_change.sh

on_role_change.sh example:

#!/bin/bash ROLE=$1 # "master" or "replica"

if [ "$ROLE" == "replica" ]; then

Lost leadership, ensure NO writes possible

sudo iptables -A INPUT -p tcp --dport 5432 -j REJECT

Block incoming connections to PostgreSQL

fi

if [ "$ROLE" == "master" ]; then

Gained leadership, allow writes

sudo iptables -D INPUT -p tcp --dport 5432 -j REJECT fi

6.3。シナリオ: スプリット ブレインからの回復_

検出:_

# Symptoms:

- Multiple nodes claim to be primary

- Patroni shows errors

- Applications seeing inconsistent data

Check cluster state

patronictl list postgres

If you see multiple "Leader" or conflicts:

SPLIT-BRAIN DETECTED! ⚠️

回復ステップ_:

# Step 1: STOP ALL NODES immediately
for node in node1 node2 node3; do
ssh $node "sudo systemctl stop patroni"
done

Step 2: Determine "source of truth"

Usually: Node with most recent data / highest timeline

for node in node1 node2 node3; do echo "=== $node ===" ssh $node "sudo -u postgres psql -c " SELECT timeline_id, pg_last_wal_receive_lsn() FROM pg_control_checkpoint(); "" done

Step 3: Choose winner (e.g., node2 has highest timeline)

WINNER="node2"

Step 4: Backup diverged data from losers

ssh node1 "sudo -u postgres pg_dumpall > /backup/node1-diverged.sql" ssh node3 "sudo -u postgres pg_dumpall > /backup/node3-diverged.sql"

Step 5: Wipe losers and rebuild from winner

for node in node1 node3; do ssh $node "sudo rm -rf /var/lib/postgresql/18/data/*" ssh $node "sudo -u postgres pg_basebackup
-h $WINNER
-D /var/lib/postgresql/18/data
-U replicator -R -P" done

Step 6: Clear DCS state (fresh start)

etcdctl del --prefix /service/postgres/

Step 7: Start winner first

ssh $WINNER "sudo systemctl start patroni"

Wait for winner to become leader

sleep 10

Step 8: Start other nodes

ssh node1 "sudo systemctl start patroni" ssh node3 "sudo systemctl start patroni"

Step 9: Verify cluster

patronictl list postgres

Should show:

node2: Leader

node1: Replica (following node2)

node3: Replica (following node2)

All same timeline ✅

Step 10: Reconcile diverged data manually

Review /backup/*-diverged.sql files

Merge critical transactions if needed

7。ノード回復のモニタリング_

7.1。主要な指標_

-- Replication status
SELECT application_name,
state,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes,
replay_lag,
sync_state
FROM pg_stat_replication;

-- Timeline check SELECT timeline_id FROM pg_control_checkpoint();

-- Recovery status (on replica) SELECT pg_is_in_recovery(), pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn(), pg_wal_lsn_diff(pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn()) AS replay_lag_bytes;

7.2。 Patroni REST API モニタリング

# Check node status
curl -s http://10.0.1.11:8008/patroni | jq

Key fields:

{

"state": "running",

"role": "replica",

"timeline": 3,

"replication": [

{

"usename": "replicator",

"application_name": "node1",

"state": "streaming",

"sync_state": "async",

"replay_lsn": "0/5000000"

}

]

}

7.3。回復の問題に関する警告

# Prometheus alert
groups:

  • name: node_recovery rules:
    • alert: PatroniNodeDown expr: up{job="patroni"} == 0 for: 1m labels: severity: warning annotations: summary: "Patroni node {{ $labels.instance }} is down"

    • alert: PatroniTimelineMismatch expr: | count by (cluster) (patroni_timeline) != count by (cluster, timeline) (patroni_timeline) labels: severity: critical annotations: summary: "Timeline mismatch detected - possible split-brain"

    • alert: PatroniReplicationLagHigh expr: patroni_replication_lag_bytes > 104857600 # 100MB for: 5m labels: severity: warning annotations: summary: "Replication lag > 100MB on {{ $labels.instance }}"

8。ベスト プラクティス

✅ DO

  1. wal_log_hints を有効にする - pg_rewind に必須
  2. 回復を定期的にテスト - 毎月の訓練
  3. タイムラインを監視 - アラート分岐
  4. バックアップを用意してください - 危険な操作の前に
  5. 手順を文書化__HTMLTAG_472___ -ランブック_
  6. Patroni 自動回復を使用 - 手動による介入を軽減_
  7. 回復後に検証 - テストレプリケーション、クエリ
  8. DCS を健全に保つ - etcd クラスターが重要
  9. すべてをログに記録 - 監査証跡インシデント_
  10. スプリットブレインリカバリの練習 - 必要ないことを願っていますが、準備はしておいてください

❌しないでください_

  1. wal_log_hints をスキップしないでください - pg_rewind は失敗します_
  2. 自動回復を想定しないでください動作 - テストしてください!
  3. タイムラインを無視しないでください - 重大な問題_
  4. 回復中は手動で昇格しないでください - Patroni ハンドル_
  5. バックアップせずにデータを削除しないでください - 分岐したデータが重要である可能性があります
  6. スプリットブレイン クラスターを実行しないでください - 修正すぐに
  7. コールバックを忘れない - フェンシング防止スプリットブレイン_
  8. 再初期化を過度に自動化しない - リスクデータ損失_

9。ラボ演習

ラボ 1: クリーン シャットダウン後の自動再参加

タスク:

  1. 1 つのレプリカを停止します: sudo systemctl stop patroni
  2. プライマリを変更
  3. レプリカを開始: sudo systemctl start patroni_
  4. 自動再参加と遅延を確認するキャッチアップ
  5. 回復の時間を計る_

ラボ 2: シミュレーション後の pg_rewindフェイルオーバー

タスク:

  1. 現在のプライマリを記録
  2. プライマリを手動で停止: sudo systemctl stop patroni_
  3. フェールオーバーが完了するまで待ちます
  4. 古いプライマリを開始します (自動巻き戻されるはずです)
  5. 古いプライマリがレプリカとして再結合していることを確認します_
  6. タイムラインを確認します増分_

ラボ 3: pg_basebackup を使用した完全な再構築_

タスク:

  1. レプリカの停止_
  2. データ ディレクトリの削除: sudo rm -rf /var/lib/postgresql/18/data/*
  3. プライマリから pg_basebackup を手動で実行_
  4. レプリケーションを開始_
  5. レプリケーションが復元されたことを確認
  6. リビルドを測定する時間

ラボ 4: Patroni 再初期化コマンド

タスク:

  1. 使用patronictl postgres ノード 3 を再起動
  2. プロセス中のログを監視
  3. 自動再構築を確認_
  4. 時間と手動 pg_basebackup の比較

ラボ 5: タイムライン分岐シミュレーション

タスク:

  1. ネットワークパーティション(iptables)の作成
  2. フェイルオーバーを待機_
  3. 手動で昇格古いプライマリ (強制スプリット ブレイン)
  4. 両方の「プライマリ」に異なるデータを書き込む
  5. ネットワークを復元
  6. 競合検出を監視
  7. リカバリを実践する手順

10。トラブルシューティング

問題: pg_rewind が失敗する

エラー: pg_rewind: 致命的: 共通のものが見つかりませんでした祖先

原因: wal_log_hints が有効になっていない、またはデータが多すぎる

解決策:

# Check wal_log_hints
sudo -u postgres psql -c "SHOW wal_log_hints;"

If off, enable:

sudo -u postgres psql -c "ALTER SYSTEM SET wal_log_hints = on;" sudo systemctl restart postgresql

If still fails, use pg_basebackup instead

patronictl reinit postgres node1

問題: レプリカがリカバリ中に停止

症状_: レプリカが表示される「実行中」だが遅延が大きい。

診断:

# Check replication status
sudo -u postgres psql -h 10.0.1.11 -c "
SELECT * FROM pg_stat_replication;
"

Check replica logs

sudo journalctl -u postgresql -n 100

一般的な原因:

  • WAL受信機のクラッシュ
  • ネットワークの問題
  • レプリカのディスクがいっぱい
  • アーカイブの復元エラー_

解決策:

# Restart replication
sudo systemctl restart patroni

If persists, reinit

patronictl reinit postgres node3

問題:リカバリ_

エラー: FATAL: データベース システムが起動中

原因: PostgreSQL がまだ再生中WAL.

解決策: 回復が完了するまで待つか、ログでエラーを確認してください。

# Check recovery progress
sudo -u postgres psql -h 10.0.1.13 -c "
SELECT pg_is_in_recovery(),
pg_last_wal_receive_lsn(),
pg_last_wal_replay_lsn();
"

11。概要

回復方法の概要

方法速度データ損失ユースケース
_自動再参加最速なしクリーンなシャットダウン/再起動
pg_rewind___HTMLTAG_7 32___高速_なしタイムライン相違
pg_basebackup_遅いなし破損、重大発散
手動回復変動可能スプリットブレイン、複雑問題_

重要な概念

✅ 自動再参加 - Patroni はクリーン リカバリを処理します自動的に_

✅ pg_rewind - タイムラインの分岐後に再同期します (必須wal_log_hints)

✅ pg_basebackup - プライマリからの完全な再構築 (遅いが、安全)

✅ タイムライン - 履歴ブランチ、増分オンフェイルオーバー

✅ スプリットブレイン - 複数のプライマリ (DCS リーダー ロックにより防止)

リカバリチェックリスト_

  •  ノード障害が検出されました
  •  必要な回復方法を決定_
  •  分岐したデータをバックアップする任意)
  •  リカバリの実行 (自動または手動)
  •  タイムラインがクラスタと一致することを確認
  •  レプリケーションストリーミングを確認
  •  読み取り/書き込みをテストする操作
  •  レプリケーションラグの確認
  •  監視/ドキュメントの更新

次のステップ

レッスン 16 では、表紙 バックアップとポイントインタイムリカバリ:

  • pg_basebackup戦略
  • WALアーカイブ構成_
  • ポイントインタイムリカバリ(PITR)手順_
  • バックアップの自動化とスケジュール
  • 災害復旧計画