Replikering er en nøglefunktion for de fleste opsætninger, og den understøttes af de fleste databaseteknologier på markedet. PostgreSQL-fællesskabet introducerede replikering i version 9.0 (kaldet Streaming Replication eller SR), siden da har replikeringen i PostgreSQL udviklet sig med yderligere funktioner som Cascading Replication, Logical Decoding og adskillige flere optimeringer.
I denne blog vil vi se på at bruge Ansible-rollen postgresql som udviklet af "Demonware" (en forgrening af rollen "ANXS/postgresql"). Jeg havde allerede talt om at bruge rollen "ANXS/postgresql" i min tidligere blog, men jeg diskuterede ikke replikeringsfunktionen. Ansible-rollen "postgresql" tilføjer muligheden for at konfigurere PostgreSQL-replikering ved hjælp af repmgr.
Om Repmgr
Repmgr er et open source kommandolinjeværktøj udviklet og vedligeholdt af 2ndQuadrant. Værktøjet automatiserer de fleste opgaver relateret til styring af PostgreSQL-replikeringsklyngen. Nedenfor er listen over opgaver, der kan udføres problemfrit ved hjælp af repmgr-kommandoen og repmgrd-dæmonen.
- Opstart af PostgreSQL-replikeringsklyngen.
- Udfører auto-failover og manuel omskiftning af den primære instans.
- Tilføjelse og fjernelse af standby-forekomster (læse-replika).
Forberedelse af Controller Node
Forbered controller-noden med Ansible PostgreSQL-rollen, playbooks, opgørelser og tilpasset PostgreSQL-replikering.
$ mkdir demo
$ pushd demo
$ mkdir roles
$ git clone https://github.com/Demonware/postgresql roles/postgresql
$ pushd roles/postgresql
$ git checkout add-repmgr-extension
I den downloadede rolle er der to standard variable filer main.yml og repmgr.yml fil. Ansible vil dog kun overveje filen main.yml. For at gøre Ansible også bruge filen repmgr.yml, vi flytter begge filer under mappen defaults/main.
$ mkdir defaults/main
$ mv defaults/main.yml defaults/repmgr.yml defaults/main
$ popd
Ansible Inventory File
Til demoen opsætter vi PostgreSQL-replikeringsklyngen på tre noder. Jeg oprettede tre CentOS VM'er vm-01, vm-02 og vm-03, alle er opført under gruppen postgres_cluster i filen development.yaml.
$ cat development.yaml
all:
children:
postgres_cluster:
hosts:
vm-01:
vm-02:
vm-03:
vars:
ansible_user: "vagrant"
Lav Ansible ping og sørg for, at vi er i stand til at nå alle værterne under gruppen 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"
}
Tilpasset variabelfil
I den tilpassede variabelfil custom-vars.yaml vil vi definere følgende ting:
- PostgreSQL-version til installation og kodning til brug
- Ved at ændre PostgreSQL-konfigurationen for at aktivere replikering, vil vi ændre parametre som wal_level, max_wal_senders, max_replication_slots, hot_standby, archive_mode, archive_command
- Oprettelse af de nødvendige brugere og database
- Ændring af filen pg_hba.conf for at tillade den nødvendige forbindelse fra applikationen og repmgr-replikeringen
- Nogle repmgr-relaterede variabler
$ 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"
Følgende er nogle af de bemærkelsesværdige variabler defineret i custom-vars.yaml:
- postgresql_version:11 - Installerer PostgreSQL version 11
- postgresql_ext_install_repmgr:ja - Installerer repmgr-udvidelsen på PostgreSQL-klyngen
- repmgr_target_group:"postgres_cluster" - Repmgr fungerer på værterne defineret under gruppen "postgres_cluster" defineret i inventarfilen
- repmgr_master:"vm-03" - Host vm-03 vil være den primære PostgreSQL-instans, vm-01 og vm--02 vil replikere fra vm-03
Ansible Playbook
I nedenstående postgres-play.yaml playbook har jeg tildelt rollen postgresql mod værtsgruppen postgres_cluster. Jeg har også inkluderet tilpasset variabel fil custom-vars.yaml, som har konfigurationen til PostgreSQL og repmgr.
$ cat postgres-play.yaml
- hosts: postgres_cluster
become: yes
vars_files:
- ./custom-vars.yaml
roles:
- postgresql
Kører Ansible Playbook
Vi har nu oprettet følgende Ansible-artefakter, og vi er klar til at køre Ansible-spillebogen.
- roller/postgresql, Ansible rollemappe.
- custom-vars.yaml, Ansible variabel fil.
- development.yaml, Ansible inventarfil.
- postgres-play.yam, Ansible playbook-fil.
Kør nedenstående ansible-playbook-kommando fra controller-noden. Da postgresql-rollen forventer sudo-adgang for controlleren, angiver vi -K-optionen i kommandoen, som igen beder os om at indtaste SUDO-adgangskoden for controller-knuden.
$ 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
Tjek PLAY RECAP i kommandoudgangen, og sørg for, at antallet af fejlslag er 0.
Tjek PostgreSQL-replikering
Med nedenstående repmgr cluster show-kommando kan vi kontrollere status for PostgreSQL-replikeringsklyngen. Den viser rollen, status og tidslinje for hele PostgreSQL-forekomsten i replikeringsklyngen.
$ 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
Fra outputtet af ovenstående kommando er vm-03 den primære og vm-01,vm02 er standby-instansen, der replikerer fra opstrømsknuden vm-03. Alle PostgreSQL-forekomster er i kørende tilstand.
Kontrollerer pg_stat_replication view på primær vm-03 for at bekræfte, at både vm-01 og vm-02 replikerer fint.
$ 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)
Tilføjelse af en anden standby-knude til klyngen
For at tilføje en anden PostgreSQL-node til klyngen skal vi bare køre Ansible-afspilningsbogen igen efter at have tilføjet den særlige vært i inventaret. I nedenstående trin tilføjer jeg vm-04 til min eksisterende Repmgr Postgresql replikeringsklynge.
- Tilføjelse af vm-04 til Ansible inventory-filen developmeb
$ cat development.yaml all: children: postgres_cluster: hosts: vm-01: vm-02: vm-03: vm-04: vars: ansible_user: "vagrant"
- Kør Ansible playbook
$ 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
- Tjek replikeringsklynge
$ 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
Konklusion
Indtil videre har vi set på opsætning af Repmgr PostgreSQL replikeringsklyngen ved hjælp af Ansible. Når repmgr-klyngen er konfigureret, kan vi bruge repmgr-kommandoen til at udføre anden vedligeholdelse på replikerings-klyngen som at lave failover og switch-over af den primære node og opsætte kaskadereplikering. Se venligst repmgr-dokumentationen for flere detaljer.