Die Replikation ist eine Schlüsselfunktion für die meisten Setups und wird von den meisten Datenbanktechnologien auf dem Markt unterstützt. Die PostgreSQL-Community hat die Replikation in Version 9.0 (genannt Streaming Replication oder SR) eingeführt, seitdem hat sich die Replikation in PostgreSQL mit zusätzlichen Funktionen wie Cascading Replication, Logical Decoding und mehreren weiteren Optimierungen weiterentwickelt.
In diesem Blog werden wir uns mit der Verwendung der Ansible-Rolle postgresql befassen, wie sie von „Demonware“ entwickelt wurde (eine Verzweigung der Rolle „ANXS/postgresql“). Ich hatte bereits in meinem vorherigen Blog über die Verwendung der Rolle „ANXS/postgresql“ gesprochen, aber ich habe die Replikationsfunktion nicht besprochen. Die Ansible-Rolle „postgresql“ fügt die Möglichkeit hinzu, die PostgreSQL-Replikation mit repmgr.
einzurichtenÜber Repmgr
Repmgr ist ein Open-Source-Befehlszeilentool, das von 2ndQuadrant entwickelt und gepflegt wird. Das Tool automatisiert die meisten Aufgaben im Zusammenhang mit der Verwaltung des PostgreSQL-Replikationsclusters. Nachfolgend finden Sie eine Liste von Aufgaben, die mit dem repmgr-Befehl und dem repmgrd-Daemon problemlos ausgeführt werden können.
- Bootstrapping des PostgreSQL-Replikationsclusters.
- Automatisches Failover und manuelles Umschalten der primären Instanz.
- Hinzufügen und Entfernen der Standby-Instanzen (Lesereplikate).
Vorbereiten des Controller-Knotens
Bereiten Sie den Controller-Knoten mit der Ansible PostgreSQL-Rolle, Playbooks, Inventaren und benutzerdefinierter PostgreSQL-Replikation vor.
$ mkdir demo
$ pushd demo
$ mkdir roles
$ git clone https://github.com/Demonware/postgresql roles/postgresql
$ pushd roles/postgresql
$ git checkout add-repmgr-extension
In der heruntergeladenen Rolle gibt es zwei standardmäßige Variablendateien:main.yml und repmgr.yml. Ansible berücksichtigt jedoch nur die Datei main.yml. Damit Ansible auch die Datei repmgr.yml verwendet, verschieben wir beide Dateien in das Verzeichnis defaults/main.
$ mkdir defaults/main
$ mv defaults/main.yml defaults/repmgr.yml defaults/main
$ popd
Ansible-Inventardatei
Für die Demo richten wir den PostgreSQL-Replikationscluster auf drei Knoten ein. Ich habe drei CentOS-VMs vm-01, vm-02 und vm-03 erstellt, die alle unter der Gruppe postgres_cluster in der Datei development.yaml aufgelistet sind.
$ cat development.yaml
all:
children:
postgres_cluster:
hosts:
vm-01:
vm-02:
vm-03:
vars:
ansible_user: "vagrant"
Führen Sie einen Ansible-Ping durch und stellen Sie sicher, dass wir alle Hosts unter der Gruppe postgres_cluster erreichen können.
$ 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"
}
Benutzerdefinierte Variablendatei
In der benutzerdefinierten Variablendatei custom-vars.yaml definieren wir die folgenden Dinge:
- Zu installierende PostgreSQL-Version und zu verwendende Codierung
- Beim Ändern der PostgreSQL-Konfiguration zum Aktivieren der Replikation ändern wir die Parameter wie wal_level, max_wal_senders, max_replication_slots, hot_standby, archive_mode, archive_command
- Erstellen der erforderlichen Benutzer und der Datenbank
- Ändern der pg_hba.conf-Datei, um die notwendige Verbindung von der Anwendung und der repmgr-Replikation zu ermöglichen
- Einige repmgr-bezogene Variablen
$ 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"
Im Folgenden sind einige der bemerkenswerten Variablen aufgeführt, die in custom-vars.yaml definiert sind:
- postgresql_version:11 – Installiert PostgreSQL-Version 11
- postgresql_ext_install_repmgr:yes – Installiert die repmgr-Erweiterung auf dem PostgreSQL-Cluster
- repmgr_target_group:"postgres_cluster" - Repmgr arbeitet auf den Hosts, die unter der in der Inventardatei definierten Gruppe "postgres_cluster" definiert sind
- repmgr_master:"vm-03" - Host vm-03 wird die primäre PostgreSQL-Instanz sein, vm-01 und vm--02 werden von vm-03 repliziert
Ansible-Playbook
Im folgenden postgres-play.yaml-Playbook habe ich der Hostgruppe postgres_cluster die Rolle postgresql zugewiesen. Ich habe auch die benutzerdefinierte Variablendatei custom-vars.yaml eingefügt, die die Konfiguration für PostgreSQL und repmgr enthält.
$ cat postgres-play.yaml
- hosts: postgres_cluster
become: yes
vars_files:
- ./custom-vars.yaml
roles:
- postgresql
Ansible Playbook ausführen
Wir haben jetzt die folgenden Ansible-Artefakte erstellt und sind bereit, das Ansible-Playbook auszuführen.
- roles/postgresql, Ansible-Rollenverzeichnis.
- custom-vars.yaml, Ansible-Variablendatei.
- development.yaml, Ansible-Inventardatei.
- postgres-play.yam, Ansible-Playbook-Datei.
Führen Sie den folgenden ansible-playbook-Befehl vom Controller-Knoten aus. Da die postgresql-Rolle den sudo-Zugriff des Controllers erwartet, geben wir im Befehl die Option -K an, die uns wiederum auffordert, das SUDO-Passwort des Controller-Knotens einzugeben.
$ 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
Überprüfen Sie die PLAY RECAP in der Befehlsausgabe und stellen Sie sicher, dass die Fehleranzahl 0 ist.
PostgreSQL-Replikation prüfen
Mit dem folgenden Befehl repmgr cluster show können wir den Status des PostgreSQL-Replikationsclusters überprüfen. Es zeigt die Rolle, den Status und die Zeitleiste aller PostgreSQL-Instanzen im Replikationscluster.
$ 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
Aus der Ausgabe des obigen Befehls geht hervor, dass vm-03 die primäre und vm-01, vm02 die Standby-Instanz sind, die vom Upstream-Knoten vm-03 repliziert werden. Alle PostgreSQL-Instanzen befinden sich im Ausführungsstatus.
Überprüfen Sie die pg_stat_replication-Ansicht auf dem primären vm-03, um zu bestätigen, dass sowohl vm-01 als auch vm-02 einwandfrei replizieren.
$ 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)
Hinzufügen eines weiteren Standby-Knotens zum Cluster
Um einen weiteren PostgreSQL-Knoten zum Cluster hinzuzufügen, müssen wir das Ansible-Playbook einfach erneut ausführen, nachdem wir den jeweiligen Host in der Bestandsliste hinzugefügt haben. In den folgenden Schritten füge ich vm-04 zu meinem vorhandenen Repmgr Postgresql-Replikationscluster hinzu.
- Hinzufügen von vm-04 zur Ansible-Inventardatei developmentmeb
$ cat development.yaml all: children: postgres_cluster: hosts: vm-01: vm-02: vm-03: vm-04: vars: ansible_user: "vagrant"
- Ansible Playbook ausführen
$ 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
- Replikationscluster prüfen
$ 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
Schlussfolgerung
Bisher haben wir die Einrichtung des Repmgr PostgreSQL-Replikationsclusters mit Ansible gesehen. Nachdem der repmgr-Cluster eingerichtet wurde, können wir den repmgr-Befehl verwenden, um andere Wartungsarbeiten am Replikationscluster durchzuführen, z. B. Failover und Switchover des primären Knotens und Einrichten der Kaskadenreplikation. Weitere Einzelheiten finden Sie in der repmgr-Dokumentation.