0

Настройка потоковой репликации PostgreSQL

Тематические термины: PostgreSQL.

Репликация PostgreSQL представляет из себя способ реализации отказоустойчивого кластера. Инструкция написана на примере PostgreSQL 14/13/12/11/10/9.6, также она будет работать для PostgreSQL 9.2 (все нюансы будут отмечены отдельными комментариями).

В данном примере мы настроим потоковую (streaming) репликацию. Другой тип репликации (логическая) добавлена в PostgreSQL 10. Она позволяет реплицировать разные базы данных и таблицы на разные реплики.

Также, мы будем применять асинхронную репликацию — это вид репликации, при котором запросы выполняются сначала на мастере, затем попадают в журнал операций (WAL) и только после этого — на slave. При синхронной репликации запросы сначала попадают в WAL — после в мастер и слейв.

Используемые в данном руководстве команды, применимы для операционных систем Linux. Если Postgre работает под Windows, данную инструкцию можно использовать как шпаргалку для настройки конфигурационных файлов СУБД.

1. Подготовка серверов

Для начала, готовим наши серверы к настройке кластера.

PostgreSQL

На всех серверах баз данных должна быть установлена одна и та же версия PostgreSQL. Также, все серверы должны иметь одну и ту же архитектуру процессора.

Вот пример установки сервера PostgreSQL на CentOS 7.

Брандмауэр

При использовании брандмауэра, необходимо открыть TCP-порт 5432 — он используется сервером postgre.

а) Если управление выполняется с помощью Firewalld:

firewall-cmd --permanent --add-port=5432/tcp

firewall-cmd --reload

б) Если используем Iptables:

iptables -A INPUT -p tcp --dport 5432 -j ACCEPT

в) Если используем UFW:

ufw allow 5432/tcp

SELinux

Если активирована система безопасности SELinux (по умолчанию в системах Red Hat / CentOS / Fedora), отключаем ее:

setenforce 0

sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config

Если необходимо, чтобы SELinux работал, настраиваем его.

2. Настройки на Master

В данной статье мы будем настраивать серверы с IP-адресами 192.168.1.10 (первичный или master) и 192.168.1.11 (вторичный или slave).

Переходим на сервер, с которого будем реплицировать данные (мастер) и выполняем следующие действия.

Создаем пользователя в PostgreSQL

Входим в систему под пользователем postgres:

su - postgres

Создаем нового пользователя для репликации:

createuser --replication -P repluser

* система запросит пароль — его нужно придумать и ввести дважды. В данном примере мы создаем пользователя repluser.

Выходим из оболочки пользователя postgres:

exit

Настраиваем postgresql

Смотрим расположение конфигурационного файла postgresql.conf командой:

su - postgres -c "psql -c 'SHOW config_file;'"

В моем случае система вернула строку:

 /etc/postgresql/9.6/main/postgresql.conf

* конфигурационный файл находится по пути /etc/postgresql/9.6/main/postgresql.conf.

Открываем конфигурационный файл postgresql.conf.

vi /etc/postgresql/9.6/main/postgresql.conf

* мы открываем файл, который получили sql-командой SHOW config_file;.

Редактируем следующие параметры:

listen_addresses = 'localhost, 192.168.1.10'
wal_level = replica
max_wal_senders = 2
max_replication_slots = 2
hot_standby = on
hot_standby_feedback = on

* где

  • 192.168.1.10 — IP-адрес сервера, на котором он будем слушать запросы Postgre; 
  • wal_level указывает, сколько информации записывается в WAL (журнал операций, который используется для репликации); 
  • max_wal_senders — количество планируемых слейвов; 
  • max_replication_slots — максимальное число слотов репликации (данный параметр не нужен для postgresql 9.2 — с ним сервер не запустится); 
  • hot_standby — определяет, можно или нет подключаться к postgresql для выполнения запросов в процессе восстановления; 
  • hot_standby_feedback — определяет, будет или нет сервер slave сообщать мастеру о запросах, которые он выполняет.

Открываем конфигурационный файл pg_hba.conf — он находитсяч в том же каталоге, что и файл postgresql.conf:

vi /etc/postgresql/9.6/main/pg_hba.conf

Добавляем следующие строки:

host replication repluser 127.0.0.1/32 md5
host replication repluser 192.168.1.10/32 md5
host replication repluser 192.168.1.11/32 md5

* данной настройкой мы разрешаем подключение к базе данных replication пользователю repluser с локального сервера (localhost и 192.168.1.10) и сервера 192.168.1.11.

Перезапускаем службу postgresql:

systemctl restart postgresql

* обратите внимание, что название для сервиса в системах Linux может различаться.

3. Настройки на Slave

Смотрим путь до конфигурационного файла postgresql:

su - postgres -c "psql -c 'SHOW data_directory;'" 

В моем случае путь был:

/var/lib/pgsql/9.6/data

Также смотрим путь до конфигурационного файла postgresql.conf (нам это понадобиться ниже):

su - postgres -c "psql -c 'SHOW config_file;'"

Останавливаем сервис postgresql:

systemctl stop postgresql

На всякий случай, создаем архив базы:

tar -czvf /tmp/data_pgsql.tar.gz /var/lib/pgsql/9.6/data

* в данном примере мы сохраним все содержимое каталога /var/lib/pgsql/9.6/data в виде архива /tmp/data_pgsql.tar.gz.

Удаляем содержимое каталога с данными:

rm -rf /var/lib/pgsql/9.6/data/*

И реплицируем данные с master сервера.

а) Если у нас postgresql 9:

su -u postgres -с "pg_basebackup -h 192.168.1.10 -U repluser -D /var/lib/pgsql/9.6/data --xlog-method=stream --write-recovery-conf"

* где 192.168.1.10 — IP-адрес мастера; /var/lib/pgsql/9.6/data — путь до каталога с данными.

б) Если у нас postgresql 10:

su - postgres -c "pg_basebackup --host=192.168.1.10 --username=repluser --pgdata=/var/lib/pgsql/10/data --wal-method=stream --write-recovery-conf"

* где 192.168.1.10 — IP-адрес мастера; /var/lib/pgsql/10/data — путь до каталога с данными.

После ввода команды система запросит пароль для созданной ранее учетной записи repluser — вводим его. Начнется процесс клонирования данных.

Открываем конфигурационный файл postgresql.conf на слейве:

vi /etc/postgresql/9.6/main/postgresql.conf

И редактируем следующие параметры:

listen_addresses = 'localhost, 192.168.1.11'

* где 192.168.1.11 — IP-адрес нашего вторичного сервера.

Снова запускаем сервис postgresql:

systemctl start postgresql

4. Проверка репликации

Посмотреть статус

Статус работы репликации можно посмотреть следующими командами.

На мастере:

=# select * from pg_stat_replication;

На слейве:

=# select * from pg_stat_wal_receiver;

Создать тестовую базу

На мастере заходим в командную оболочку Postgre:

su - postgres -c "psql"

Создаем новую базу данных:

=# CREATE DATABASE repltest ENCODING='UTF8';

Теперь на вторичном сервере смотрим список баз:

su - postgres -c "psql"

=# \l

Мы должны увидеть среди баз ту, которую создали на первичном сервере:

   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access
-----------+----------+----------+-------------+-------------+-----------------
 ...
 repltest  | postgres | UTF8     | ru_RU.UTF-8 | ru_RU.UTF-8 | 

Свежие комментарии

Подписка

Лучшие статьи


Fatal error: Uncaught Error: Call to a member function have_posts() on null in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php:398 Stack trace: #0 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/widget.php(257): fox56_blog_grid(NULL, Array) #1 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/widgets/latest-posts/register.php(33): include('/home/host18670...') #2 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/class-wp-widget.php(394): Wi_Widget_Latest_Posts->widget(Array, Array) #3 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/widgets.php(845): WP_Widget->display_callback(Array, Array) #4 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(418): dynamic_sidebar('sidebar') #5 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(136): fox56_single_sidebar() #6 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/single.php(7): fox56_single_inner() #7 /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/single.php(23): fox56_single() #8 /home/host1867038/the-devops.ru/htdocs/www/wp-includes/template-loader.php(106): include('/home/host18670...') #9 /home/host1867038/the-devops.ru/htdocs/www/wp-blog-header.php(19): require_once('/home/host18670...') #10 /home/host1867038/the-devops.ru/htdocs/www/index.php(17): require('/home/host18670...') #11 {main} thrown in /home/host1867038/the-devops.ru/htdocs/www/wp-content/themes/fox/inc/blog.php on line 398