🔁

PostgreSQL データベースサーバを冗長化(ストリーミングレプリケーション)する

に公開

この記事では、データの消失を防ぐために、PostgreSQL データベースサーバを冗長化し、データの消失被害を最小限にする。

ターゲット

  • ✅ 冗長化によってデータの消失を防ぎたい
  • ✅ 問題が発生した時、手動で主系と従系を切り替えたい
  • ✅ 負荷分散を目的としない

スタート地点

  • ✅ 主系と従系の PostgreSQL サーバのセットアップがそれぞれ完了している(ただし、Docker や VM などの手段は問わない)
  • ✅ ssh や telnet でホストに接続したり、あるいは pgadminDBeaver などのデータベース管理ソフトを利用して、 postgres コマンドなど,標準ツールチェーンに相当する操作をすることができる

用語

主系

メインで利用するサーバ。記事によっては「マスタ(サーバ)」「プライマリ(サーバ)」などと呼ばれる。

従系

バックアップのために利用するサーバ。記事によっては「スレーブ(サーバ)」「セカンダリ(サーバ)」「レプリケーションサーバ」「スタンバイサーバ」などと呼ばれる。

Write Ahead Logging (WAL)

和訳では、「ログ先行書き込み」。トランザクションのログを残すための一般的な手法で、データベースがどのタイミングでどのように更新されたかを詳細に記録する。

ストリーミングレプリケーション

データベース全体を複製するクラスタ単位でのレプリケーションの仕組み。この記事ではこちらを採用する。主系で出力された WAL を従系に転送し、従系はその WAL を利用して状態を同期する。従系は設定により、参照用として利用することができる。対義語に「ロジカルレプリケーション」がある。

操作

①【主系】postgresql.conf を変更する

/var/lib/pgsql/{version}/data/postgresql.conf を開き、以下の 3 つの行を編集する。もし、該当行がコメントアウトされている場合は、解除する。

listen_addresses = '*'
max_wal_senders = 10 
synchronous_standby_names = 'YOUR_SYNCHRONOUS_STANDBY_NAME'

各行の値は次のとおり。その他カスタマイズできる設定は ドキュメント に存在する。

  • listen_addresses: データベースサーバが接続を許可するホスト名または IP アドレス
  • max_wal_senders: WAL で生成したログを同時にやり取りできるホスト数を指定する
  • synchronous_standby_names: 従系のサーバ名。ホスト名ではなく、従系の application_name に指定した値を利用する(後述)。ワイルドカードでの指定も可能だが、セキュリティに注意すること。

②【主系】pg_hba.conf を変更する

以下を追記する。

host    replication    all    [従系の IP アドレス]/32    trust

その後、主系を再起動すること。

③【従系】主系の情報を取得する

以下のコマンドを実行する。

rm -rf /var/lib/pgsql/*
pg_basebackup -R -D /var/lib/pgsql/ -h [プライマリ側のIPアドレス]

④【従系】postgresql.auto.conf を変更する

pg_basebackup コマンドによって、postgresql.auto.confが自動生成される。末尾に、以下のapplication_name={②でsynchronous_standby_namesに指定した値} の形の文字列を追加すること。

- primary_conninfo = 'user=postgres passfile=''/var/lib/pgsql/.pgpass'' channel_binding=prefer host=[プライマリ側のIPアドレス] port=5432 sslmode=prefer sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any'
+ primary_conninfo = 'user=postgres passfile=''/var/lib/pgsql/.pgpass'' channel_binding=prefer host=[プライマリ側のIPアドレス] port=5432 sslmode=prefer sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any application_name=YOUR_SYNCHRONOUS_STANDBY_NAME'

⑤【従系】postgresql.conf を変更する

pg_basebackup を実行すると,主系は postgresql.conf 従系にそのままコピーされる。①で指定したうち、listen_addresses 以外の変更行をすべてコメントアウトする。

listen_addresses = '*'
# max_wal_senders = 10 
# synchronous_standby_names = 'YOUR_SYNCHRONOUS_STANDBY_NAME'

その後、従系を再起動する。

テスト実行

主系でデータベースの何らかの CRUD の C や U や D を発行し、従系で意図した結果に READ できるかどうか試す。問題なく実行できれば、動作は正常である。

おわりに

おわる

Discussion