ここでは、Pgpool-IIのネイティブレプリケーションモードおよびスナップショットアイソレーションモードの設定例を示します。
項8.2で紹介した「ストリーミングレプリケーションモード」では、 PostgreSQLのストリーミングレプリケーション機能でレプリケーションを行いますが、 ネイティブレプリケーションモードでは、Pgpool-IIが書き込みクエリをすべてのPostgreSQLで実行することで、レプリケーションを行います。
また、スナップショットアイソレーションモードはネイティブレプリケーションモードにスナップショットの管理機能を追加しており、ノードを跨る読み取りの一貫性を保証できます。 Pgpool-IIが書き込みクエリをすべてのPostgreSQLで実行し、 レプリケーションを行う点はネイティブレプリケーションモードと同じです。
この設定例ではPostgreSQL 14を使っていますが、 各種スクリプトはPostgreSQL 10以降での動作確認を行っています。
この設定例では、Pgpool-II 1台、PostgreSQL 3台を用いて、Pgpool-IIのレプリケーション機能を説明します。
物理サーバを3台用意し、それぞれのホスト名は 「server1」、「server2」、「server3」 とします。使用するOSはすべてCentOS 7.9とします。 それぞれのサーバにPostgreSQLをインストールし、その中の1台にPgpool-IIをインストールします。
また、この設定例では、レプリケーション機能を利用するための必要最低限の設定を紹介しています。 本番環境で利用する場合、Pgpool-IIの冗長化機能Watchdogを有効にすることをお勧めします。 Watchdogの設定例は項8.2.6.10をご参照ください。
表 8-7. ホスト名とIPアドレス
ホスト名 | IPアドバイス | 説明 |
---|---|---|
server1 | 192.168.137.101 | PostgreSQLノード0、Pgpool-II |
server2 | 192.168.137.102 | PostgreSQLノード1 |
server3 | 192.168.137.103 | PostgreSQLノード2 |
表 8-8. PostgreSQLのバージョンと設定情報
項目 | 値 | 説明 |
---|---|---|
PostgreSQLバージョン | 14.0 | - |
ポート番号 | 5432 | - |
$PGDATA | /var/lib/pgsql/14/data | - |
アーカイブモード | 有効 | /var/lib/pgsql/archivedir |
表 8-9. Pgpool-IIのバージョンと設定情報
項目 | 値 | 説明 |
---|---|---|
Pgpool-IIバージョン | 4.3.0 | - |
ポート番号 | 9999 | Pgpool-IIが接続を受け付けるポート番号 |
9898 | PCPプロセスが接続を受け付けるポート番号 | |
設定ファイル | /etc/pgpool-II/pgpool.conf | Pgpool-IIの設定ファイル |
Pgpool-II起動ユーザ | postgres (Pgpool-II 4.1以降) | Pgpool-II 4.0以前のバージョンでは、デフォルトではrootでPgpool-IIを起動する |
Pgpool-II動作モード | ネイティブレプリケーションモード | - |
スナップショットアイソレーションモード | ネイティブレプリケーションモードの拡張 |
すべてのサーバにPostgreSQL 14.0とPgpool-II 4.3をRPMからインストールします。
PostgreSQLのインストールはPostgreSQLコミュニティのリポジトリを使います。
# yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm # yum install -y postgresql14-server
Pgpool-IIのインストールはPgpool-II開発コミュニティが提供するYumリポジトリを用いてインストールします。
# yum install -y https://www.pgpool.net/yum/rpms/4.3/redhat/rhel-7-x86_64/pgpool-II-release-4.3-1.noarch.rpm # yum install -y pgpool-II-pg14-*
PostgreSQL、Pgpool-IIの設定の前に、以下の設定を行います。
オンラインリカバリ機能を利用するには、すべてのサーバにパスワードなしでSSH接続できるように設定する必要があります。 全サーバで以下のコマンドを実行し、SSHの設定を行います。 生成される鍵ファイル名はid_rsa_pgpoolとします。
[全サーバ]# su - postgres [全サーバ]$ cd ~/.ssh [全サーバ]$ ssh-keygen -t rsa -f id_rsa_pgpool [全サーバ]$ ssh-copy-id -i id_rsa_pgpool.pub postgres@server1 [全サーバ]$ ssh-copy-id -i id_rsa_pgpool.pub postgres@server2 [全サーバ]$ ssh-copy-id -i id_rsa_pgpool.pub postgres@server3
設定後、postgresユーザで、 ssh postgres@serverX -i ~/.ssh/id_rsa_pgpoolコマンドを実行し、 パスワード入力せずログインできることを確認してください。 必要に応じて/etc/ssh/sshd_configを編集し、 sshdを再起動してください。
PostgreSQLユーザのパスワード入力を求められることなく、 オンラインリカバリのスクリプトを実行できるように、すべてのサーバにて postgresユーザのホームディレクトリ/var/lib/pgsqlに .pgpassを作成し、パーミッションを 600 に設定しておきます。
[全サーバ]# su - postgres [全サーバ]$ vi /var/lib/pgsql/.pgpass (以下を追加) server1:5432:replication:repl:<replユーザのパスワード> server2:5432:replication:repl:<replユーザのパスワード> server3:5432:replication:repl:<replユーザのパスワード> server1:5432:postgres:postgres:<postgresユーザのパスワード> server2:5432:postgres:postgres:<postgresユーザのパスワード> server3:5432:postgres:postgres:<postgresユーザのパスワード> [全サーバ]$ chmod 600 /var/lib/pgsql/.pgpass
Pgpool-IIやPostgreSQLに接続する際には、 ファイアーウォールによって目的のポートが開けられていなければなりません。 CentOS/RHEL7の場合、以下のように設定します。
[全サーバ]# firewall-cmd --permanent --zone=public --add-service=postgresql [全サーバ]# firewall-cmd --permanent --zone=public --add-port=9999/tcp --add-port=9898/tcp [全サーバ]# firewall-cmd --reload
Watchdogを利用する場合は、9000と9694ポートも開放する必要があります。
[全サーバ]# firewall-cmd --permanent --zone=public --add-port=9000/tcp --add-port=9694/udp
ここでは、PostgreSQLサーバの作成・設定を説明します。
WALアーカイブ機能を有効にします。 すべてのサーバにてWALを格納するディレクトリ/var/lib/pgsql/archivedirを作成します。
[全サーバ]# su - postgres [全サーバ]$ mkdir /var/lib/pgsql/archivedir
server1上でPostgreSQLのmainノードを作成します。他の2台のreplicaノードはPgpool-IIのオンラインリカバリ機能によって作成されるため、ここでの作成・設定は不要です。
server1で以下のコマンドを実行し、PostgreSQLデータベースクラスタを作成します。
[server1]# su - postgres [server1]$ /usr/pgsql-14/bin/initdb -E UTF8 --no-locale
次にserver1にて、設定ファイル$PGDATA/postgresql.confを以下のように編集します。
[server1]$ vi $PGDATA/postgresql.conf (以下を追加) listen_addresses = '*' archive_mode = on archive_command = 'cp "%p" "/var/lib/pgsql/archivedir/%f"'
Pgpool-IIサーバとPostgreSQLバックエンドサーバが 同じサブネットワークにあることを想定し、各ユーザがscram-sha-256認証方式で接続できるように、 pg_hba.confを編集しておきます。
[server1]$ vi $PGDATA/pg_hba.conf (以下を追加) host all all samenet scram-sha-256 host replication all samenet scram-sha-256
server1で以下のコマンドを実行し、PostgreSQLを起動します。
[server1]$ /usr/pgsql-14/bin/pg_ctl start
Pgpool-IIのヘルスチェックでPostgreSQLのユーザを設定する必要があります。 セキュリティ上の理由で、この設定例ではスーパーユーザを使わないようにします。 Pgpool-IIのヘルスチェック用のユーザpgpoolを作成します。 また、PostgreSQLレプリケーション専用ユーザreplを作成します。 Pgpool-II 4.0からSCRAM認証を利用できるようになりました。 この設定例では、scram-sha-256認証方式を利用します。
表 8-10. ユーザ
ユーザ名 | パスワード | 備考 |
---|---|---|
repl | repl | PostgreSQLのレプリケーション専用ユーザ |
pgpool | pgpool | Pgpool-IIのヘルスチェック専用ユーザ(health_check_user) |
postgres | postgres | オンラインリカバリを実行するユーザ |
[server1]$ psql -U postgres -p 5432 postgres=# SET password_encryption = 'scram-sha-256'; postgres=# CREATE ROLE pgpool WITH LOGIN; postgres=# CREATE ROLE repl WITH REPLICATION LOGIN; postgres=# \password pgpool postgres=# \password repl postgres=# \password postgres
スナップショットアイソレーションモードはPostgreSQLのトランザクション隔離レベルが「repeatable read」の場合のみ使用できます。スナップショットアイソレーションモードを利用する場合、 postgresql.confにdefault_transaction_isolation = 'repeatable read'を設定しておきます。
[server1]$ vi $PGDATA/postgresql.conf (以下を追加) default_transaction_isolation = 'repeatable read'
YUMからインストールした場合、Pgpool-IIの設定ファイルは/etc/pgpool-II/pgpool.confにあります。このファイルを編集し、Pgpool-IIの設定を行います。
Pgpool-IIのクラスタリングモードを設定します。
ネイティブレプリケーションモードの場合
backend_clustering_mode = 'native_replication'
スナップショットアイソレーションモードの場合
backend_clustering_mode = 'snapshot_isolation'
Pgpool-IIが全てのIPアドレスから接続を受け付けるように、 listen_addressesパラメータに'*'を設定します。
listen_addresses = '*'
定期的にPostgreSQLに接続し、死活監視を行うために、ヘルスチェックを有効にします。 health_check_periodのデフォルト値が0で、これはヘルスチェックが無効であることを意味します。 また、ネットワークが不安定な場合には、バックエンドが正常であるにも関わらず、 ヘルスチェックに失敗し、フェイルオーバや縮退運転が発生してしまう可能性があります。 そのようなヘルスチェックの誤検知を防止するため、ヘルスチェックのリトライ回数を health_check_max_retries = 3 に設定しておきます。 この設定例では、health_check_passwordはpgpool.confに指定せず、 pool_passwdファイルに作成します。 作成方法については後述の項8.2.6.9を参照ください。 Pgpool-II 4.0から、sr_check_passwordが空白の場合、 Pgpool-IIは空のパスワードを使用する前に まずpool_passwdファイルからsr_check_userに 指定したユーザのパスワードを取得できるか試みます。
health_check_period = 5 health_check_timeout = 30 health_check_user = 'pgpool' health_check_password = '' health_check_max_retries = 3
また、バックエンド情報を前述のserver1、server2 及びserver3の設定に従って設定しておきます。 複数バックエンドノードを定義する場合、以下のbackend_*などのパラメータ名の 末尾にノードIDを表す数字を付加することで複数のバックエンドを指定することができます。
# - Backend Connection Settings - backend_hostname0 = 'server1' backend_port0 = 5432 backend_weight0 = 1 backend_data_directory0 = '/var/lib/pgsql/14/data' backend_flag0 = 'ALLOW_TO_FAILOVER' backend_hostname1 = 'server2' backend_port1 = 5432 backend_weight1 = 1 backend_data_directory1 = '/var/lib/pgsql/14/data' backend_flag1 = 'ALLOW_TO_FAILOVER' backend_hostname2 = 'server3' backend_port2 = 5432 backend_weight2 = 1 backend_data_directory2 = '/var/lib/pgsql/14/data' backend_flag2 = 'ALLOW_TO_FAILOVER'
続いて、オンラインリカバリを行うためのPostgreSQLのユーザ名
及びオンラインリカバリ時に呼び出されるコマンドrecovery_1st_stage_command
とrecovery_2nd_stage_commandを設定します。
オンラインリカバリで実行されるpgpool_recovery
関数は
PostgreSQLのスーパーユーザ権限が必要なため、
recovery_userにスーパーユーザを指定しなければなりません。
ここでは、postrgesユーザを指定します。
recovery_user = 'postgres' recovery_password = '' recovery_1st_stage_command = 'recovery_1st_stage.sh' recovery_2nd_stage_command = 'recovery_2nd_stage.sh'
ネイティブレプリケーションモード/スナップショットアイソレーションモード専用のオンラインリカバリ用のサンプルスクリプトreplication_mode_recovery_1st_stage.sample、 replication_mode_recovery_2nd_stage.sample 及びpgpool_remote_start.sampleは /etc/pgpool-II/配下にインストールされていますので、 これらのファイルをmainノード(server1)のデータベースクラスタ配下に配置します。
[server1]# cp -p /etc/pgpool-II/replication_mode_recovery_1st_stage.sample /var/lib/pgsql/14/data/recovery_1st_stage.sh [server1]# cp -p /etc/pgpool-II/replication_mode_recovery_2nd_stage.sample /var/lib/pgsql/14/data/recovery_2nd_stage.sh [server1]# cp -p /etc/pgpool-II/pgpool_remote_start.sample /var/lib/pgsql/14/data/pgpool_remote_start [server1]# chown postgres:postgres /var/lib/pgsql/14/data/{recovery_1st_stage.sh,recovery_2nd_stage.sh,pgpool_remote_start}
基本的にはPGHOMEを環境に合わせて変更すれば、動作します。
[server1]# vi /var/lib/pgsql/14/data/recovery_1st_stage.sh ... PGHOME=/usr/pgsql-14 ... [server1]# vi /var/lib/pgsql/14/data/recovery_2nd_stage.sh ... PGHOME=/usr/pgsql-14 ... [server1]# vi /var/lib/pgsql/14/data/pgpool_remote_start ... PGHOME=/usr/pgsql-14 ...
また、オンラインリカバリ機能を使用するには、pgpool_recovery
、
pgpool_remote_start
、pgpool_switch_xlog
という関数が必要になるので、
server1のtemplate1にpgpool_recovery
をインストールしておきます。
[server1]# su - postgres [server1]$ psql template1 -c "CREATE EXTENSION pgpool_recovery"
注意: recovery_1st_stageスクリプトはテーブルスペースに対応していません。 テーブルスペースを使っている場合は、スクリプトを自分で変更する必要があります。
PostgreSQLの設定の章で、 Pgpool-IIとPostgreSQLの間に 認証方式をscram-sha-256に設定しました。 この設定例では、クライアントとPgpool-IIの間でも scram-sha-256認証方式を利用し接続するように設定します。 Pgpool-IIのクライアント認証の設定ファイルは pool_hba.confと呼ばれ、YUMからインストールする場合、 デフォルトでは/etc/pgpool-II配下にインストールされます。 デフォルトではpool_hba.confによる認証は無効になっているので、 pgpool.confで以下の設定をonに変更します。
enable_pool_hba = on
pool_hba.confのフォーマットはPostgreSQLの pg_hba.confとほとんど同じです。 pgpoolとpostgresユーザの認証方式をscram-sha-256認証に設定します。
[server1]# vi /etc/pgpool-II/pool_hba.conf (以下を追加) host all pgpool 0.0.0.0/0 scram-sha-256 host all postgres 0.0.0.0/0 scram-sha-256
注意: Pgpool-II 4.1からpgpool.confファイル内の health_check_password、sr_check_password、 wd_lifecheck_password、recovery_passwordには AES256暗号化形式、平文形式、md5ハッシュ形式が指定できます。 Pgpool-II 4.0ではAES256暗号化形式、 平文形式が指定可能で、それ以前のバージョンでは平文形式のみが指定可能です。
Pgpool-IIのクライアント認証で用いるデフォルトのパスワードファイル名はpool_passwdです。 scram-sha-256認証を利用する場合、 Pgpool-IIはそれらのパスワードを復号化するために復号鍵が必要となります。 全サーバで復号鍵ファイルをPgpool-IIの起動ユーザ postgres (Pgpool-II 4.0以前のバージョンではroot) のホームディレクトリ配下に作成します。
[server1]# su - postgres [server1]$ echo '任意の文字列' > ~/.pgpoolkey [server1]$ chmod 600 ~/.pgpoolkey
「pg_enc -m -k /path/to/.pgpoolkey -u username -p」を実行すると、 ユーザ名とAES256で暗号化したパスワードのエントリがpool_passwdに登録されます。 pool_passwd がまだ存在しなければ、pgpool.confと同じディレクトリ内に作成されます。
[server1]$ pg_enc -m -k ~/.pgpoolkey -u pgpool -p db password: [pgpoolユーザのパスワード] [server1]$ pg_enc -m -k ~/.pgpoolkey -u postgres -p db password: [postgresユーザのパスワード] [server1]$ cat /etc/pgpool-II/pool_passwd pgpool:AESheq2ZMZjynddMWk5sKP/Rw== postgres:AESHs/pWL5rtXy2IwuzroHfqg==
PCPコマンドを使用するにはユーザ認証が必要になるので、 ユーザ名とmd5ハッシュに変換されたパスワードを "username:encrypted password"の形式で pcp.confファイルに設定します。
以下のようにpg_md5コマンドを利用し、 ハッシュ化されたpgpoolユーザのパスワードエントリを/etc/pgpool-II/pcp.confに追加します。
[全サーバ]# echo 'pgpool:'`pg_md5 PCPコマンドパスワード` >> /etc/pgpool-II/pcp.conf
Pgpool-II 4.2以降、ログ収集プロセスが追加されました。 ここでは、ログ収集プロセス(logging_collector)を有効にします。
log_destination = 'stderr' logging_collector = on log_directory = '/var/log/pgpool_log' log_filename = 'pgpool-%Y-%m-%d_%H%M%S.log' log_truncate_on_rotation = on log_rotation_age = 1d log_rotation_size = 10MB
server1にログファイルを格納するディレクトリを作成します。
[server1]# mkdir /var/log/pgpool_log/ [server1]# chown postgres:postgres /var/log/pgpool_log/
Pgpool-II起動時にpgpool_statusファイルが存在する場合、 Pgpool-IIはpgpool_statusファイルからバックエンドの状態(up/down)を読み取ります。 Pgpool-II起動時にpgpool_statusファイルを無視させたい場合、 /etc/sysconfig/pgpoolの起動オプションOPTSに「-D」を追加します。
[server1]# vi /etc/sysconfig/pgpool (...省略...) OPTS=" -D -n"
Pgpool-IIを起動する前に、 バックエンドのPostgreSQLをあらかじめ起動する必要があります。 また、PostgreSQLを停止する場合、 Pgpool-IIを先に停止する必要があります。 以下のコマンドでPgpool-IIの起動・停止を行います。
Pgpool-IIの起動
# systemctl start pgpool.service
Pgpool-IIの停止
# systemctl stop pgpool.service
これから、動作確認を行います。 まず、server1で以下のコマンドでPgpool-IIを起動します。
[server1]# systemctl start pgpool.service
まず、Pgpool-IIのオンラインリカバリ機能を利用し、PostgreSQLノード1、ノード2を構築します。
[server1]# pcp_recovery_node -h server1 -p 9898 -U pgpool -n 1 Password: pcp_recovery_node -- Command Successful [server1]# pcp_recovery_node -h server1 -p 9898 -U pgpool -n 2 Password: pcp_recovery_node -- Command Successful
ノード0がmainノードとして起動しており、ノード1とノード2がreplicaとして起動していることを確認します。
# psql -h server1 -p 9999 -U pgpool postgres -c "show pool_nodes" Password for user pgpool: node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change ---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- 0 | server1 | 5432 | up | up | 0.333333 | main | main | 0 | true | 0 | | | 2021-12-02 16:48:21 1 | server2 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 2 | server3 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 (3 rows)
pgbenchを使って、レプリケーション機能を試してみましょう。
[server1]# /usr/pgsql-14/bin/createdb test -U postgres -p 9999 [server1]# /usr/pgsql-14/bin/pgbench -h server1 -U postgres -i -p 9999 test
Pgpool-IIのレプリケーション機能が正しく動いているかどうか確かめるために、 それぞれのノードに接続して、同じ結果を返すかどうか見てみます。
[server1]# /usr/pgsql-14/bin/psql -h server1 -U postgres -p 5432 test test=# \d List of relations Schema | Name | Type | Owner --------+------------------+-------+---------- public | pgbench_accounts | table | postgres public | pgbench_branches | table | postgres public | pgbench_history | table | postgres public | pgbench_tellers | table | postgres (4 rows) [server1]# /usr/pgsql-14/bin/psql -h server2 -U postgres -p 5432 test test=# \d List of relations Schema | Name | Type | Owner --------+------------------+-------+---------- public | pgbench_accounts | table | postgres public | pgbench_branches | table | postgres public | pgbench_history | table | postgres public | pgbench_tellers | table | postgres (4 rows) [server1]# /usr/pgsql-14/bin/psql -h server3 -U postgres -p 5432 test test=# \d List of relations Schema | Name | Type | Owner --------+------------------+-------+---------- public | pgbench_accounts | table | postgres public | pgbench_branches | table | postgres public | pgbench_history | table | postgres public | pgbench_tellers | table | postgres (4 rows)
server1、server2、server3のPostgreSQLは、同一の結果を返しています。
次に、pgbenchをしばらく走らせて、結果を見てみます。
[server1]# /usr/pgsql-14/bin/pgbench -h server1 -U postgres -p 9999 -T 10 test
すべてのPostgreSQLは、同一の結果を返しています。
[server1]# /usr/pgsql-14/bin/psql -h server1 -U postgres -p 5432 test -c "SELECT sum(abalance) FROM pgbench_accounts" Password for user postgres: sum -------- -99710 (1 row) [server1]# /usr/pgsql-14/bin/psql -h server2 -U postgres -p 5432 test -c "SELECT sum(abalance) FROM pgbench_accounts" Password for user postgres: sum -------- -99710 (1 row) [server1]# /usr/pgsql-14/bin/psql -h server3 -U postgres -p 5432 test -c "SELECT sum(abalance) FROM pgbench_accounts" Password for user postgres: sum -------- -99710 (1 row)
次にmainノードであるserver1のPostgreSQLを停止し、 mainノードの切り替えを確認してみます。
[server1]# su - postgres -c "/usr/pgsql-14/bin/pg_ctl -m i stop"
ノード0を停止した後に、ノード0が切り離されて、mainノードの切り替えが発生することを確認します。
[server1]# psql -h server1 -p 9999 -U pgpool postgres -c "show pool_nodes" Password for user pgpool: node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change ---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- 0 | server1 | 5432 | down | down | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:57:45 1 | server2 | 5432 | up | up | 0.333333 | main | main | 1 | true | 0 | | | 2021-12-02 16:48:21 2 | server3 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 (3 rows)
次に、Pgpool-IIのオンラインリカバリ機能を利用し、 先ほど停止した旧mainノードを復旧させます。
# pcp_recovery_node -h server1 -p 9898 -U pgpool -n 0 Password: pcp_recovery_node -- Command Successful
ノード1がmainノードとして起動していることを確認します。
# psql -h server1 -p 9999 -U pgpool postgres -c "show pool_nodes" Password for user pgpool: node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change ---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------------- 0 | server1 | 5432 | up | up | 0.333333 | main | main | 0 | true | 0 | | | 2021-12-02 16:57:45 1 | server2 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 2 | server3 | 5432 | up | up | 0.333333 | replica | replica | 0 | false | 0 | | | 2021-12-02 16:48:21 (3 rows)
以上で、動作確認が完了です。