Как исправить приставку 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

Как сказал Бен Гримм в комментариях, речь идет о том, чтобы установить сегменты на максимально возможное значение, чтобы позволить подчиненному устройству догнать.