Replikacja jest kluczową funkcją większości konfiguracji i jest obsługiwana przez większość technologii bazodanowych dostępnych na rynku. Społeczność PostgreSQL wprowadziła replikację w wersji 9.0 (zwanej Streaming Replication lub SR), od tego czasu replikacja w PostgreSQL ewoluowała wraz z dodatkowymi funkcjami, takimi jak replikacja kaskadowa, dekodowanie logiczne i kilka innych optymalizacji.
W tym blogu przyjrzymy się wykorzystaniu roli Ansible postgresql opracowanej przez „Demonware” (rozwidlenie roli „ANXS/postgresql”). Mówiłem już o używaniu roli „ANXS/postgresql” na moim poprzednim blogu, ale nie omawiałem funkcji replikacji. Rola Ansible „postgresql” dodaje możliwość skonfigurowania replikacji PostgreSQL za pomocą repmgr.
O przedstawicielach
Repmgr to narzędzie wiersza poleceń o otwartym kodzie źródłowym, opracowane i utrzymywane przez 2ndQuadrant. Narzędzie automatyzuje większość zadań związanych z zarządzaniem klastrem replikacyjnym PostgreSQL. Poniżej znajduje się lista zadań, które można wykonać płynnie za pomocą polecenia repmgr i demona repmgrd.
- Rozruch klastra replikacji PostgreSQL.
- Wykonywanie automatycznego przełączania awaryjnego i ręcznego przełączania instancji podstawowej.
- Dodawanie i usuwanie instancji gotowości (repliki do odczytu).
Przygotowywanie węzła kontrolera
Przygotuj węzeł kontrolera z rolą Ansible PostgreSQL, podręcznikami, inwentarzami i niestandardową replikacją PostgreSQL.
$ mkdir demo
$ pushd demo
$ mkdir roles
$ git clone https://github.com/Demonware/postgresql roles/postgresql
$ pushd roles/postgresql
$ git checkout add-repmgr-extension
W pobranej roli znajdują się dwa domyślne pliki zmiennych main.yml i plik repmgr.yml. Jednak Ansible rozważy tylko plik main.yml. Aby Ansible używał również pliku repmgr.yml, przenosimy oba pliki do katalogu defaults/main.
$ mkdir defaults/main
$ mv defaults/main.yml defaults/repmgr.yml defaults/main
$ popd
Plik inwentarzowy Ansible
Na potrzeby demonstracji skonfigurujemy klaster replikacji PostgreSQL na trzech węzłach. Stworzyłem trzy maszyny wirtualne CentOS vm-01, vm-02 i vm-03, wszystkie są wymienione w grupie postgres_cluster w pliku development.yaml.
$ cat development.yaml
all:
children:
postgres_cluster:
hosts:
vm-01:
vm-02:
vm-03:
vars:
ansible_user: "vagrant"
Wykonaj polecenie Ansible i upewnij się, że jesteśmy w stanie połączyć się ze wszystkimi hostami w grupie 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"
}
Plik zmiennej niestandardowej
W niestandardowym pliku zmiennych custom-vars.yaml zdefiniujemy następujące rzeczy:
- Wersja PostgreSQL do zainstalowania i kodowania do użycia
- Modyfikując konfigurację PostgreSQL, aby umożliwić replikację, zmodyfikujemy parametry, takie jak wal_level, max_wal_senders, max_replication_slots, hot_standby, archive_mode, archive_command
- Tworzenie niezbędnych użytkowników i bazy danych
- Zmodyfikowanie pliku pg_hba.conf, aby umożliwić niezbędne połączenie z aplikacji i replikację repmgr
- Niektóre zmienne związane z 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"
Oto niektóre z godnych uwagi zmiennych zdefiniowanych w custom-vars.yaml:
- postgresql_version:11 — instaluje PostgreSQL w wersji 11
- postgresql_ext_install_repmgr:yes - Instaluje rozszerzenie repmgr w klastrze PostgreSQL
- repmgr_target_group:"postgres_cluster" - Repmgr działa na hostach zdefiniowanych w grupie "postgres_cluster" zdefiniowanej w pliku inwentarza
- repmgr_master:„vm-03” — Host vm-03 będzie podstawową instancją PostgreSQL, vm-01 i vm--02 będą replikować się z vm-03
Poradnik Ansible
W poniższym podręczniku postgres-play.yaml przypisałem rolę postgresql grupie gospodarzy postgres_cluster. Dołączyłem również niestandardowy plik zmiennych custom-vars.yaml, który ma konfigurację dla PostgreSQL i repmgr.
$ cat postgres-play.yaml
- hosts: postgres_cluster
become: yes
vars_files:
- ./custom-vars.yaml
roles:
- postgresql
Uruchamianie podręcznika Ansible
Stworzyliśmy teraz następujące artefakty Ansible i jesteśmy gotowi do uruchomienia podręcznika Ansible.
- roles/postgresql, katalog ról Ansible.
- custom-vars.yaml, plik zmiennych Ansible.
- development.yaml, plik inwentarza Ansible.
- postgres-play.yam, plik podręcznika Ansible.
Uruchom poniższe polecenie ansible-playbook z węzła kontrolera. Ponieważ rola postgresql oczekuje dostępu sudo do kontrolera, podajemy w poleceniu opcję -K, która z kolei prosi nas o wprowadzenie hasła SUDO węzła kontrolera.
$ 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
Sprawdź ODTWÓRZ RECAP w danych wyjściowych polecenia i upewnij się, że liczba nieudanych prób wynosi 0.
Sprawdź replikację PostgreSQL
Za pomocą poniższego polecenia repmgr cluster show możemy sprawdzić stan klastra replikacji PostgreSQL. Pokazuje rolę, status, oś czasu wszystkich instancji PostgreSQL w klastrze replikacji.
$ 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
Z danych wyjściowych powyższego polecenia wynika, że vm-03 jest podstawowym, a vm-01,vm02 jest instancją rezerwową replikującą się z węzła nadrzędnego vm-03. Wszystkie instancje PostgreSQL są uruchomione.
Sprawdzanie widoku pg_stat_replication na podstawowej maszynie vm-03, aby potwierdzić, że zarówno vm-01, jak i vm-02 replikują się prawidłowo.
$ 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)
Dodawanie kolejnego węzła gotowości do klastra
Aby dodać kolejny węzeł PostgreSQL do klastra, wystarczy ponownie uruchomić podręcznik Ansible po dodaniu konkretnego hosta do ekwipunku. W poniższych krokach dodaję vm-04 do mojego istniejącego klastra replikacji Repmgr Postgresql.
- Dodanie vm-04 do pliku inwentarza Ansible developmentmeb
$ cat development.yaml all: children: postgres_cluster: hosts: vm-01: vm-02: vm-03: vm-04: vars: ansible_user: "vagrant"
- Uruchom 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
- Sprawdź klaster replikacji
$ 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
Wniosek
Do tej pory widzieliśmy konfigurowanie klastra replikacji Repmgr PostgreSQL przy użyciu Ansible. Po skonfigurowaniu klastra repmgr możemy użyć polecenia repmgr do wykonywania innych czynności konserwacyjnych w klastrze replikacji, takich jak przełączanie awaryjne i przełączanie węzła podstawowego oraz konfigurowanie replikacji kaskadowej. Więcej informacji można znaleźć w dokumentacji repmgr.