Anarchy In the 1K

ストリーミングレプリケーションをDocker上で

背景


 上記書籍を読んでPostgreSQLについてお勉強をしています。そんな中、ストリーミングレプリケーションに関して、実際に動作確認をしたくました。
 そこで今回は、Dockerを用いて環境構築を行った後、動作確認を行うまでを実施します。Dockerを用いたPostgreSQLの構築は、以前こちらに記載した為、合わせてご覧下さい。

目次

 今回の記事の目次は、以下の通りです。

ハンズオン

環境構築

 PostgreSQLを下図の通り、primary, standby構成で構築します。 f:id:fujiU:20200612133842p:plain

primary

コンテナ起動(ホスト上)

docker run -d --name=primary --hostname=primary -e POSTGRES_PASSWORD=password postgres

コンテナ上でbash実行(ホスト上)

$ docker exec -it primary /bin/bash

設定変更(コンテナ上)

事前準備

 以下の通り、設定ファイルの変更に用いるvimをインストールした後、postgresユーザで変更を実施します。

# apt-get update
# apt-get install -y vim
# su - postgres
ストリーミングレプリケーションの有効化

 /var/lib/postgresql/data/postgresql.confを以下の通り変更します。

  • #wal_level = replicaからwal_level = replica
  • #max_wal_senders = 10からmax_wal_senders = 10
  • #archive_mode = offからarchive_mode = on
  • #archive_command = ''からarchive_command = 'cp %p /tmp/%f'
  • #synchronous_stanby_names = ''からsynchronous_stanby_names = 'stanby'
  • #synchronous_commit = onからsynchronous_commit = off
standbyからの接続許可

 /var/lib/postgresql/data/pg_hba.confに以下を追記します。

  • host replication postgres <下記で確認する、standbyのIPアドレス>/32 trust

設定反映(コンテナ上とホスト上)

 ctrl-Dを押下しコンテナから抜けた後、ホスト上で以下の通りコマンドを発行し、PostgreSQLの再起動を実施します。

$ docker restart primary

standby

コンテナ起動(ホスト上)

# docker run -it --name=standby --hostname=standby -e POSTGRES_PASSWORD=password postgres /bin/bash

IPアドレスの確認(ホスト上)

 別ウィンドウを開き以下コマンドを発行する。

$ docker network inspect bridge
[
    {
        ...
        "Containers": {
            "51e8fb3a6db4851a8f09460d2ecd5a702b5a97df8c83e2e24f1f5f740fbf8442": {
                "Name": "primary",
                "EndpointID": "5ecb226b6b8383ddcb472e194f3ac0d7eabcd8bcb823f816e6b177072992794a",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "<primaryのIPアドレス>/16",
                "IPv6Address": ""
            },
            "bc6606a60176209dc5b66d14ddf18a40467aac5dbdf9440b9c53e8b68b416fdf": {
                "Name": "standby",
                "EndpointID": "e5e026ba735dbe7f3284ad81754c7e0203998cb9f153fb0b5ba8306eb4204907",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "<standbyのIPアドレス>/16",
                "IPv6Address": ""
            }
        },
        ...
  }
]

ベースバックアップの実施(コンテナ上)

 standbyを起動したウィンドウに戻り以下コマンドを発行する。

# su - postgres
$ export PGDATA=/var/lib/postgresql/data 
$ pg_basebackup -R -D ${PGDATA} -h <上記で確認した、primaryのIPアドレス> -p 5432
$ chmod 750 -R ${PGDATA}

PostgreSQLの起動(コンテナ上)

$ /usr/lib/postgresql/<バージョン番号>/bin/pg_ctl start

動作確認

primaryで追加したレコードをstandbyで参照する

primaryでレコード追加(ホスト上とコンテナ上)

// ホスト上で以下コマンドを発行する。
$ docker exec -it primary /bin/bash

// コンテナ上で以下コマンドを発行する。
# su - postgres
$ psql -U postgres

postgres=# CREATE TABLE test (id integer);
postgres=# INSERT INTO test values(1);
postgres=# SELECT * FROM test;
 id 
----
  1
(1 row)

standbyでレコード参照(コンテナ上)

$ psql -U postgres

postgres=# SELECT * FROM test;
 id 
----
  1
(1 row)

standbyからprimaryへ昇格

standbyでコマンド発行(コンテナ上)

// PostgreSQLにログイン
$ psql -U postgres

// 昇格前はINSERTできないことを確認
postgres=# insert into test values(2);
2020-06-11 12:41:13.066 UTC [37] ERROR:  cannot execute INSERT in a read-only transaction
2020-06-11 12:41:13.066 UTC [37] STATEMENT:  insert into test values(2);
ERROR:  cannot execute INSERT in a read-only transaction

// PostgreSQLからログアウト
postgres=# \q

// standbyからprimaryへ昇格
$ /usr/lib/postgresql/<バージョン番号>/bin/pg_ctl promote

// 昇格後はINSERTできることを確認
$ psql -U postgres
postgres=# insert into test values(2);
postgres=# select * from test;
 id 
----
  1
  2
(2 rows)