Трансляция журналов на резервные серверы
Эта страница переведена при помощи нейросети GigaChat.
Непрерывное архивирование может использоваться для создания конфигурации кластера с высоким уровнем доступности (HA) с одним или несколькими серверами резервных копий, готовыми взять на себя операции в случае сбоя основного сервера. Эта возможность широко известна как горячий резерв или трансляция журналов.
Основной и резервный сервер работают вместе для обеспечения этой возможности, хотя серверы связаны только слабо. Основной сервер работает в режиме непрерывного архивирования, тогда как каждый резервный сервер работает в режиме непрерывного восстановления, читая файлы WAL с основного сервера. Не требуется вносить никаких изменений в таблицы баз данных для включения этой функции, поэтому она предлагает низкую административную нагрузку по сравнению с некоторыми другими решениями репликации. Эта конфигурация также имеет относительно низкое влияние на производительность основного сервера.
Прямое перемещение записей WAL с одного сервера баз данных на другой обычно описывается как логическая передача. PostgreSQL реализует передачу файлов журнала путем передачи записей WAL по одному файлу (сегмент WAL) за раз. Файлы WAL (16 МБ) могут быть легко и дешево переданы на любое расстояние, будь то соседняя система, другая система на том же сайте или другая система на противоположной стороне земного шара. Полоса пропускания, необходимая для этой техники, варьируется в зависимости от частоты транзакций основного сервера. Логическая передача на основе записей более детализирована и постепенно передает изменения WAL через сетевое соединение (см. раздел «Потоковая репликация»).
Следует отметить, что передача журналов является асинхронной, т.е. записи WAL отправляются после фиксации транзакции. В результате существует окно для потери данных в случае катастрофического сбоя основного сервера; транзакции, которые еще не были отправлены, будут потеряны. Размер окна потери данных при передаче файлов журнала может быть ограничен использованием параметра archive_timeout
, который можно установить до нескольких секунд. Однако такая низкая настройка существенно увеличит необходимую полосу пропускания для передачи файлов. Потоковая репликация (см. раздел «Потоковая репликация») позволяет значительно меньшее окно повреждения данных.
Производительность восстановления достаточно хороша, чтобы резервный сервер обычно был всего лишь мгновениями от полной доступности сразу после его активации. В результате это называется конфигурацией горячего резерва, которая обеспечивает высокую доступность. Восстановление сервера из архивированной базовой резервной копии и роллфорварда займет гораздо больше времени, поэтому эта техника предлагает решение только для аварийного восстановления, а не высокой доступности. Резервный сервер также может использоваться для выполнения запросов только для чтения, в этом случае он называется горячим резервным сервером. См. раздел «Горячий резерв» для получения дополнительной информации.
Планирование
Обычно целесообразно создавать основной и резервный серверы таким образом, чтобы они были максимально похожи друг на друга, по крайней мере с точки зрения сервера баз данных. В частности, пути имен, связанные с табличными пространствами, будут переданы без изменений, поэтому как первичный, так и резервный сервер должны иметь одинаковые точки монтирования для табличных пространств, если используется эта функция. Помните, что если выполняется команда CREATE TABLESPACE, то любая новая точка монтирования, необходимая для нее, должна быть создана на основном и всех резервных серверах до выполнения команды. Оборудование не обязательно должно быть точно таким же, но опыт показывает, что поддерживать две идентичные системы легче, чем поддерживать две различные системы в течение всего срока службы приложения и системы. В любом случае архитектура оборудования должна быть одинаковой – переход, скажем, от 32-битной к 64-битной системе работать не будет.
Как правило, передача журналов между серверами, работающими под управлением разных основных версий PostgreSQL, невозможна. Политика Глобальной группы разработки PostgreSQL заключается в том, чтобы не вносить изменения в форматы дисков при обновлении второстепенных выпусков, поэтому весьма вероятно, что работа с разными уровнями второстепенного выпуска на первичном и резервном серверах будет успешной. Однако официальной поддержки этого нет, и рекомендуется поддерживать первичный и резервный серверы на одном уровне выпуска насколько это возможно. При обновлении до новой второстепенной версии наиболее безопасной политикой является обновление резервных серверов в первую очередь -- новая второстепенная версия с большей вероятностью сможет читать файлы WAL из предыдущей второстепенной версии, чем наоборот.
Работа резервного сервера
Сервер переходит в режим ожидания, если при запуске сервера существует файл standby.signal
в каталоге данных.
В режиме ожидания сервер непрерывно применяет WAL, полученный от основного сервера. Сервер-резервная копия может считывать WAL из архива WAL (см. restore_command) или непосредственно с основного через TCP-соединение (потоковая репликация). Резервный сервер также попытается восстановить любой WAL, найденный в каталоге pg_wal
кластера резервных копий. Обычно это происходит после перезагрузки сервера, когда резервная копия снова воспроизводит WAL, который был передан с основного перед перезапуском, но также можно вручную скопировать файлы в pg_wal
в любое время для их воспроизведения.
При запуске резервный сервер начинает с восстановления всех доступных WAL в архивном расположении, вызывая restore_command
. Как только он достигает конца доступного там WAL и restore_command
терпит неудачу, он пытается восстановить любой WAL, доступный в каталоге pg_wal
. Если это не удается, и настроена потоковая репликация, резервный сервер пытается подключиться к основному серверу и начать потоковую передачу WAL с последней найденной действительной записи в архиве или pg_wal
. Если это не удается или потоковая репликация не настроена, или если соединение позже отключается, резервный сервер возвращается к шагу 1 и снова пытается восстановить файл из архива. Этот цикл повторных попыток из архива, pg_wal
, и через потоковую репликацию продолжается до тех пор, пока сервер не будет остановлен или отказоустойчивость не будет вызвана файлом триггера.
Режим ожидания завершается и сервер переключается в нормальный режим работы при запуске pg_ctl promote
, вызове pg_promote()
. Перед отказоустойчивым переключением будет восстановлен любой WAL, немедленно доступный в архиве или в pg_wal
, но не предпринимается попыток подключения к основному устройству.
Подготовка основного сервера для работы с резервными серверами
Настройте непрерывное архивирование на основном сервере в архивный каталог, доступный с резервного сервера, как описано в разделе «Непрерывное архивирование и восстановление до заданной точки во времени (PITR)». Расположение архива должно быть доступно с резервного сервера даже при отключении основного сервера, т.е. оно должно находиться на самом резервном сервере или другом доверенном сервере, а не на основном сервере.
Если нужно использовать потоковую репликацию, настройте аутентификацию на основном сервере для разрешения соединений репликации от резервного сервера(ов), то есть создайте роль и предоставьте соответствующую запись или записи в pg_hba.conf
с полем базы данных, установленным на replication
. Также убедитесь, что max_wal_senders
установлен на достаточно высокое значение в файле конфигурации основного сервера. Если будут использоваться слоты репликации, убедитесь, что max_replication_slots
также установлен достаточно высоко.
Создайте резервную копию базы данных, как описано в разделе «Создание резервной копии базы данных», чтобы инициализировать сервер-резервную копию.
Настройка резервного сервера
Чтобы настроить резервный сервер, восстановите базовое резервное копирование, выполненное с основного сервера (см. раздел «Восстановление с использованием непрерывного архивного резервирования»). Создайте файл standby.signal
в каталоге кластерных данных резервного сервера. Установите restore_command на простую команду для копирования файлов из архива WAL. Если планируется иметь несколько резервных серверов для обеспечения высокой доступности, убедитесь, что recovery_target_timeline
установлен на latest
(по умолчанию), чтобы резервный сервер следовал изменению временной шкалы, которое происходит при отказе от другого резервного сервера.
Команда restore_command должна немедленно завершиться, если файл не существует. Сервер повторит эту команду снова при необходимости.
Если требуется использовать потоковую репликацию, заполните primary_conninfo строкой подключения libpq, включая имя хоста (или IP-адрес) и любые дополнительные сведения, необходимые для подключения к основному серверу. Если основной сервер требует пароля для аутентификации, пароль также необходимо указать в primary_conninfo.
Если настраивается резервный сервер для обеспечения высокой доступности, настройте архивирование WAL, соединения и аутентификацию так же, как на основном сервере, потому что после отказа резервный сервер будет работать как основной сервер.
Если используется архив WAL, его размер можно минимизировать с помощью параметра archive_cleanup_command, чтобы удалить файлы, которые больше не требуются резервному серверу. Утилита pg_archivecleanup специально разработана для использования с archive_cleanup_command
в типичных конфигурациях с одним резервным сервером. См. pg_archivecleanup. Однако обратите внимание, что если используется архив для целей резервного копирования, то необходимо сохранить файлы, необходимые для восстановления хотя бы последней базовой копии, даже если они больше не нужны резервному серверу.
Простой пример конфигурации:
primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass options=''-c wal_sender_timeout=5000'''
restore_command = 'cp /path/to/archive/%f %p'
archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'
Можно иметь любое количество резервных серверов, но если используется потоковая репликация, убедитесь, что max_wal_senders
установлен достаточно высоко на основном сервере, чтобы все они могли быть подключены одновременно.
Потоковая репликация
Потоковая репликация позволяет резервному серверу оставаться более актуальным, чем это возможно с помощью передачи файлов журнала. Резервный сервер подключается к основному, который передает записи WAL на резервный сервер по мере их генерации, не дожидаясь заполнения файла WAL.
Потоковая репликация по умолчанию асинхронна (см. раздел «Синхронная репликация»), при которой существует небольшая задержка между фиксацией транзакции в основной базе и отображением изменений во вспомогательной базе. Однако эта задержка значительно меньше, чем при передаче файлов журнала, обычно менее одной секунды, если предполагается, что резервная копия достаточно мощная для обработки нагрузки. При потоковой репликации не требуется archive_timeout
, чтобы уменьшить окно потери данных.
Если используете потоковую репликацию без непрерывной архивации на основе файлов, сервер может повторно использовать старые сегменты WAL до того, как резервная копия получит их. Если это произойдет, резервную копию необходимо будет инициализировать заново из новой базовой копии. Можно избежать этого, установив wal_keep_size
на значение, достаточное для обеспечения того, чтобы сегменты WAL не были переработаны слишком рано, или настроив слот репликации для резервного сервера. Если настраивается архив WAL, доступный с резервного сервера, эти решения не требуются, поскольку резервная копия всегда может использовать архив для восстановления, если она сохраняет достаточно сегментов.
Для использования потоковой репликации настройте сервер резервного копирования на основе файлового журнала, как описано в разделе «Трансляция журналов на резервные серверы». Шаг, который превращает файловый журнал резервного копирования в потоковую репликацию резервного копирования, заключается в установке параметра primary_conninfo
для указания на основной сервер. Установите параметры listen_addresses и аутентификации (см. pg_hba.conf
) на основном сервере таким образом, чтобы сервер резервной копии мог подключиться к псевдобазе данных replication
на основном сервере (см. раздел «Аутентификация»).
На системах, поддерживающих опцию сокета keepalive, установка параметров tcp_keepalives_idle, tcp_keepalives_interval и tcp_keepalives_count помогает основному серверу своевременно заметить разорванное соединение.
Установите максимальное количество одновременных соединений от серверов резервного копирования (подробности см. в разделе max_wal_senders).
Когда резервный сервер запущен и параметр primary_conninfo
установлен правильно, резервный сервер подключится к основному после воспроизведения всех доступных файлов WAL в архиве. Если подключение установлено успешно, то увидите процесс walreceiver
на резервном сервере и соответствующий процесс walsender
на основном сервере.
Аутентификация
Очень важно настроить привилегии доступа для репликации таким образом, чтобы только доверенные пользователи могли читать поток WAL, потому что из него легко извлечь конфиденциальную информацию. Серверы-резервные копии должны аутентифицироваться на основном сервере как учетная запись с привилегией REPLICATION
или суперпользователь. Рекомендуется создать специальную учетную запись пользователя с привилегиями REPLICATION
и LOGIN
для репликации. Хотя привилегия REPLICATION
предоставляет очень высокие разрешения, она не позволяет пользователю изменять какие-либо данные в основной системе, что делает привилегию SUPERUSER
.
Аутентификация клиентского приложения для репликации контролируется записью pg_hba.conf
, указывающей replication
в поле database
. Например, если резервный сервер работает на хосте IP 192.168.1.100
и имя учетной записи для репликации - foo
, администратор может добавить следующую строку в файл pg_hba.conf
на главном компьютере:
# Allow the user "foo" from host 192.168.1.100 to connect to the primary
# as a replication standby if the user's password is correctly supplied.
#
# TYPE DATABASE USER ADDRESS METHOD
host replication foo 192.168.1.100/32 md5
Имя хоста и номер порта основного компьютера, имя пользователя подключения и пароль указаны в primary_conninfo. Пароль также можно установить в файле ~/.pgpass
на резервном сервере (укажите replication
в поле database
). Например, если основная версия работает на хосте IP 192.168.1.50
, порту 5432
, имя учетной записи для репликации - foo
, а пароль - foopass
, администратор может добавить следующую строку в файл postgresql.conf
на резервном сервере:
# The standby connects to the primary that is running on host 192.168.1.50
# and port 5432 as the user "foo" whose password is "foopass".
primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
Мониторинг
Важным показателем здоровья потоковой репликации является объем записей WAL, сгенерированных в основной системе, но еще не примененных в резервной копии. Можно рассчитать эту задержку, сравнив текущее местоположение записи WAL в основной системе с последним местоположением WAL, полученным резервной копией. Эти места можно получить, используя pg_current_wal_lsn
на основном и pg_last_wal_receive_lsn
на резервном соответственно (см. таблицу «Функции управления резервным копированием» и таблица «Функции информации о восстановлении» для получения подробной информации). Последнее место приема WAL в резервной копии также отображается в статусе процесса приемника WAL, который отображается с помощью команды ps
(см. раздел «Стандартные инструменты Unix» для получения дополнительной информации).
Можно получить список процессов отправителя WAL через представление pg_stat_replication
. Большие различия между pg_current_wal_lsn
и полем sent_lsn
представления могут указывать на то, что основная серверная система испытывает большую нагрузку, тогда как различия между sent_lsn
и pg_last_wal_receive_lsn
на резервной копии могут указывать на задержку сети или на то, что резервная копия испытывает большую нагрузку.
На горячем резерве статус процесса приемника WAL можно получить через представление pg_stat_wal_receiver
. Большая разница между pg_last_wal_replay_lsn
и представлением flushed_lsn
указывает на то, что WAL принимается быстрее, чем может быть воспроизведено.
Слоты репликации
Слоты репликации обеспечивают автоматизированный способ обеспечения того, чтобы ведущий сервер не удалял сегменты WAL до тех пор, пока они не будут получены всеми резервными копиями, и чтобы ведущий сервер не удалял строки, которые могли бы вызвать конфликт при восстановлении даже тогда, когда резервная копия отключена.
Вместо использования слотов репликации можно предотвратить удаление старых сегментов WAL с помощью wal_keep_size или путем хранения сегментов в архиве с использованием archive_command или archive_library. Слоты репликации могут сохранять так много сегментов WAL, что они заполняют пространство, выделенное для pg_wal
; max_slot_wal_keep_size ограничивает размер файлов WAL, сохраняемых слотами репликации.
Аналогично, hot_standby_feedback обеспечивает защиту от удаления соответствующих строк вакуумом, но не обеспечивает защиты во время любого периода времени, когда резервная копия не подключена. Слоты репликации преодолевают эти недостатки.
Учтите, что слоты репликации могут привести к накоплению такого большого числа сегментов WAL, что они заполнят пространство, выделенное для хранения `pg_wal
`. Параметр `max_slot_wal_keep_size` позволяет ограничить размер файлов WAL, сохраняемых слотами репликации.
Запрос и манипулирование слотами репликации
Каждый слот репликации имеет имя, которое может содержать строчные буквы, цифры и символ подчеркивания.
Существующие слоты репликации и их состояние можно увидеть в представлении pg_replication_slots
.
Слоты могут быть созданы и удалены либо через протокол потоковой репликации (см. Раздел «Протокол репликации»), либо с помощью функций SQL (см. раздел «Функции управления репликацией»).
Пример конфигурации
Создать слот репликации можно следующим образом:
postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot');
slot_name | lsn
-------------+-----
node_a_slot |
postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
slot_name | slot_type | active
-------------+-----------+--------
node_a_slot | physical | f
(1 row)
Чтобы настроить резервную копию для использования этого слота, primary_slot_name
должен быть настроен на резервной копии. Пример:
primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
primary_slot_name = 'node_a_slot'
Каскадная репликация
Функция каскадной репликации позволяет серверу-резервному копировать соединения для репликации и передавать записи WAL другим резервным копиям, действуя как ретранслятор. Это можно использовать для уменьшения количества прямых подключений к основному серверу и минимизации межсайтовой нагрузки на полосу пропускания.
Резервный сервер, который одновременно является получателем и отправителем, называется каскадным резервом. Резервы, которые находятся ближе всего к первичному серверу, называются серверами верхнего уровня, а те резервные серверы, которые расположены дальше, являются нижестоящими серверами. Каскадная репликация не накладывает ограничений на количество или расположение нижестоящих серверов, хотя каждый резервный сервер подключается только к одному вышестоящему серверу, который в конечном итоге связан с одним основным сервером.
Каскадный резерв передает не только записи WAL, полученные от основного сервера, но и восстановленные из архива. Таким образом, даже если соединение для репликации в каком-то верхнем соединении будет прервано, потоковая репликация продолжается вниз по течению до тех пор, пока доступны новые записи WAL.
Каскадная репликация в настоящее время является асинхронной. Параметры синхронной репликации (см. раздел 27.2.8) в данный момент не влияют на каскадную репликацию.
Обратная связь горячей замены распространяется вверх независимо от каскадного расположения.
Если резервный сервер выше по потоку повышается до нового основного сервера, нижестоящие серверы будут продолжать передавать данные с нового основного сервера, если параметр primary_conninfo установлен в значение 'application_name=standby' (по умолчанию).
Чтобы использовать каскадную репликацию, настройте каскадный резервный сервер таким образом, чтобы он мог принимать соединения для репликации (то есть установите max_wal_senders и hot_standby, а также настройте аутентификацию на основе хоста). Также потребуется установить primary_conninfo
в резервном сервере ниже по потоку так, чтобы он указывал на каскадный резервный сервер.
Синхронная репликация
Потоковая репликация в PostgreSQL по умолчанию асинхронна. Если основной сервер выходит из строя, некоторые транзакции, которые были подтверждены, могут не быть реплицированы на резервный сервер, что приводит к потере данных. Объем потерянных данных пропорционален задержке репликации на момент отказа.
Синхронная репликация предлагает возможность подтверждения того, что все изменения, внесенные транзакцией, были переданы одному или нескольким синхронным резервным серверам. Это расширяет стандартный уровень устойчивости, предлагаемый фиксацией транзакции. Этот уровень защиты соответствует второму уровню безопасности репликации из теории вычислительной техники, или групповой безопасности первого уровня (безопасности групповой и уровня 1), когда synchronous_commit
установлен на remote_write
.
При запросе синхронной репликации каждая фиксация записи транзакции будет ожидать до получения подтверждения о том, что фиксация была записана в журнал предварительной записи на диск как основного, так и резервного сервера. Единственная возможность потери данных заключается в том, если основной сервер и резервный сервер одновременно выходят из строя. Это может обеспечить гораздо более высокий уровень надежности, хотя только в том случае, если системный администратор осторожен с размещением и управлением двумя серверами. Ожидание подтверждения повышает уверенность пользователя в том, что изменения не будут потеряны в случае сбоя сервера, но это также неизбежно увеличивает время отклика для запрашиваемой транзакции. Минимальное время ожидания – это время прохождения туда и обратно между основным и резервным серверами.
Только для чтения транзакций и отмены транзакций нет необходимости ждать ответов от резервных серверов. Промежуточные подтверждения не ожидают ответа от резервных серверов, только фиксации верхнего уровня. Длительные действия, такие как загрузка данных или построение индексов, не ждут до самого последнего сообщения фиксации. Все действия двухфазной фиксации требуют ожиданий фиксации, включая подготовку и фиксацию.
Синхронный резервный экземпляр может быть физическим резервным экземпляром репликации или подписчиком логической репликации. Это также может быть любой другой потребитель физического или логического потока репликации WAL, который знает, как отправлять соответствующие сообщения обратной связи. Помимо встроенных физических и логических систем репликации, сюда входят специальные программы, такие как pg_receivewal
и pg_recvlogical
, а также некоторые сторонние системы репликации и специализированные программы. Проверьте соответствующую документацию для получения подробной информации о поддержке синхронной репликации.
Базовая настройка
После настройки потоковой репликации настройка синхронной репликации требует только одного дополнительного шага конфигурации: synchronous_standby_names должно быть установлено на непустое значение. synchronous_commit
также должен быть установлен на on
, но поскольку это значение по умолчанию, обычно не требуется никаких изменений. (См. Раздел «Журнал записи с опережением (WAL)» (Настройка) и раздел «Главный сервер».) Эта конфигурация приведет к тому, что каждый коммит будет ожидать подтверждения того, что резервный сервер записал запись фиксации в долговременное хранилище. synchronous_commit
может быть настроен отдельными пользователями, поэтому его можно настроить в файле конфигурации для конкретных пользователей или баз данных или динамически приложениями для управления гарантией долговечности на основе каждой транзакции.
После того, как запись фиксации была записана на диск на основном сервере, запись WAL отправляется на резервный сервер. Резервный сервер отправляет сообщения ответа каждый раз, когда новая порция данных WAL записывается на диск, если wal_receiver_status_interval
не установлен равным нулю на резервном сервере. В случае, если synchronous_commit
установлен на remote_apply
, резервный сервер отправляет сообщения ответа при воспроизведении записи фиксации, делая транзакцию видимой. Если резервный сервер выбран в качестве синхронного резервного сервера в соответствии с настройкой synchronous_standby_names
на основном сервере, ответы от этого резервного сервера будут учитываться вместе с ответами других синхронных резервных серверов для определения времени освобождения транзакций, ожидающих подтверждения получения записи фиксации. Эти параметры позволяют администратору указать, какие резервные серверы должны быть синхронными резервными серверами. Обратите внимание, что конфигурация синхронной репликации осуществляется главным образом на основном сервере. Названные резервные копии должны быть напрямую подключены к основному серверу; основной сервер ничего не знает о нижестоящих резервных серверах, использующих каскадную репликацию.
Установка synchronous_commit
на remote_write
приведет к тому, что каждая фиксация будет ожидать подтверждения того, что резервный сервер получил запись фиксации и вывел ее в свою собственную операционную систему, но не для того, чтобы данные были сброшены на диск резервного сервера. Эта настройка обеспечивает меньшую гарантию устойчивости, чем on
: резервный сервер может потерять данные в случае сбоя операционной системы, хотя и не PostgreSQL. Однако это полезная настройка на практике, поскольку она может уменьшить время отклика для транзакции. Потеря данных могла бы произойти только в том случае, если бы основной сервер и резервный сервер вышли из строя одновременно, а база данных основного сервера была повреждена.
Установка synchronous_commit
на remote_apply
приведет к тому, что каждая фиксация будет ждать до тех пор, пока текущие синхронные резервные копии не сообщат, что они воспроизвели транзакцию, сделав ее доступной для пользовательских запросов. В простых случаях это позволяет балансировать нагрузку с причинно-следственной согласованностью.
Пользователи перестанут ждать, если будет запрошен быстрый останов. Тем не менее, как и при использовании асинхронной репликации, сервер полностью не завершит работу до тех пор, пока все незавершенные записи WAL не будут переданы на подключенные в данный момент резервные серверы.
Несколько синхронных резервных копий
Синхронная репликация поддерживает одну или несколько синхронных серверов-резервных копий; транзакции будут ожидать до тех пор, пока все серверы-резервные копии, которые считаются синхронными, не подтвердят получение своих данных. Количество синхронных резервных копий, от которых транзакциям необходимо дождаться ответов, указано в synchronous_standby_names
. Этот параметр также указывает список имен резервных копий и метод (FIRST
и ANY
) выбора синхронных резервных копий из перечисленных.
Метод FIRST
определяет приоритетную синхронную репликацию и заставляет коммиты транзакций ждать до тех пор, пока их записи WAL не будут реплицированы на запрошенное количество синхронных резервных копий, выбранное на основе их приоритетов. Резервным копиям, имена которых появляются раньше в списке, присваивается более высокий приоритет, и они будут рассматриваться как синхронные. Другие серверы резервного копирования, появляющиеся позже в этом списке, представляют потенциальные синхронные резервные копии. Если какая-либо из текущих синхронных резервных копий отключается по какой-либо причине, она будет немедленно заменена следующей резервной копией с наивысшим приоритетом.
Пример synchronous_standby_names
для нескольких синхронных резервных копий на основе приоритета:
synchronous_standby_names = 'FIRST 2 (s1, s2, s3)'
В этом примере, если четыре резервных сервера s1
, s2
, s3
и s4
запущены, два резервных копирования s1
и s2
будут выбраны в качестве синхронных резервных копий, поскольку их имена появляются рано в списке имен резервного копирования. s3
является потенциальной синхронной резервной копией и возьмет на себя роль синхронной резервной копии, когда либо s1
, либо s2
выйдет из строя. s4
является асинхронным резервным сервером, так как его имя отсутствует в списке.
Метод ANY
определяет кворумную синхронную репликацию и заставляет транзакции ожидать фиксации до тех пор, пока их записи WAL не будут реплицированы по крайней мере на запрошенное количество синхронных резервных копий в списке.
Пример synchronous_standby_names
для кворумной множественной синхронной резервной копии выглядит следующим образом:
synchronous_standby_names = 'ANY 2 (s1, s2, s3)'
В этом примере, если четыре резервных сервера s1
, s2
, s3
и s4
работают, фиксация транзакций будет ждать ответов от любого двух резервных копий s1
, s2
и s3
. s4
является асинхронным резервным сервером, так как его имя отсутствует в списке.
Синхронные состояния резервных серверов можно просмотреть с помощью представления pg_stat_replication
.
Планирование производительности
Синхронная репликация обычно требует тщательно спланированных и размещенных резервных серверов для обеспечения приемлемой работы приложений. Ожидание не использует системные ресурсы, но блокировки транзакций продолжают удерживаться до подтверждения передачи. В результате неосторожное использование синхронной репликации снизит производительность приложений баз данных из-за увеличенного времени отклика и более высокой конкуренции.
PostgreSQL позволяет разработчику приложения указать требуемый уровень устойчивости через репликацию. Это может быть указано для всей системы, хотя это также может быть указано для конкретных пользователей или подключений или даже отдельных транзакций.
Например, рабочая нагрузка приложения может состоять из: 10% изменений - это важные данные о клиентах, а 90% изменений - менее важная информация, которую бизнес может легче пережить при ее потере, например сообщения чата между пользователями.
С помощью опций синхронной репликации, заданных на уровне приложения (на основном сервере), можно предложить синхронную репликацию для наиболее важных изменений без замедления основной части общей рабочей нагрузки. Опции уровня приложения являются важным и практичным инструментом, позволяющим использовать преимущества синхронной репликации для высокопроизводительных приложений.
Нужно учитывать, что пропускная способность сети должна быть выше скорости генерации данных WAL.
Планирование высокой доступности
synchronous_standby_names
определяет количество и имена синхронных резервных копий, от которых транзакции ожидают ответа при установке synchronous_commit
на on
, remote_apply
или remote_write
. Такие транзакционные подтверждения могут никогда не быть завершены, если какая-либо из синхронных резервных копий выйдет из строя.
Лучшим решением для обеспечения высокой доступности является обеспечение наличия такого количества синхронных резервных копий, которое запрашивается. Это можно сделать, указав несколько потенциальных синхронных резервных копий с помощью synchronous_standby_names
.
В приоритетной синхронной репликации резервные копии, названия которых появляются раньше в списке, будут использоваться в качестве синхронных резервных копий. Резервные копии, перечисленные после них, возьмут на себя роль синхронного резерва, если один из текущих выйдет из строя.
При синхронной репликации на основе кворума все резервные копии, указанные в списке, будут использоваться в качестве кандидатов для синхронных резервных копий. Даже если одна из них выйдет из строя, другие резервные копии продолжат выполнять роль кандидатов для синхронных резервных копий.
Когда резервный сервер впервые подключается к основному, он еще не будет должным образом синхронизирован. Это описывается как режим catchup
. Как только отставание между резервной копией и основной базой данных достигает нуля впервые, переходим к состоянию реального времени streaming
. Продолжительность догоняющего периода может быть длительной сразу после создания резервного сервера. Если резервная копия отключена, то период догоняния увеличится в соответствии с продолжительностью отключения резервной копии. Резервная копия способна стать синхронной резервной копией только тогда, когда она достигнет состояния streaming
. Это состояние можно просмотреть с помощью представления pg_stat_replication
.
Если основная база данных перезапускается при ожидании подтверждения коммитов, эти ожидающие транзакции будут помечены полностью завершенными после восстановления основной базы данных. Нет никакой возможности убедиться, что все резервные копии получили все оставшиеся данные WAL во время сбоя основной базы данных. Некоторые транзакции могут не отображаться как завершенные на резервном сервере, даже если они отображаются как завершенные на основном сервере. Гарантированное нами заключается в том, что приложение не получит явное подтверждение успешного завершения транзакции до тех пор, пока данные WAL не будут признаны безопасно полученными всеми синхронными резервными серверами.
Если действительно не получается поддерживать столько синхронных резервных копий, сколько требуется, то следует уменьшить количество синхронных резервных копий, от которых транзакционные коммиты должны ожидать ответов в synchronous_standby_names
(или отключить его), а затем перезагрузить файл конфигурации на главном сервере.
Если главный сервер изолирован от оставшихся серверов резервных копий, то следует переключиться на лучший кандидат из этих остальных серверов резервных копий.
Если нужно воссоздать резервный сервер, пока ожидаются транзакции, убедитесь, что команды pg_backup_start() и pg_backup_stop() выполняются в сеансе с synchronous_commit
= off
, иначе эти запросы будут ждать появления резервного сервера вечно.
Непрерывное архивирование на резервном сервере
Когда используется непрерывное архивирование WAL в резервной копии, возможны два разных сценария: архив WAL может быть общим для основного и резервного сервера или у резервного сервера может быть свой собственный архив WAL. Когда у резервного сервера есть свой собственный архив WAL, установите archive_mode
на always
, и резервная копия будет вызывать команду архива для каждого сегмента WAL, который она получает, независимо от того, восстанавливается ли он из архива или посредством потоковой репликации. Общий архив можно обрабатывать аналогичным образом, но archive_command
или archive_library
должны проверять, существует ли уже файл, подлежащий архивированию, и имеет ли существующий файл идентичное содержимое. Это требует более тщательного подхода к archive_command
или archive_library
, поскольку они должны быть осторожны, чтобы не перезаписывать существующий файл с другим содержимым, но возвращать успех, если один и тот же файл заархивирован дважды. И все это должно быть сделано без условий гонки, если две серверные машины попытаются заархивировать один и тот же файл одновременно.
Если archive_mode
установлен на on
, архиватор не включается во время восстановления или режима ожидания. Если резервный сервер повышен до уровня, он начнет архивирование после повышения, но не будет архивировать никакие файлы истории WAL или временной шкалы, которые он сам не создал. Чтобы получить полную серию файлов WAL в архиве, нужно убедиться, что весь журнал архивируется перед тем, как он достигнет резервного копирования. Это внутренне верно при передаче журналов на основе файлов, так как резервная копия может восстановить только те файлы, которые находятся в архиве, но не тогда, когда включена потоковая репликация. Когда сервер не находится в режиме восстановления, нет никакой разницы между режимами on
и always
.