Настройка репликации в postgresql
Потоковая репликация
Потоковая репликация postgresql предназначена для реализации отказустойчивого кластера и повышение производительности
Когда postgresql получает команду на изменение данных, изменения сначала записываются в WAL. Этот журнал нужен для того, чтобы в случае сбоя можно было восстановить неза
фиксированные данные.
Потоковая асинхронная репликация (Streaming Replication) - запросы выполняются сначала на мастере, затем передаются в журнал операций ( WAL ) и только после этого на slave, таким образом изменения, происходящие на основном сервере (Master), будут дублироваться на другом (Slave). В данном случае преимуществом является более быстрое подтверждение транзакции. Недостатком является возможная потеря данных, если основной сервер выходит из строя, но данные не успели продубироваться на реплике.
При синхронной репликации запросы сначала попадают в WAL одной из реплик — после в мастер и остальные slave. Такой способ более медленный, так как данные сначала дублируются на реплике.
На обоих серверах master и slave должны быть одинкавые архитектуры процессоров, должна быть установлена одна и та же версия postgresql
На обоих серверах должен быть открыт порт 5432
Логическая репликация
Логическая репликация оперирует записями в таблицах, в отличии от физической репликации которая оперирует физическим уровнем данных, биты, байты и адреса блоков на диске.
Данный вид репликации основан на принципе публикации и подписки, когда один сервер публикует изменения, другой подписывается на них
В логической репликации нельзя реплицировать изменения структуры базы данных, например создание отдельной таблицы или ее столбца
В отличии от потоковой репликации, логическая репликация может работать между разными версиями postgresql, ос и архитектурами
Создание потоковой репликации c master на slave
#Создаем пользователя на сервере master
$ sudo -u postgres createuser --replication -P repluser
Enter password for new role:
Enter it again:
#Или
ALTER ROLE repluser PASSWORD 'ВАШ_ПАРОЛЬ'
#Проверим, что данный пользователь существует в базе данных
sudo -u postgres psql
\du
#Открываем конфигурационный файл на сервере master
vim /etc/postgresql/14/main/postgresql.conf
#Добавляем следующие данные
# Настройка репликации
listen_addresses = 'localhost, 192.168.1.7'
wal_level = replica
max_wal_senders = 2
max_replication_slots = 2
hot_standby = on
hot_standby_feedback = on
#Редактируем файл pg_hba.conf
#Добавляем строки
host replication repluser 127.0.0.1/32 md5
host replication repluser 192.168.1.7/32 md5 #master
host replication repluser 192.168.1.8/32 md5 #slave
#Сохранение изменений
/etc/init.d/postgresql restart
Настройка на slave
#Редактируем файл pg_hba.conf
host replication repluser 192.168.1.7/32 md5
#Редактируем файл postgresql.conf
listen_addresses = 'localhost, 192.168.1.8'
wal_level = replica
max_wal_senders = 2
max_replication_slots = 2
hot_standby = on
hot_standby_feedback = on
#Перезапускаем конфигурацию
/etc/init.d/postgresql restart
#Реплицируем данные с master сервера
#Каталог data должен быть пустым
/etc/init.d/postgresql stop; rm -fr /var/lib/postgresql/data/*
#Запуск
su - postgres -c "pg_basebackup -R --progress --host=192.168.1.7 --username=repluser --pgdata=/var/lib/postgresql/data --wal-method=stream --write-recovery-conf"
Password:
#192.168.1.7 master сервер
#pg_basebackup - Указывает серверу начать потоковую передачу базовой копии. Система автоматически переходит в режим резервного копирования до начала передачи, и выходит из него после завершения копирования.
#--pgdata=/var/lib/postgresql/data это путь до каталога данных на slave
#--host=192.168.1.7 ip master сервера
#--wal Включает в резервную копию необходимые сегменты WAL. При этом в подкаталог pg_wal архива базового каталога будут включены все файлы с начала до конца копирования.
#--progress Запрашивает информацию, необходимую для отслеживания прогресса операции
#--max_rate Ограничивает (сдерживает) максимальный объём данных, передаваемый от сервера клиенту за единицу времени.
# -R означает, что сервер создаст пустой файл standby.signal, наличие этого файла означает, что этот сервер — реплика.
#Проверка репликации на master
select * from pg_stat_replication;
sudo -u postgres psql -c "\x" -c "select * from pg_stat_replication;"
Expanded display is on.
-[ RECORD 1 ]----+------------------------------
pid | 422553
usesysid | 27404
usename | repluser
application_name | walreceiver
client_addr | 192.168.1.8
client_hostname |
client_port | 58154
backend_start | 2024-03-10 11:07:24.912558+03
backend_xmin |
state | streaming
sent_lsn | 0/A000CD8
write_lsn | 0/A000CD8
flush_lsn | 0/A000CD8
replay_lsn | 0/A000CD8
write_lag |
flush_lag |
replay_lag |
sync_priority | 0
sync_state | async
reply_time | 2024-03-10 11:09:18.174022+03
#Проверка репликации на slave
=# select * from pg_stat_wal_receiver;
-[ RECORD 1 ]---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid | 11637
status | streaming
receive_start_lsn | 0/8000000
receive_start_tli | 1
written_lsn | 0/8000148
flushed_lsn | 0/8000000
received_tli | 1
last_msg_send_time | 2024-02-23 22:43:18.207867+03
last_msg_receipt_time | 2024-02-23 22:43:18.209177+03
latest_end_lsn | 0/8000148
latest_end_time | 2024-02-23 22:34:47.752813+03
slot_name |
sender_host | 192.168.1.7
sender_port | 5432
conninfo | user=repluser password=******** channel_binding=prefer dbname=replication host=192.168.1.7 port=5432 fallback_application_name=walreceiver sslmode=prefer sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres target_session_attrs=any
#Проверим репликацию данных на вторичный сервер
#Попробуем создать тестовую базу данных:
CREATE DATABASE testbase ENCODING='UTF8';
#Проверим, что база данных есть на slave
sudo -u postgres psql
\l
#При попытке создать таблицу на реплике, получим ошибку, так как данный сервер настроен только репликацию
testdb=# CREATE TABLE test_table (id INT, name TEXT);
ERROR: cannot execute CREATE TABLE in a read-only transaction
Использование реплики в качестве мастера
В случае выхода из строя основного сервера, можно использоваться slave в качестве основого сервера
Для этого выключаем сервер master
И выполняем следующую команду:
sudo -u postgres pg_ctl promote -D /var/lib/postgresql/data
waiting for server to promote.... done
server promoted
#После выполнения команды сервер slave должен перейти в режим записи
testdb=# CREATE TABLE test_table1 (id INT, name TEXT);
CREATE TABLE
Для переключения приложений на новый сервер может использоваться балансировщик нагрузки
Источники
Здесь пока нет комментариев