レプリケーションはほとんどのセットアップの重要な機能であり、市場に出回っているほとんどのデータベーステクノロジでサポートされています。 PostgreSQLコミュニティはバージョン9.0でレプリケーション(ストリーミングレプリケーションまたはSRと呼ばれる)を導入しました。それ以来、PostgreSQLのレプリケーションは、カスケードレプリケーション、論理デコード、その他のいくつかの最適化などの追加機能で進化してきました。
このブログでは、「Demonware」(ロール「ANXS / postgresql」のフォーク)によって開発されたAnsibleロールpostgresqlの使用について説明します。以前のブログで「ANXS/postgresql」ロールの使用についてはすでに話しましたが、レプリケーション機能については説明しませんでした。 Ansibleロール「postgresql」は、repmgrを使用してPostgreSQLレプリケーションをセットアップする機能を追加します。
Repmgrについて
Repmgrは、2ndQuadrantによって開発および保守されているオープンソースのコマンドラインツールです。このツールは、PostgreSQLレプリケーションクラスターの管理に関連するほとんどのタスクを自動化します。以下は、repmgrコマンドとrepmgrdデーモンを使用してスムーズに実行できるタスクのリストです。
- PostgreSQLレプリケーションクラスターのブートストラップ。
- プライマリインスタンスの自動フェイルオーバーと手動スイッチオーバーを実行します。
- スタンバイ(リードレプリカ)インスタンスの追加と削除。
コントローラーノードの準備
Ansible PostgreSQLの役割、プレイブック、インベントリ、カスタムPostgreSQLレプリケーションを使用してコントローラーノードを準備します。
$ mkdir demo
$ pushd demo
$ mkdir roles
$ git clone https://github.com/Demonware/postgresql roles/postgresql
$ pushd roles/postgresql
$ git checkout add-repmgr-extension
ダウンロードされたロールには、2つのデフォルトの変数ファイルmain.ymlとrepmgr.ymlファイルがあります。ただし、Ansibleはmain.ymlファイルのみを考慮します。 Ansibleを作成するには、repmgr.ymlファイルも使用して、両方のファイルをdefaults/mainディレクトリに移動します。
$ mkdir defaults/main
$ mv defaults/main.yml defaults/repmgr.yml defaults/main
$ popd
Ansible Inventory File
デモでは、3つのノードにPostgreSQLレプリケーションクラスターをセットアップします。 3つのCentOSVMvm-01、vm-02、およびvm-03を作成しました。これらはすべて、development.yamlファイルのグループpostgres_clusterの下にリストされています。
$ cat development.yaml
all:
children:
postgres_cluster:
hosts:
vm-01:
vm-02:
vm-03:
vars:
ansible_user: "vagrant"
Ansible pingを実行し、グループpostgres_clusterの下のすべてのホストに到達できることを確認します。
$ ansible -i development.yaml -m ping postgres_cluster
vm-01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
vm-03 | SUCCESS => {
"changed": false,
"ping": "pong"
}
vm-02 | SUCCESS => {
"changed": false,
"ping": "pong"
}
カスタム変数ファイル
カスタム変数ファイルcustom-vars.yamlで、次のことを定義します。
- インストールするPostgreSQLのバージョンと使用するエンコーディング
- レプリケーションを有効にするためにPostgreSQL構成を変更し、wal_level、max_wal_senders、max_replication_slots、hot_standby、archive_mode、archive_commandなどのパラメーターを変更します
- 必要なユーザーとデータベースの作成
- アプリケーションとrepmgrレプリケーションからの必要な接続を許可するようにpg_hba.confファイルを変更します
- いくつかのrepmgr関連の変数
$ cat custom-vars.yaml
# Basic settings
postgresql_version: 11
postgresql_encoding: "UTF-8"
postgresql_locale: "en_US.UTF-8"
postgresql_ctype: "en_US.UTF-8"
postgresql_admin_user: "postgres"
postgresql_default_auth_method: "peer"
postgresql_listen_addresses: "*"
postgresql_wal_level: "replica"
postgresql_max_wal_senders: 10
postgresql_max_replication_slots: 10
postgresql_wal_keep_segments: 100
postgresql_hot_standby: on
postgresql_archive_mode: on
postgresql_archive_command: "/bin/true"
postgresql_shared_preload_libraries:
- repmgr
postgresql_users:
- name: "{{repmgr_user}}"
pass: "password"
postgresql_databases:
- name: "{{repmgr_database}}"
owner: "{{repmgr_user}}"
encoding: "UTF-8"
postgresql_user_privileges:
- name: "{{repmgr_user}}"
db: "{{repmgr_database}}"
priv: "ALL"
role_attr_flags: "SUPERUSER,REPLICATION"
postgresql_pg_hba_custom:
- { type: "host", database: "all", user: "all", address: "192.168.0.0/24", method: "md5" }
- { type: "host", database: "replication", user: "repmgr", address: "192.168.0.0/24", method: "md5" }
- { type: "host", database: "replication", user: "repmgr", address: "127.0.0.1/32", method: "md5" }
# repmgr related variables
postgresql_ext_install_repmgr: yes
repmgr_target_group: "postgres_cluster"
repmgr_target_group_hosts: "{{ groups[repmgr_target_group] }}"
repmgr_master: "vm-03"
以下は、custom-vars.yamlで定義されている注目すべき変数の一部です。
- postgresql_version:11-PostgreSQLバージョン11をインストールします
- postgresql_ext_install_repmgr:yes-PostgreSQLクラスターにrepmgr拡張機能をインストールします
- repmgr_target_group: "postgres_cluster"-Repmgrは、インベントリファイルで定義されたグループ"postgres_cluster"で定義されたホストで動作します
- repmgr_master: "vm-03"-ホストvm-03がPostgreSQLプライマリインスタンスになり、vm-01とvm--02がvm-03から複製されます
Ansible Playbook
以下のpostgres-play.yamlプレイブックでは、ホストグループpostgres_clusterに対してpostgresqlの役割を割り当てています。 PostgreSQLとrepmgrの構成を持つカスタム変数ファイルcustom-vars.yamlも含めました。
$ cat postgres-play.yaml
- hosts: postgres_cluster
become: yes
vars_files:
- ./custom-vars.yaml
roles:
- postgresql
AnsiblePlaybookの実行
これで、次のAnsibleアーティファクトが作成され、Ansibleプレイブックを実行する準備が整いました。
- roles / postgresql、Ansibleロールディレクトリ。
- custom-vars.yaml、Ansible変数ファイル。
- development.yaml、Ansibleインベントリファイル。
- postgres-play.yam、Ansibleプレイブックファイル。
コントローラノードから以下のansible-playbookコマンドを実行します。 postgresqlロールはコントローラーのsudoアクセスを想定しているため、コマンドで-Kオプションを指定します。これにより、コントローラーノードのSUDOパスワードの入力を求められます。
$ ansible-playbook -Ki development.yaml postgres-play.yaml
SUDO password:
PLAY [postgres_cluster] ********************************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************************************************
ok: [vm-01]
ok: [vm-02]
ok: [vm-03]
...
...
PLAY RECAP *********************************************************************************************************************************************************************************************************************************************************************
vm-01 : ok=41 changed=4 unreachable=0 failed=0
vm-02 : ok=41 changed=5 unreachable=0 failed=0
vm-03 : ok=43 changed=5 unreachable=0 failed=0
コマンド出力のPLAYRECAPをチェックし、失敗カウントが0であることを確認します。
PostgreSQLレプリケーションを確認する
以下のrepmgrclustershowコマンドを使用して、PostgreSQLレプリケーションクラスターのステータスを確認できます。レプリケーションクラスター内のすべてのPostgreSQLインスタンスの役割、ステータス、タイムラインが表示されます。
$ sudo -u postgres /usr/pgsql-11/bin/repmgr -f /etc/postgresql/11/data/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+-------+---------+-----------+----------+----------+----------+----------+--------------------------------------------------------
1 | vm-01 | standby | running | vm-03 | default | 100 | 1 | host=vm-01 user=repmgr dbname=repmgr connect_timeout=2
2 | vm-02 | standby | running | vm-03 | default | 100 | 1 | host=vm-02 user=repmgr dbname=repmgr connect_timeout=2
3 | vm-03 | primary | * running | | default | 100 | 1 | host=vm-03 user=repmgr dbname=repmgr connect_timeout=2
上記のコマンドの出力から、vm-03はプライマリであり、vm-01、vm02はアップストリームノードvm-03から複製するスタンバイインスタンスです。すべてのPostgreSQLインスタンスは実行状態です。
プライマリvm-03のpg_stat_replicationビューをチェックして、vm-01とvm-02の両方が正常に複製されていることを確認します。
$ sudo -iu postgres /usr/pgsql-11/bin/psql -h vm-03 -c 'select * from pg_stat_replication'
Password for user postgres:
pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state
------+----------+---------+------------------+---------------+-----------------+-------------+-------------------------------+--------------+-----------+-----------+-----------+-----------+------------+-----------+-----------+------------+---------------+------------
8480 | 16384 | repmgr | vm-02 | 192.168.0.122 | | 59972 | 2019-07-18 09:04:44.315859+00 | | streaming | 0/A000870 | 0/A000870 | 0/A000870 | 0/A000870 | | | | 0 | async
8481 | 16384 | repmgr | vm-01 | 192.168.0.121 | | 35598 | 2019-07-18 09:04:44.336693+00 | | streaming | 0/A000870 | 0/A000870 | 0/A000870 | 0/A000870 | | | | 0 | async
(2 rows)
クラスターへの別のスタンバイノードの追加
クラスターに別のPostgreSQLノードを追加するには、インベントリに特定のホストを追加した後、Ansibleプレイブックを再実行する必要があります。以下の手順では、vm-04を既存のRepmgrPostgresqlレプリケーションクラスターに追加しています。
- Ansibleインベントリファイルにvm-04を追加するdevelopmeb
$ cat development.yaml all: children: postgres_cluster: hosts: vm-01: vm-02: vm-03: vm-04: vars: ansible_user: "vagrant"
- Ansibleプレイブックを実行する
$ ansible-playbook -Ki development.yaml postgres-play.yaml SUDO password: PLAY [postgres_cluster] ******************************************************************************************************************************************************************************************************************************************************** TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************************************************* ok: [vm-01] ok: [vm-04] ok: [vm-03] ok: [vm-02] ... ... RUNNING HANDLER [postgresql : restart postgresql] ****************************************************************************************************************************************************************************************************************************** changed: [vm-04] changed: [vm-02] changed: [vm-01] changed: [vm-03] PLAY RECAP ********************************************************************************************************************************************************************************************************************************************************************* vm-01 : ok=41 changed=4 unreachable=0 failed=0 vm-02 : ok=41 changed=5 unreachable=0 failed=0 vm-03 : ok=43 changed=5 unreachable=0 failed=0 vm-04 : ok=46 changed=32 unreachable=0 failed=0
- レプリケーションクラスターを確認します
$ sudo -u postgres /usr/pgsql-11/bin/repmgr -f /etc/postgresql/11/data/repmgr.conf cluster show ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string ----+-------+---------+-----------+----------+----------+----------+----------+-------------------------------------------------------- 1 | vm-01 | standby | running | vm-03 | default | 100 | 1 | host=vm-01 user=repmgr dbname=repmgr connect_timeout=2 2 | vm-02 | standby | running | vm-03 | default | 100 | 1 | host=vm-02 user=repmgr dbname=repmgr connect_timeout=2 3 | vm-03 | primary | * running | | default | 100 | 1 | host=vm-03 user=repmgr dbname=repmgr connect_timeout=2 4 | vm-04 | standby | running | vm-03 | default | 100 | 1 | host=vm-04 user=repmgr dbname=repmgr connect_timeout=2
結論
これまで、Ansibleを使用したRepmgrPostgreSQLレプリケーションクラスターのセットアップについて見てきました。 repmgrクラスターがセットアップされたら、repmgrコマンドを使用して、プライマリノードのフェイルオーバーとスイッチオーバーの実行やカスケードレプリケーションのセットアップなど、レプリケーションクラスターの他のメンテナンスを実行できます。詳細については、repmgrのドキュメントを確認してください。