[Database] PostgreSQLクラスタの同期が崩れたときの対処・・・の一例

Mastodon環境で動いてるデータベース

今はこんな構造で動いてます。

今構成してるPostgreSQLの構成

実はHAクラスタについて、少し学ぶ必要があったのでPacemaker + Corosync + pcsd + PostgreSQL Streaming Replicationによる構成で自宅環境に組み込んでみた感じです。それぞれ

  • S-LAN:192.168.200.0/24…サービス提供用
  • D-LAN:192.168.110.0/24…レプリケーション用
  • IC-LAN:192.168.120.0/24…インターコネクト

と言う役割のネットワークに2ノードで組んでいたりします。これで可用性もバッチリだむふふと思ったらそうは問屋が卸しませんで。

よりによってバックアップ処理が・・

困ったことにバックアップ処理に問題がありまして。
ある日のこと、ZABBIXの監視ダッシュボードにドギャーン!

200090_SNSDB-VirtualNode/pacemaker: Probably cluster migration detected (hostname was changed)

と言うのは、バックアップはVEEAM Backup & Recovery Community Editionを使ってVADPバックアップをしてるのですが、どうやらこのバックアップ処理時、特にバックアップ終了後のSnapshot削除処理でIOが一時的に停滞しているところをPacemakerが検知してしまって障害の原因になってるようです。

2号機に切り替わるのでそれ自体は良いんですが、困ったのがWALログの不整合です。

FATAL:  could not start WAL streaming: ERROR:  requested starting point 2/9C000000 on timeline 8 is not in this server's history

1号機が異常終了したと見做されダウンするんで、再度DBを立ち上げるとサービスは起動して、Slaveとして起動はしますが、ログを見ると上記のエラーを繰り返すばかりで何も同期されなくなります。

と言うわけで復帰手順を備忘録。

まずはクラスタをメンテナンスモードにします。

pcs property set maintenance-mode=true

これでクラスタリソースは全てUnmanagedになります。
続いて以下のコマンドでPostgreSQLユーザにスイッチしたのち、あらかたの既存データを削除します。

■DB停止(Slave側)
/usr/pgsql-10/bin/pg_ctl stop -D /data/pgsql/data

■データ削除
rm -rf /data/pgsql/pg_archivelog/*
rm -rf /data/pgsql/data/*

アーカイブログが残ってるとWAL更新に影響が出る場合があるので一旦削除します。
そして、現在動いてる2号機からVirtual IPアドレスを通じてベースとなるデータを採取します。

/usr/pgsql-10/bin/pg_basebackup -h 192.168.110.90 -U postgres -D /data/pgsql/data -X stream -P

我が家の環境、このクラスタノード間のレプリケーションセグメントは10GbEなもんだから思った以上に速い。2GB程度のデータしかないこともあり、1分程度で同期が行えました。この後はあらかじめ退避させていた recovery.conf なんかを復帰させた上で、

cp /data/pgsql/data/recovery.conf /data/pgsql/data

PostgreSQLユーザセッションを終了し、メンテナンスモードを解除。

pcs property set maintenance-mode=false
pcs resource cleanup

併せて立ち上がっている障害フラグを倒したらPostgreSQLは起動してSlaveとして動作するようになります。取り敢えず以下のようなログが出てきたら大丈夫そうです。

2020-08-04 22:20:06.844 JST [18203] LOG:  received promote request
2020-08-04 22:20:06.844 JST [18203] LOG:  redo done at 2/9F000028
2020-08-04 22:20:06.844 JST [18203] LOG:  last completed transaction was at log time 2020-08-04 22:20:03.893851+09
2020-08-04 22:20:06.854 JST [18203] LOG:  selected new timeline ID: 10
2020-08-04 22:20:06.880 JST [18203] LOG:  archive recovery complete
2020-08-04 22:20:06.892 JST [18174] LOG:  database system is ready to accept connections

実際にはcpコマンドの失敗結果なんかが出たりするんですが、多分それ自体は問題なさそうです。

恐らくIOフリーズを想定したリソース管理が出来てないから障害になってるんだろうなーと言うのは想定できていて、これを如何に修正していくかが重要かなーなんて思ったりしています。もうちょっと勉強せんとわからんな・・