PostgreSQLはストリーミングレプリケーションと呼ばれるデータコピーの仕組みがあります。このページではカースケイド構成(多段構成)のレプリケーションの設定例を紹介します。
- PostgreSQL インストール
- PostgreSQL データベースの作成
- PostgreSQL contribモジュールの使い方
- PostgreSQL パラメタの設定方法
- PostgreSQL ベンチマークツールの紹介
- PostgreSQL WAL(Write Ahead Log)の基本説明
- PostgreSQL バックアップとリストア
- PostgreSQL PITR(Point In Time Recovery)基本概念の説明
- PostgreSQL PITR(Point In Time Recovery)操作方法の説明
- PostgreSQL PITR(Point In Time Recovery)タイムライン操作
- PostgreSQL ストリーミングレプリケーションの最小構成
- PostgreSQL ストリーミングレプリケーションのパラメタ説明
- PostgreSQL ストリーミングレプリケーションの障害復旧
- PostgreSQL ストリーミングレプリケーションの多段構成 (いまここ)
- PostgreSQL ストリーミングレプリケーションのDR向け設定
- PostgreSQL ストリーミングレプリケーションのコンフリクト
- PostgreSQL 自動バキューム(AUTO VACUUM)
- PostgreSQL HOT(Heap Only Tuple)
- PostgreSQL インデックスのメンテナンス
- PostgreSQL 統計情報の更新
- PostgreSQL 実行計画
- PostgreSQL スロークエリの調査方法
動作確認構成
以下の環境で動作確認を行います。
+------------------+ +------------------+ | 192.168.56.10/24 |---->| 192.168.56.11/24 | | centos10 | | centos11 | | (primary) | +--| (secondary) | +------------------+ | +------------------+ | | +------------------+ +->| 192.168.56.12/24 | | centos12 | | (secondary) | +------------------+
構築例
マスターサーバの構築
postgresql.confおよびpg_hba.confに以下を加筆します。
cat << EOF >> /var/lib/pgsql/13/data/postgresql.conf listen_addresses = '0.0.0.0' max_wal_senders = 10 synchronous_commit = 'remote_write' synchronous_standby_names = 'centos11' EOF cat << EOF >> /var/lib/pgsql/13/data/pg_hba.conf host replication postgres 192.168.56.0/24 trust EOF
再起動し設定を反映させます。
systemctl restart postgresql-13.service
スタンバイサーバ1台目の構築
pg_basebackupコマンドを使用して、プライマリサーバのデータを1台目スタンバイサーバへコピーします。
pg_basebackup -R -D ${PGDATA} -h 192.168.56.10
postgresql.auto.confのsynchronous_standby_namesにapplication_nameを加筆します。
# vi /var/lib/pgsql/13/data/postgresql.auto.conf primary_conninfo = 'user=postgres <omitted> application_name=centos11'
postgresql.confをスタンバイ1台目から2台目へレプリケーションできるような設定に変更します。
具体的にはsynchronous_standby_namesをcentos11からcentos12へ変更します。
MySQLでは多段レプリケーションを実現するには–log-slave-updatesという明示的な設定が必要でしたが、PostgreSQLでは明示設定なしに多段レプリケーションを実現する事ができます。
# vi /var/lib/pgsql/13/data/postgresql.conf listen_addresses = '0.0.0.0' max_wal_senders = 10 synchronous_commit = 'remote_write' synchronous_standby_names = 'centos12'
postgresqlを起動します。
systemctl start postgresql-13.service
レプリケーションが開始された旨のログを確認します。
[root@centos11 ~]# tail -n 3 /var/lib/pgsql/13/data/log/postgresql-Sun.log 2020-12-27 19:41:25.355 JST [1131] LOG: 0/2000100 でリカバリの一貫性が確保されました 2020-12-27 19:41:25.355 JST [1128] LOG: データベースシステムはリードオンリー接続の受け付け準備ができました 2020-12-27 19:41:25.459 JST [1135] LOG: プライマリのタイムライン1の 0/3000000からでWALストリーミングを始めます
スタンバイサーバ2台目の構築
pg_basebackupコマンドを使用して、スタンバイサーバ1台目のデータをスタンバイサーバ2台目へコピーします。
pg_basebackup -R -D ${PGDATA} -h 192.168.56.11
postgresql.auto.confのsynchronous_standby_namesにapplication_nameを加筆します。また、スタンバイサーバ1台目から引き継いだprimary_conninfoの設定を削除またはコメントアウトします。
# vi /var/lib/pgsql/13/data/postgresql.auto.conf # primary_conninfo = <omitted> primary_conninfo = 'user=postgres <omitted> application_name=centos12'
postgresql.confについてスタンバイサーバ1台目から引き継いだ設定をコメントアウトします。
# vi /var/lib/pgsql/13/data/postgresql.conf #listen_addresses = '0.0.0.0' #max_wal_senders = 10 #synchronous_commit = 'remote_write' #synchronous_standby_names = 'centos12'
postgresqlを起動します。
systemctl start postgresql-13.service
レプリケーションが開始された旨のログを確認します。
[root@centos12 ~]# tail -n 3 /var/lib/pgsql/13/data/log/postgresql-Sun.log 2020-12-27 19:57:58.406 JST [1127] LOG: 0/3000148のレコード長が不正です:長さは24である必要がありますが、実際は0でした 2020-12-27 19:57:58.406 JST [1124] LOG: データベースシステムはリードオンリー接続の受け付け準備ができました 2020-12-27 19:57:58.570 JST [1131] LOG: プライマリのタイムライン1の 0/3000000からでWALストリーミングを始めます
プライマリサーバに何らかのデータを書き込みます。
[postgres@centos10 ~]$ psql -c "CREATE DATABASE test" CREATE DATABASE [postgres@centos10 ~]$
2台目のスタンバイサーバまでレプリケーションされている事を確認します。
[postgres@centos12 ~]$ psql -l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres test | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | (4 rows)
障害復旧例
プライマリサーバへの昇格
centos10に障害が発生し、centos11がスタンバイからプライマリへ昇格するシナリオを想定して動作確認を行います。
+------------------+ +------------------+ | 192.168.56.10/24 |---->| 192.168.56.11/24 | | centos10 | | centos11 | | (out of order) | +--| (primary) | +------------------+ | +------------------+ | | +------------------+ +->| 192.168.56.12/24 | | centos12 | | (secondary) | +------------------+
pg_ctl promoteコマンドを使用してスタンバイからプライマリへ昇格させます。
[postgres@centos11 ~]$ /usr/pgsql-13/bin/pg_ctl promote waiting for server to promote.... done server promoted [postgres@centos11 ~]$
この時、タイムラインが1から2になった事に留意ください。
[postgres@centos11 ~]$ tail -n 20 /var/lib/pgsql/13/data/log/postgresql-Sun.log 2020-12-27 19:41:25.355 JST [1128] LOG: データベースシステムはリードオンリー接続の受け付け準備ができました 2020-12-27 19:41:25.459 JST [1135] LOG: プライマリのタイムライン1の 0/3000000からでWALストリーミングを始めます 2020-12-27 20:00:52.227 JST [1131] LOG: 昇格要求を受信しました 2020-12-27 20:00:52.227 JST [1135] FATAL: 管理者コマンドにより WAL 受信プロセスを終了しています 2020-12-27 20:00:52.229 JST [1131] LOG: 0/30009C8のレコード長が不正です:長さは24である必要がありますが、実際は0でした 2020-12-27 20:00:52.229 JST [1131] LOG: REDOが0/3000990で終了しました 2020-12-27 20:00:52.229 JST [1131] LOG: 最後に完了したトランザクションのログ時刻は2020-12-27 19:58:48.115269+09でした 2020-12-27 20:00:52.230 JST [1131] LOG: 新しいタイムラインIDを選択: 2 2020-12-27 20:00:52.287 JST [1131] LOG: アーカイブリカバリが完了しました 2020-12-27 20:00:52.316 JST [1128] LOG: データベースシステムの接続受け付け準備が整いました
この状態で更新処理を試みると、更新処理がスタンバイに反映されてない可能性を示すメッセージが表示されます。
これはスタンバイ(centos12)のタイムラインが1のままだからです。
[postgres@centos11 ~]$ psql -c "CREATE DATABASE test2" ^CCancel request sent WARNING: ユーザからの要求により同期レプリケーションの待ち状態をキャンセルしています DETAIL: トランザクションはローカルではすでにコミット済みですが、スタンバイ側にはレプリケーションされていない可能性があります。 CREATE DATABASE [postgres@centos11 ~]$
スタンバイサーバのタイムライン変更
スタンバイサーバのrecovery_target_timelineの設定を確認します。デフォルト設定の場合はlatestになっていますので、再起動すれば最新のタイムラインが反映されます。
[postgres@centos12 ~]$ psql -c "SHOW ALL" | grep timeline recovery_target_timeline | latest | Specifies the timeline to recover into. [postgres@centos12 ~]$
再起動しタイムラインを最新にします。
[root@centos12 ~]# systemctl start postgresql-13.service
タイムラインが2に変わった事を確認します。
[root@centos12 ~]# tail -n 3 /var/lib/pgsql/13/data/log/postgresql-Sun.log 2020-12-27 20:03:19.187 JST [1316] LOG: 0/30014A0のレコード長が不正です:長さは24である必要がありますが、実際は0でした 2020-12-27 20:03:19.187 JST [1313] LOG: データベースシステムはリードオンリー接続の受け付け準備ができました 2020-12-27 20:03:19.266 JST [1320] LOG: プライマリのタイムライン2の 0/3000000からでWALストリーミングを始めます
マスターサーバに何らかの更新処理を発生させます。
[postgres@centos11 ~]$ psql -c "CREATE DATABASE test2" CREATE DATABASE [postgres@centos11 ~]$
更新がスタンバイサーバに反映されている事を確認します。
[postgres@centos12 ~]$ psql -l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres test | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | test2 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | (5 rows)