PostgreSQL 13 ストリーミングレプリケーションのパラメタ説明

スポンサーリンク

PostgreSQLはストリーミングレプリケーションと呼ばれるデータコピーの仕組みがあります。3台以上のプライマリ/スレーブ構成を紹介し、ストリーミングレプリケーションに関するパラメタについて説明します。

動作確認構成

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

 +----------+            +----------+
 |          |            |          |
 | centos10 +-----+------+ centos11 |
 | (primary)|     |      | (standby)|
 +----------+     |      +----------+
192.168.56.10/24  |  192.168.56.11/24
                  |
                  |      +----------+
                  |      |          |
                  +------+ centos12 |
                  |      | (standby)|
                  |      +----------+
                  |  192.168.56.12/24
                  |
                  |      +----------+
                  |      |          |
                  +------+ centos13 |
                         | (standby)|
                         +----------+
                     192.168.56.13/24

パラメタ解説

synchronous_commit

PostgreSQLはWALログが転送されたかどうかを確認してから処理を完了させるかどうかを指定する事ができます。

例えば、あるアプリケーションがWALをスタンバイに転送する前に決済完了処理を完了させてしまうと、プライマリ障害時に決済処理が失われてしまいます。このような厳密なトランザクションを管理するような処理は、必ずスタンバイへの転送を待ってから処理完了する必要があります。他方、ディザスタリカバリのような要件で東データセンターから西データセンターにレプリケーションするような場合では、WAL転送を待つのは大きな性能劣化となってしまいます。

このようにWALをどこまで処理されるのを待ってからCOMMITするかを指定するパラメタがsynchronous_commitです。synchronous_commitに指定できるパラメタを以下にまとめます。データロスを防ぎたいならば、デフォルト設定のremote_write以上にする必要があります。

指定値 プライマリのWAL処理 スタンバイのWAL処理
off 待たない 待たない
local 待つ 待たない
remote_write 待つ メモリ書き込みまで待つ
on 待つ ディスク書き込みまで待つ
remote_apply 待つ WALが適用されるまで待つ

synchronous_standby_names

synchronous_standby_namesには複数台のスタンバイサーバを指定する事ができます。前述のsynchronous_commitは全てのスタンバイサーバのWALが処理されるのを待つのではなく、一部サーバのWALが処理されるのを待つような指定もできます。

FIRSTという指定をすると、先頭に記述したサーバのWALの処理を待つ挙動になります。例えば、以下のような記述の場合は、centos11, centos12の処理が終わるまでを待ちます。

synchronous_standby_names = 'FIRST 2 (centos11,centos12,centos13)'

ANYという指定をすると、一部サーバのWALの処理を待つ起動になります。例えば、以下のような記述の場合は、centos11, centos12,centos13のうち2台の処理が終わるまでを待ちます。

synchronous_standby_names = 'ANY 2 (centos11,centos12,centos13)'

正常系動作確認

マスターサーバの構築

postgresql.confおよびpg_hba.confに以下を加筆します。スタンバイ機は3台構成とし、そのうち2台まではWALが同期している状態とします。

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 = 'ANY 2 (centos11,centos12,centos13)'
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コマンドを使用して、プライマリサーバのデータを1台目スタンバイサーバへコピーします。

[ -n "${PGDATA}" ] && rm -rf ${PGDATA}/*
pg_basebackup -R -D ${PGDATA} -h 192.168.56.10
[ -n "${PGDATA}" ] && rm -rf ${PGDATA}/*
rsync -av root@192.168.56.11:/var/lib/pgsql/13/data/ ${PGDATA}
[ -n "${PGDATA}" ] && rm -rf ${PGDATA}/*
rsync -av root@192.168.56.11:/var/lib/pgsql/13/data/ ${PGDATA}

postgresql.auto.confのsynchronous_standby_namesにapplication_nameを加筆します。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.auto.conf 

primary_conninfo = 'user=postgres <omitted> application_name=centos12'
# vi /var/lib/pgsql/13/data/postgresql.auto.conf 

primary_conninfo = 'user=postgres <omitted> application_name=centos13'

postgresql.confのプライマリ固有の設定をコメントアウトします。

# 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 = 'ANY 2 (centos11,centos12,centos13)'

postgresqlを起動し、レプリケーションを開始します。

systemctl start postgresql-13.service

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

[root@centos11 ~]# tail -n 3 /var/lib/pgsql/13/data/log/postgresql-Fri.log
2020-12-25 23:43:33.141 JST [1531] LOG:  0/4000100 でリカバリの一貫性が確保されました
2020-12-25 23:43:33.141 JST [1528] LOG:  データベースシステムはリードオンリー接続の受け付け準備ができました
2020-12-25 23:43:33.238 JST [1535] LOG:  プライマリのタイムライン1の 0/5000000からでWALストリーミングを始めます
[root@centos12 ~]# tail -n 3 /var/lib/pgsql/13/data/log/postgresql-Fri.log
2020-12-25 23:43:37.835 JST [1017] LOG:  0/4000100 でリカバリの一貫性が確保されました
2020-12-25 23:43:37.836 JST [1014] LOG:  データベースシステムはリードオンリー接続の受け付け準備ができました
2020-12-25 23:43:37.978 JST [1021] LOG:  プライマリのタイムライン1の 0/5000000からでWALストリーミングを始めます
[root@centos13 ~]# tail -n 3 /var/lib/pgsql/13/data/log/postgresql-Fri.log
2020-12-25 23:43:40.011 JST [1022] LOG:  0/4000100 でリカバリの一貫性が確保されました
2020-12-25 23:43:40.012 JST [1019] LOG:  データベースシステムはリードオンリー接続の受け付け準備ができました
2020-12-25 23:43:40.165 JST [1026] LOG:  プライマリのタイムライン1の 0/5000000からでWALストリーミングを始めます

動作確認

pgbenchを用いて、動作確認目的の更新処理を発生させます。

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

pg_stat_replicationテーブルを参照すると、ストリーミングレプリケーションの対象と進捗を確認する事ができます。

以下出力の場合は、3レコードが現れていますので、3台のスタンバイ機へWALが転送されている事が分かります。

[postgres@centos10 ~]$ psql << EOF
> \x
> SELECT * FROM pg_stat_replication;
> EOF
Expanded display is on.
-[ RECORD 1 ]----+------------------------------
pid              | 5043
usesysid         | 10
usename          | postgres
application_name | centos11
client_addr      | 192.168.56.11
client_hostname  | 
client_port      | 54554
backend_start    | 2020-12-25 22:43:08.465588+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/5CC3AA0
write_lsn        | 0/5CC3AA0
flush_lsn        | 0/5CC3AA0
replay_lsn       | 0/5CC3AA0
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 1
sync_state       | quorum
reply_time       | 2020-12-25 23:45:11.354132+09
-[ RECORD 2 ]----+------------------------------
pid              | 5044
usesysid         | 10
usename          | postgres
application_name | centos12
client_addr      | 192.168.56.12
client_hostname  | 
client_port      | 50706
backend_start    | 2020-12-25 22:43:13.635872+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/5CC3AA0
write_lsn        | 0/5CC3AA0
flush_lsn        | 0/5CC3AA0
replay_lsn       | 0/5CC3AA0
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 1
sync_state       | quorum
reply_time       | 2020-12-25 23:45:11.319904+09
-[ RECORD 3 ]----+------------------------------
pid              | 5045
usesysid         | 10
usename          | postgres
application_name | centos13
client_addr      | 192.168.56.13
client_hostname  | 
client_port      | 54518
backend_start    | 2020-12-25 22:43:15.965+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/5CC3AA0
write_lsn        | 0/5CC3AA0
flush_lsn        | 0/5CC3AA0
replay_lsn       | 0/5CC3AA0
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 1
sync_state       | quorum
reply_time       | 2020-12-25 23:45:11.301869+09

[postgres@centos10 ~]$ 

障害系 スタンバイ1台目の障害

スタンバイ機のうち1台目を停止します。

systemctl stop postgresql-13.service

1台の障害では充分障害に書き込み処理が成功する事を確認します。

/usr/pgsql-13/bin/pgbench -c 5 -t 10 test

pg_stat_replicationを見ると、レコードが2つしかなく、2台のみにレプリケーションしている事が分かります。

[postgres@centos10 ~]$ psql << EOF
> \x
> SELECT * FROM pg_stat_replication;
> EOF
Expanded display is on.
-[ RECORD 1 ]----+------------------------------
pid              | 5044
usesysid         | 10
usename          | postgres
application_name | centos12
client_addr      | 192.168.56.12
client_hostname  | 
client_port      | 50706
backend_start    | 2020-12-25 22:43:13.635872+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/5CD2568
write_lsn        | 0/5CD2568
flush_lsn        | 0/5CD2568
replay_lsn       | 0/5CD2568
write_lag        | 00:00:00.000724
flush_lag        | 00:00:00.003386
replay_lag       | 00:00:00.003392
sync_priority    | 1
sync_state       | quorum
reply_time       | 2020-12-25 23:45:54.367778+09
-[ RECORD 2 ]----+------------------------------
pid              | 5045
usesysid         | 10
usename          | postgres
application_name | centos13
client_addr      | 192.168.56.13
client_hostname  | 
client_port      | 54518
backend_start    | 2020-12-25 22:43:15.965+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/5CD2568
write_lsn        | 0/5CD2568
flush_lsn        | 0/5CD2568
replay_lsn       | 0/5CD2568
write_lag        | 00:00:00.001292
flush_lag        | 00:00:00.003343
replay_lag       | 00:00:00.003347
sync_priority    | 1
sync_state       | quorum
reply_time       | 2020-12-25 23:45:54.340801+09

[postgres@centos10 ~]$ 

スタンバイ2台目の障害

スタンバイ機のうち2台目を停止します。

systemctl stop postgresql-13.service

動作確認のため簡単なSQL文を発行してみます。すると、ハングアップしていつまでも処理が完了しません。

Ctrl+Cでキャンセルすると、スタンバイ側にレプリケーションされていない可能性がある旨の警告が現れます。

[postgres@centos10 ~]$ psql -c "CREATE DATABASE test2"
^CCancel request sent
WARNING:  ユーザからの要求により同期レプリケーションの待ち状態をキャンセルしています
DETAIL:  トランザクションはローカルではすでにコミット済みですが、スタンバイ側にはレプリケーションされていない可能性があります。
CREATE DATABASE
[postgres@centos10 ~]$ 
タイトルとURLをコピーしました