Как исправить приставку PostgreSQL 9.3, которая не может справиться с мастером?
У нас есть конфигурация репликации master-slave, как показано ниже.
На главном устройстве:
postgresql.conf
имеет репликацию, сконфигурированную следующим образом (строка комментария выведена для краткости):
max_wal_senders = 1
wal_keep_segments = 8
В подчиненном устройстве:
Тот же postgresql.conf
как на главном. recovery.conf
выглядит следующим образом:
standby_mode = 'on'
primary_conninfo = 'host=master1 port=5432 user=replication password=replication'
trigger_file = '/tmp/postgresql.trigger.5432'
Когда это было первоначально установлено, мы выполнили несколько простых тестов и подтвердили, что репликация работает. Однако, когда мы выполнили начальную загрузку данных, только некоторые данные сделали ее ведомому.
Теперь ведомый журнал заполняется сообщениями, которые выглядят следующим образом:
< 2015-01-23 23:59:47.241 EST >LOG: started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:47.241 EST >FATAL: could not receive data from WAL stream: ERROR: requested WAL segment 000000010000000F00000052 has already been removed
< 2015-01-23 23:59:52.259 EST >LOG: started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:52.260 EST >FATAL: could not receive data from WAL stream: ERROR: requested WAL segment 000000010000000F00000052 has already been removed
< 2015-01-23 23:59:57.270 EST >LOG: started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:57.270 EST >FATAL: could not receive data from WAL stream: ERROR: requested WAL segment 000000010000000F00000052 has already been removed
После некоторого анализа и помощи на IRP-канале #postgresql я пришел к выводу, что подчиненный не может идти в ногу с мастером. Мое предложенное решение выглядит следующим образом.
На главном устройстве:
- Установить
max_wal_senders=5
- Установите
wal_keep_segments=4000
. Да, я знаю, что это очень высоко, но я бы хотел следить за ситуацией и видеть, что происходит. У меня есть место на хозяине.
В подчиненном устройстве:
- Сохраните файлы конфигурации в каталоге данных (т.е.
pg_hba.conf pg_ident.conf postgresql.conf recovery.conf
)
- Очистите каталог данных (
rm -rf /var/lib/pgsql/9.3/data/*
). Это, по-видимому, требуется pg_basebackup
.
- Выполните следующую команду:
pg_basebackup -h master -D /var/lib/pgsql/9.3/data --username=replication --password
Я что-то пропустил? Есть ли лучший способ обновить ведомый без необходимости перезагрузки всех данных?
Любая помощь очень ценится.
Ответы
Ответ 1
Два важных варианта работы с WAL для потоковая репликация:
-
wal_keep_segments
должен быть установлен достаточно высоким, чтобы позволить подчиненному устройству догнать его после разумного запаздывания (например, высокий уровень обновления, подчиненный в автономном режиме и т.д.).
-
archive_mode
позволяет архивировать WAL, которое может использоваться для восстановления файлов старше wal_keep_segments
. Для ведомых серверов просто нужен метод для извлечения сегментов WAL. NFS - это самый простой способ, но все, что угодно: от scp до http до лент будет работать до тех пор, пока оно может быть написано сценарием.
# on master
archive_mode = on
archive_command = 'cp %p /path_to/archive/%f'
# on slave
restore_command = 'cp /path_to/archive/%f "%p"'
Когда ведомое устройство не может вытащить сегмент WAL непосредственно из ведущего устройства, оно попытается использовать restore_command
для его загрузки. Вы можете настроить ведомое устройство для автоматического удаления сегментов с помощью параметра archive_cleanup_command
.
Если подчиненное устройство переходит в ситуацию, когда следующий сегмент WAL, который ему нужен, отсутствует как у ведущего, так и у архива, не будет никакого способа последовательно восстанавливать базу данных. Единственный разумный вариант - очистить сервер и начать с нового pg_basebackup
.
Ответ 2
Как сказал Бен Гримм в комментариях, речь идет о том, чтобы установить сегменты на максимально возможное значение, чтобы позволить подчиненному устройству догнать.