PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Einrichtung und Wartung der PostgreSQL-Replikation mit Ansible

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.

  1. 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"
  2. 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
  3. 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.