Репликацията е ключова характеристика за повечето настройки и се поддържа от повечето технологии за бази данни на пазара. Общността на PostgreSQL въведе репликация във версия 9.0 (наречена поточно репликация или SR), оттогава репликацията в PostgreSQL се е развила с допълнителни функции като каскадна репликация, логическо декодиране и още няколко оптимизации.
В този блог ще разгледаме използването на ролята на Ansible postgresql, разработена от „Demonware“ (разклонение на ролята „ANXS/postgresql“). Вече говорих за използването на ролята „ANXS/postgresql“ в предишния си блог, но не обсъждах функцията за репликация. Ролята на Ansible „postgresql“ добавя възможността за настройка на репликация на PostgreSQL с помощта на repmgr.
Относно 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
В изтеглената роля има два файла с променливи по подразбиране 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
За демонстрацията ще настроим клъстера за репликация на PostgreSQL на три възела. Създадох три виртуални машини на CentOS vm-01, vm-02 и vm-03, всички те са изброени под групата postgres_cluster във файла development.yaml.
$ cat development.yaml
all:
children:
postgres_cluster:
hosts:
vm-01:
vm-02:
vm-03:
vars:
ansible_user: "vagrant"
Направете ping на Ansible и се уверете, че можем да достигнем до всички хостове в групата 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
- Създаване на необходимите потребители и база данни
- Промяна на файла pg_hba.conf, за да позволи необходимата връзка от приложението и репликирането на repmgr
- Някои променливи, свързани с 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:да - Инсталира разширение repmgr в клъстера PostgreSQL
- 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 съм присвоил ролята postgresql срещу хост групата postgres_cluster. Включих също персонализиран файл с променлива custom-vars.yaml, който има конфигурацията за PostgreSQL и repmgr.
$ cat postgres-play.yaml
- hosts: postgres_cluster
become: yes
vars_files:
- ./custom-vars.yaml
roles:
- postgresql
Изпълнение на Ansible Playbook
Вече създадохме следните артефакти на Ansible и сме готови да стартираме Ansible playbook.
- roles/postgresql, Ansible ролева директория.
- custom-vars.yaml, Ansible променлив файл.
- development.yaml, Ansible инвентарен файл.
- postgres-play.yam, Ansible playbook файл.
Изпълнете командата 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
Проверете PLAY RECAP в изхода на командата и се уверете, че неуспешният брой е 0.
Проверете репликацията на PostgreSQL
С по-долу командата repmgr cluster show можем да проверим състоянието на клъстера за репликация на 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 са в работещо състояние.
Проверка на изгледа pg_stat_replication на основния vm-03, за да се потвърди, че 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 playbook, след като добавим конкретния хост в инвентара. В стъпките по-долу добавям vm-04 към моя съществуващ репликационен клъстер Repmgr Postgresql.
- Добавяне на vm-04 към файла с инвентаризацията на Ansible developmeb
$ cat development.yaml all: children: postgres_cluster: hosts: vm-01: vm-02: vm-03: vm-04: vars: ansible_user: "vagrant"
- Изпълнете 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
- Проверете клъстер за репликация
$ 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
Заключение
Досега видяхме настройката на Repmgr PostgreSQL репликационния клъстер с помощта на Ansible. След като клъстерът repmgr е настроен, можем да използваме командата repmgr, за да извършим друга поддръжка на клъстера за репликация, като извършване на отказ и превключване на първичния възел и настройка на каскадна репликация. Моля, проверете документацията на repmgr за повече подробности.