PostgreSQL Replication

PostgreSQL Databaseのレプリケーション(複製)について、試してみました。

環境は以下ソースコードから構築した環境を使用し、一つのサーバにストリーミングレプリケーションとロジカルレプリケーションの環境をポートを変えることによりサーバを同居させました。(/home/postgres以下で作業)
「Attach to Process / GDB」

Attach to Process / GDB

参考)
「PostgreSQLでサポートされている2つのレプリケーション機能の違いと使い分け」
https://www.system-exe.co.jp/dbexpert26

レプリケーションには、WAL(Write Ahead Log:ログ先行書き込み)ファイル(pg_walディレクトリ)が使われます。バイナリファイで、pg_waldumpを使って内容を見ることができます。
先行というところがポイントで、データ書き込み中クラッシュしてもこのログを元に復元が可能になります。

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

オリジナルのサーバ(data:5432)の起動と停止

pg_ctl –pgdata=/home/postgres/data –log=/home/postgres/db.log start
pg_ctl –pgdata=/home/postgres/data stop

これにストリーミングレプリケーション(マスタ)の設定

vi data/postgresql.conf

synchronous_standby_names = 'pgsql5433'

vi data_rep/postgresql.auto.conf

primary_conninfo = 'user=postgres passfile=''/home/postgres/.pgpass'' port=5432 sslmode=disable sslcompression=0 gssencmode=disable krbsrvname=postgres target_session_attrs=any application_name=pgsql5433'
(pg_basebackupの後?)

スタンバイサーバ(data_rep:5433)の作成と設定

mkdir data_rep
chmod 700 data_rep
pg_basebackup -p 5432 -R -D data_rep

vi data_rep/postgresql.conf

port = 5433
synchronous_standby_names = 'pgsql5433'

起動と停止

pg_ctl –pgdata=/home/postgres/data_rep –log=/home/postgres/db_rep.log start
pg_ctl –pgdata=/home/postgres/data_rep stop

psql の起動
マスタ  psql (-p 5432)
スタンバイ psql -p 5433
データの確認は特別なことはなく、マスタでテーブルの作成、データのインサート、スタンバイ側でSELECTでできます。

psqlの中でマスタがどちらか知りたいときは、下記でt(True)がかえればリカバリー、つまりスタンバイ側になります。

postgres=# select pg_is_in_recovery();
pg_is_in_recovery
——————-
f
(1 row)

またスタンバイ側はリードオンリーになるため、DBやTableの作成ができなくなります。

あとここではテストしませんが、ストリーミングレプリケーションには、スタンバイ側の応答を待ってコミットする、待たずにコミットするなど、同期、非同期に関する設定があります。(下記参考)

「ストリーミングレプリケーション ~ 仕組み、構成のポイント ~」
https://www.fujitsu.com/jp/products/software/resources/feature-stories/postgres/article-index/streaming-replication1/

ロジカルレプリケーション

マスタサーバ(data2:5434) : パブリッシャー

pg_ctl –pgdata=/home/postgres/data2 initdb

vi data2/postgresql.conf

port=5434
wal_level = logical

vi data2/pg_hba.conf

host all repuser 0.0.0.0/0 md5
(ここではこれはなくても動作)

起動と停止

pg_ctl –pgdata=/home/postgres/data2 –log=/home/postgres/db2.log start
pg_ctl –pgdata=/home/postgres/data2 stop

psql -p 5434

postgres=# create table tbl_d (id int);
CREATE TABLE
postgres=# create table tbl_e (id int);
CREATE TABLE
postgres=# insert into tbl_d select generate_series(10,20);
INSERT 0 11
postgres=# insert into tbl_e select generate_series(10,20);
INSERT 0 11 ^
postgres=# create publication mypub for table tbl_d with(publish=’insert,update’);
CREATE PUBLICATION
postgres=# select * from pg_publication_tables;
pubname | schemaname | tablename
———+————+———–
mypub | public | tbl_d
(1 row)

postgres=# select * from pg_publication;
oid | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate
——-+———+———-+————–+———–+———–+———–+————-
32787 | mypub | 10 | f | t | t | f | f
(1 row)

postgres=# create publication mypub2 for table tbl_e with(publish=’insert,update’);
CREATE PUBLICATION
postgres=# select * from pg_publication_tables;
pubname | schemaname | tablename
———+————+———–
mypub | public | tbl_d
mypub2 | public | tbl_e

スタンバイ(data2_rep:5435) : サブスクライバー

pg_ctl –pgdata=/home/postgres/data2_rep initdb

vi data2_rep/postgresql.conf

port=5435

起動と停止

pg_ctl –pgdata=/home/postgres/data2_rep –log=/home/postgres/db2_rep.log start
pg_ctl –pgdata=/home/postgres/data2_rep stop

psql -p 5435 -c “CREATE DATABASE test”

CREATE DATABASE

psql -p 5435 test

test=# create table tbl_d (id int);
CREATE TABLE
test=# create table tbl_e (id int);
CREATE TABLE
test=# create subscription mysub connection ‘host=localhost port=5434 dbname=postgres’ publication mypub;
NOTICE: created replication slot “mysub” on publisher
CREATE SUBSCRIPTION
test=# select * from pg_subscription;
oid | subdbid | subname | subowner | subenabled | subconninfo | subslotname | subsynccommit | subpublica
tions
——-+———+———+———-+————+——————————————+————-+—————+———–
——
16392 | 16384 | mysub | 10 | t | host=localhost port=5432 dbname=postgres | mysub | off | {mysub}
(1 row)

test=# select * from tbl_d;
id
—-
(0 rows)

※Table作成はあらかじめ必要
ストリーミングレプリケーションは設定ファイル編集、ロジカルレプリケーションはコマンド操作で、という設定が多いようです。
下記は、create subscriptionでレプリケーションが反映された様子です。

二通りのレプリケーションの環境を構築できましたので、これをベースにまたテストを重ねたいと思います。