PostgreSQL 13 ストリーミングレプリケーションのDR向け設定

スポンサーリンク

PostgreSQLはストリーミングレプリケーションと呼ばれるデータコピーの仕組みがあります。レプリケーションは高可用性目的だけでなく、ディザスタリカバリ用途としても使用する事ができます。このページではディザスタリカバリ向けのレプリケーション設定を紹介します。

動作確認構成

以下の環境で動作確認を行います。

+------------------+     +------------------+
| 192.168.56.10/24 |     | 192.168.56.11/24 |
|    centos10      |---->|    centos11      |
|    (primary)     |     |   (secondary)    |
+------------------+     +------------------+

構成手順

マスターサーバの構築

ディザスタリカバリを実現する場合は東西間データセンターでレプリケーションを行いますので、それなりの距離遅延(レイテンシ)が発生します。距離遅延は信号が回線を伝わる時間ですので、高帯域な広域網を敷設しても解消できる問題ではなく、不可避な問題です。

そのため、マスターサーバの処理が別拠点のスタンバイサーバのWALに反映されるのを待っていると、それなりの距離遅延(レイテンシ)を待たなければならず、非現実的な処理速度になる事があります。ですので、synchronous_commitはlocalまたはoffにするのが現実的な設定例となります。

以上を踏まえると、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 = 'local'
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 

スタンバイサーバの構築

pg_basebackupコマンドを使用して、プライマリサーバのデータをスタンバイサーバへコピーします。

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'

マスターサーバとしての設定をコメントアウトします。

# vi /var/lib/pgsql/13/data/postgresql.conf

#listen_addresses = '0.0.0.0'
#max_wal_senders = 10
#synchronous_commit = 'local'

postgresqlを起動します。

systemctl start postgresql-13.service

レプリケーションが開始された旨のログを確認します。

[root@centos11 ~]# tail -n 3 /var/lib/pgsql/13/data/log/postgresql-Mon.log 
2020-12-28 12:06:43.334 JST [1181] LOG:  0/2000100 でリカバリの一貫性が確保されました
2020-12-28 12:06:43.334 JST [1178] LOG:  データベースシステムはリードオンリー接続の受け付け準備ができました
2020-12-28 12:06:43.450 JST [1185] LOG:  プライマリのタイムライン1の 0/3000000からでWALストリーミングを始めます

遅延の確認

確認方法

ディザスタリカバリの要件を合意する時、RPO(Recovery Point Objective)という観点があります。RPOとは、障害発生時、過去の「どの時点まで」のデータを復旧させるかの定義です。

pg_stat_replicationテーブルを参照すると、どのLSNまでがスタンバイ機に反映されたかを確認する事ができます。もし、sent_lsn, replay_lsn等に差異がなければプライマリとセカンダリ間での遅延は発生してなく、sent_lsn, replay_lsn等に大きな差異があればプライマリとセカンダリ間での遅延は発生しており一定時間のデータロスがある事が分かります。

[postgres@centos10 ~]$ psql << EOF
> \x
> SELECT * FROM pg_stat_replication;
> EOF
Expanded display is on.
-[ RECORD 1 ]----+------------------------------
pid              | 1238
usesysid         | 10
usename          | postgres
application_name | walreceiver
client_addr      | 192.168.56.11
client_hostname  | 
client_port      | 46876
backend_start    | 2020-12-28 12:06:43.278794+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/3000110
write_lsn        | 0/3000110
flush_lsn        | 0/3000110
replay_lsn       | 0/3000110
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 0
sync_state       | async
reply_time       | 2020-12-28 12:08:40.273378+09

各項目の意味をまとめると以下の通りです。(参照:「27.2.2. Viewing Statistics」「27.2. 統計情報コレクタ 」)

日本語訳のマニュアルはwrite, flushの訳し方が誤解を与えるような印象がありますので、以下には原文のマニュアルを転機します。

項目 意味
sent_lsn Last write-ahead log location sent on this connection
write_lsn Last write-ahead log location written to disk by this standby server
flush_lsn Last write-ahead log location flushed to disk by this standby server
replay_lsn Last write-ahead log location replayed into the database on this standby server

擬似的な遅延発生

擬似的に貧弱な回線を再現させます。Redhat系OSでは帯域制御を実現するtcと呼ばれるパッケージがあります。まず、マスターサーバにtcをインストールします。

dnf install tc

マスターサーバ側の帯域を10Kbpsまで絞り込みます。どこまで帯域を絞り込むかは環境に応じて適宜変更ください。

設定コマンドの例は以下の通りです。インターフェース名enp0s8は環境に応じて変更ください。

tc qdisc add dev enp0s8 root tbf rate 100kbit burst 20kb limit 100kb

マスターサーバ側に大きな更新処理を発生させます。

createdb test
/usr/pgsql-13/bin/pgbench -i test
/usr/pgsql-13/bin/pgbench -c 5 -t 10000 test

pg_stat_replicationテーブルを参照すると、sent_lsnとreplay_lsnの間で差分が発生しており、遅延が発生している事が分かります。

[postgres@centos10 ~]$ psql << EOF
> \x
> SELECT * FROM pg_stat_replication;
> EOF
Expanded display is on.
-[ RECORD 1 ]----+------------------------------
pid              | 1868
usesysid         | 10
usename          | postgres
application_name | centos11
client_addr      | 192.168.56.11
client_hostname  | 
client_port      | 59940
backend_start    | 2020-12-28 12:59:50.427247+09
backend_xmin     | 
state            | catchup
sent_lsn         | 0/F0C0000
write_lsn        | 0/F040000
flush_lsn        | 0/F83D398
replay_lsn       | 0/F83D398
write_lag        | 00:00:21.407438
flush_lag        | 00:00:21.407438
replay_lag       | 00:00:21.407438
sync_priority    | 0
sync_state       | async
reply_time       | 2020-12-28 13:31:20.446923+09
タイトルとURLをコピーしました