Потоковая репликация PostgreSQL

PostgreSQLBeginner
Практиковаться сейчас

Введение

В этой лаборатории вы научитесь настраивать потоковую репликацию PostgreSQL. Эта мощная функция позволяет поддерживать актуальную копию вашей основной базы данных только для чтения на вторичном сервере, известном как реплика. Реплика непрерывно получает и применяет изменения данных из основного сервера, что делает ее полезной для обеспечения высокой доступности, балансировки нагрузки при чтении запросов и резервного копирования.

Вы пройдете весь процесс, начиная с настройки основного сервера для разрешения репликации. Затем вы создадите сервер-реплику, сделав базовую резервную копию. Наконец, вы запустите реплику, протестируете поток данных между двумя серверами и увидите, как реплика остается синхронизированной с основным сервером.

Настройка основного сервера для репликации

На этом первом этапе вы настроите основной сервер PostgreSQL для подготовки к репликации. Это включает в себя изменение его конфигурационных файлов для разрешения сетевых подключений, включение необходимого уровня Write-Ahead Log (WAL) и создание специального пользователя для репликации.

1. Изменение конфигурационного файла PostgreSQL

Для подготовки к репликации вам необходимо изменить основной конфигурационный файл postgresql.conf. Редактирование этого большого файла вручную с помощью текстового редактора, такого как nano, может быть сложным и подверженным ошибкам из-за большого количества опций. Более эффективным и надежным методом является использование инструментов командной строки для просмотра и обновления конкретных настроек, которые вам нужно изменить. Это позволяет избежать прокрутки сотен строк и предотвращает случайные ошибки.

Сначала давайте проверим текущие значения настроек, которые нам нужно изменить: listen_addresses, wal_level и max_wal_senders.

CONF_FILE="/etc/postgresql/14/main/postgresql.conf"
echo "--- Current Settings ---"
sudo grep -E "^#?\s*(listen_addresses|wal_level|max_wal_senders)" $CONF_FILE

Скорее всего, вы увидите эти строки закомментированными с помощью #.

Теперь давайте автоматически обновим эти настройки. Следующие команды создадут резервную копию конфигурационного файла, а затем обновят каждый необходимый параметр.

CONF_FILE="/etc/postgresql/14/main/postgresql.conf"
## Создаем резервную копию перед внесением изменений
sudo cp $CONF_FILE ${CONF_FILE}.bak.$(date +%s)

## Устанавливаем listen_addresses в '*' для разрешения подключений с любого IP-адреса
sudo sed -i -E "s/^[#\s]*listen_addresses\s*=.*/listen_addresses = '*'/" "$CONF_FILE"

## Устанавливаем wal_level в 'replica' для включения журналов репликации
sudo sed -i -E "s/^[#\s]*wal_level\s*=.*/wal_level = replica/" "$CONF_FILE"

## Устанавливаем максимальное количество одновременных подключений для репликации
sudo sed -i -E "s/^[#\s]*max_wal_senders\s*=.*/max_wal_senders = 10/" "$CONF_FILE"

Наконец, давайте проверим, были ли изменения применены правильно. Следующая команда отобразит новые значения, отфильтровывая любые закомментированные строки.

echo "--- Verified Settings ---"
sudo grep -E "^(listen_addresses|wal_level|max_wal_senders)" $CONF_FILE

Вывод должен показать обновленную, активную конфигурацию:

listen_addresses = '*'
wal_level = replica
max_wal_senders = 10

С подтвержденными этими настройками сервер правильно сконфигурирован для следующих шагов.

2. Создание выделенного пользователя для репликации

Рекомендуется использовать выделенного пользователя для репликации вместо суперпользователя. Давайте создадим роль с именем replicator.

Подключитесь к PostgreSQL с помощью клиентской программы командной строки psql:

sudo -u postgres psql

Теперь выполните следующую команду SQL для создания пользователя с правами репликации и паролем:

CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'replicapass';

Вы должны увидеть вывод CREATE ROLE. Теперь выйдите из клиента psql:

\q

3. Разрешение подключения для репликации

Далее вам нужно настроить сервер, чтобы разрешить пользователю replicator подключаться с сервера реплики. Вы сделаете это, отредактировав файл pg_hba.conf.

Откройте файл с помощью nano:

sudo nano /etc/postgresql/14/main/pg_hba.conf

Добавьте следующую строку в конец файла. Это правило указывает, что пользователю replicator разрешено подключаться к псевдобазе данных replication с любого IP-адреса (0.0.0.0/0). Для этой лаборатории мы используем 127.0.0.1/32, поскольку оба сервера находятся на одной машине.

host    replication     replicator      127.0.0.1/32            md5

Нажмите Ctrl+X, затем Y и Enter, чтобы сохранить и выйти.

4. Перезапуск основного сервера

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

sudo service postgresql restart

Основной сервер теперь готов принимать подключения для репликации.

Создание реплики из базовой резервной копии

После настройки основного сервера следующим шагом является создание реплики. Стандартный способ сделать это — взять "базовую резервную копию" (base backup) основного сервера. Это создает идентичную копию каталога данных основного сервера, которая послужит отправной точкой для реплики.

1. Создание каталога данных для реплики

Сначала создайте новый каталог, где будут храниться данные реплики. Лучшей практикой является создание этого каталога в системном расположении, а не в домашнем каталоге пользователя, чтобы избежать проблем с разрешениями. Мы создадим его от имени пользователя postgres в стандартном каталоге PostgreSQL.

sudo -u postgres mkdir -p /var/lib/postgresql/14/replica

2. Создание базовой резервной копии

Теперь используйте утилиту pg_basebackup для копирования данных с основного сервера. Эта команда подключится к основному серверу от имени пользователя replicator и передаст данные в новый каталог реплики. Поскольку вы создали каталог от имени пользователя postgres, проблем с разрешениями не возникнет.

Выполните следующую команду. Вам будет предложено ввести пароль для пользователя replicator, который равен replicapass.

sudo -u postgres pg_basebackup -h localhost -p 5432 -U replicator -D /var/lib/postgresql/14/replica -P -v -R

Разберем эту команду:

  • sudo -u postgres: Выполняет команду от имени системного пользователя postgres, который имеет необходимые разрешения.
  • pg_basebackup: Утилита для создания базовых резервных копий.
  • -h localhost -p 5432: Указывает хост и порт основного сервера.
  • -U replicator: Имя пользователя для подключения.
  • -D /var/lib/postgresql/14/replica: Целевой каталог для резервной копии.
  • -P: Отображает отчет о ходе выполнения.
  • -v: Включает подробный режим (verbose mode).
  • -R: Это очень полезная опция. Она создает файл standby.signal и добавляет параметры подключения в файл postgresql.auto.conf в целевом каталоге, что автоматически настраивает новый каталог данных как реплику.

3. Копирование конфигурационных файлов

Базовая резервная копия копирует основные файлы данных, но во многих системах на основе Debian (как эта среда Ubuntu) конфигурационные файлы (pg_hba.conf и pg_ident.conf) хранятся отдельно в /etc/postgresql/ и не включаются в резервную копию. Вам необходимо вручную скопировать их в каталог данных реплики. После копирования вы также должны убедиться, что они принадлежат пользователю postgres, чтобы процесс сервера мог их прочитать.

sudo cp /etc/postgresql/14/main/pg_hba.conf /var/lib/postgresql/14/replica/
sudo cp /etc/postgresql/14/main/pg_ident.conf /var/lib/postgresql/14/replica/
sudo chown postgres:postgres /var/lib/postgresql/14/replica/pg_hba.conf
sudo chown postgres:postgres /var/lib/postgresql/14/replica/pg_ident.conf

После размещения файлов данных и конфигурации каталог реплики готов к финальным шагам настройки.

Настройка и запуск сервера реплики

Базовая резервная копия подготовила каталог данных реплики. Однако, поскольку вы запускаете основной и реплицирующий серверы на одной машине, они не могут использовать один и тот же сетевой порт (по умолчанию 5432). На этом шаге вы настроите реплику для использования другого порта, а затем запустите ее.

1. Настройка порта реплики

Отредактируйте файл postgresql.conf внутри каталога данных реплики, чтобы изменить порт прослушивания. Обратите внимание, что вам нужен sudo, потому что этот файл теперь принадлежит пользователю postgres.

sudo nano /var/lib/postgresql/14/replica/postgresql.conf

Добавьте следующую строку в конец файла, чтобы установить порт на 5433:

port = 5433

Нажмите Ctrl+X, затем Y и Enter, чтобы сохранить и выйти.

2. Установка разрешений для каталога данных

В целях безопасности PostgreSQL требует, чтобы его каталог данных не был доступен другим пользователям. Вы должны установить для него разрешения 700, которые предоставляют права на чтение, запись и выполнение только владельцу (postgres).

sudo chmod 0700 /var/lib/postgresql/14/replica

3. Запуск сервера реплики

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

Выполните следующую команду для запуска реплики. Вы должны использовать полный путь к pg_ctl, потому что команда sudo иначе может не знать, где его найти. Мы также укажем файл журнала в /tmp, чтобы было легко проверить состояние сервера.

sudo -u postgres /usr/lib/postgresql/14/bin/pg_ctl -D /var/lib/postgresql/14/replica -l /tmp/replica.log start
  • pg_ctl: Утилита управления сервером.
  • -D /var/lib/postgresql/14/replica: Указывает каталог данных для этого экземпляра сервера.
  • -l /tmp/replica.log: Указывает файл журнала.
  • start: Действие, которое нужно выполнить.

Вы должны увидеть сообщение:

waiting for server to start.... done
server started

4. Проверка файла журнала реплики

Чтобы убедиться, что реплика запустилась корректно и подключилась к основному серверу, просмотрите ее файл журнала с помощью sudo, так как он принадлежит пользователю postgres:

sudo cat /tmp/replica.log

Ищите строки, указывающие на то, что система базы данных готова принимать соединения только для чтения (read-only connections) и что она начала потоковую передачу WAL с основного сервера. Вы должны увидеть что-то похожее на это:

...
LOG:  database system is ready to accept read-only connections
LOG:  started streaming WAL from primary at 0/4000000 on timeline 1
...

Это подтверждает, что ваш сервер реплики запущен, работает и успешно подключен к основному серверу.

Тестирование репликации

Теперь, когда оба сервера запущены, пришло время проверить, работает ли репликация должным образом. Вы создадите таблицу на основном сервере и убедитесь, что она появилась на реплике. Вы также подтвердите, что реплика работает в режиме только для чтения (read-only).

1. Проверка статуса репликации на основном сервере

Сначала подключитесь к основному серверу (на порту 5432) и проверьте представление pg_stat_replication. Это представление предоставляет информацию для мониторинга подключенных реплик.

sudo -u postgres psql -p 5432

Выполните следующий запрос:

SELECT client_addr, state, sync_state FROM pg_stat_replication;

В выводе должно быть указано, что ваша реплика подключена, ее состояние — streaming, а sync_stateasync или sync.

 client_addr |   state   | sync_state
-------------+-----------+------------
 127.0.0.1   | streaming | async
(1 row)

2. Создание данных на основном сервере

Оставаясь подключенным к основному серверу, создайте новую таблицу и вставьте в нее некоторые данные:

CREATE TABLE replication_test (id INT, message TEXT);
INSERT INTO replication_test VALUES (1, 'Hello from primary!');

Теперь выполните запрос к таблице, чтобы убедиться, что данные присутствуют:

SELECT * FROM replication_test;

Вы должны увидеть строку, которую только что вставили. Выйдите из оболочки psql основного сервера:

\q

3. Проверка данных на реплике

Откройте новый терминал или используйте существующий для подключения к серверу реплики на порту 5433. Вам потребуется ввести пароль для пользователя postgres, который равен labex.

psql -h localhost -p 5433 -U postgres -d postgres

Теперь выполните запрос к таблице replication_test на реплике:

SELECT * FROM replication_test;

Вы должны увидеть те же самые данные, которые вы создали на основном сервере. Это подтверждает, что потоковая репликация работает!

 id |      message
----+---------------------
  1 | Hello from primary!
(1 row)

4. Тестирование режима только для чтения на реплике

Попробуйте вставить данные в таблицу на реплике:

INSERT INTO replication_test VALUES (2, 'Hello from replica?');

Команда завершится ошибкой, поскольку сервер реплики по умолчанию находится в режиме только для чтения (read-only).

ERROR:  cannot execute INSERT in a read-only transaction

Это ожидаемое поведение и ключевая характеристика потоковой реплики. Выйдите из оболочки psql реплики:

\q

Очистка окружения

На заключительном этапе вы остановите серверы и удалите файлы и каталоги, созданные во время лабораторной работы, чтобы вернуть окружение в исходное состояние.

1. Остановка сервера реплики

Сначала остановите сервер реплики с помощью pg_ctl. Не забудьте использовать полный путь к исполняемому файлу.

sudo -u postgres /usr/lib/postgresql/14/bin/pg_ctl -D /var/lib/postgresql/14/replica stop

Вы увидите подтверждающее сообщение о том, что сервер остановлен.

waiting for server to shut down.... done
server stopped

2. Остановка основного сервера

Затем остановите основной сервер с помощью команды service.

sudo service postgresql stop

3. Удаление данных и журналов реплики

Теперь, когда серверы остановлены, вы можете безопасно удалить каталог данных реплики и созданный вами файл журнала. Обратите внимание, что требуется sudo, поскольку эти файлы принадлежат пользователю postgres.

sudo rm -rf /var/lib/postgresql/14/replica /tmp/replica.log

Это завершает процесс очистки. Вы успешно настроили, протестировали и разобрали окружение потоковой репликации PostgreSQL.

Резюме

В этой лабораторной работе вы успешно настроили потоковую репликацию PostgreSQL с нуля. Вы узнали, как подготовить основной сервер, изменив postgresql.conf и pg_hba.conf, а также создав выделенного пользователя для репликации. Затем вы использовали pg_basebackup для создания реплики и настроили ее для работы на отдельном порту.

Протестировав настройку, вы убедились, что данные, записываемые на основной сервер, автоматически реплицируются на вторичный сервер практически в режиме реального времени. Вы также подтвердили, что сервер реплики работает в режиме только для чтения (read-only), что является фундаментальным аспектом его конструкции. Эти навыки необходимы для управления надежными и масштабируемыми развертываниями PostgreSQL.