четверг, 27 декабря 2012 г.

Глава 25.2 Резервные сервера на основе пересылки логов

Непрерывное архивирование может быть использовано для создания конфигурации высоко доступного (HA) кластера с одним или несколькими резервными серверами, готовыми принять на себя работу, если основной сервер выходит из строя. Эта возможность широко известна под именем "теплый" режим ожидания или передача логов.
Основной и резервный сервера работают вместе, чтобы обеспечить эту функциональность, хотя сами сервера слабо связаны. Мастер-сервер работает в непрерывном режиме архивирования, а каждый резервный сервер работает в непрерывном режиме восстановления, читая WAL файлы от мастера. Не требуется никаких изменений в таблицах базы данных чтобы включить эту возможность, так что этот метод не требует накладных расходов для настройки по сравнению с некоторыми другими видами репликации. Эта конфигурация также имеет относительно низкое влияние на производительность мастер сервера.
Непосредственное перемещение WAL записей с одного сервера баз данных на другой, как правило, называется "передачей логов". PostgreSQL реализует передачу файлов логов пересылая WAL записи, один файл (WAL сегмент) за раз. WAL файлы (16 МБ) могут быть легко и дешево переданы на любое расстояние, будь то соседняя система, другая система на этом же сайте, или другая система на другом конце земного шара. Пропускная способность, требуемая для этого, зависит от частоты транзакций основного сервера. Доставка логов на основе записей более детальна и передаёт WAL изменения инкрементально через сетевое подключение (см. раздел 25.2.5 ).
Следует отметить, что доставка логов асинхронна, то есть WAL записи передаются после подтверждения транзакции. В результате есть зазор потери данных в случае если основной сервер упадёт: не отправленные транзакции будут потеряны. Размер окна потери данных при такой пересылке логов может быть ограничен параметром archive_timeout, который может быть равен нескольким секундам. Однако такое значение существенно увеличит требования к пропускной способности, необходимой для пересылки файлов. Потоковая репликация (см. раздел 25.2.5 ) позволяет значительно сократить это окно.
Скорость восстановления достаточно хороша, так как резервный сервер как правило, находится всего в нескольких шагах от полной доступности после того, как он был активирован. В результате, эта конфигурация называется "теплым" резервом, так как она предлагает высокую доступность. Восстановление сервера из архива резервной копии базы и повтор транзакций займёт значительно больше времени, так что такой подход актуален только для аварийного восстановления, а не для обеспечения высокой доступности. Резервный сервер также может использоваться для запросов на чтение данных; в этом случае он называется "горячий" резервный сервер. В разделе 25.5 мы поговорим об этом подробнее.

25.2.1. Планирование.

Мудрым ходом будет создать мастер и резервный серверы так, чтобы они были похожи, как минимум с точки зрения сервера баз данных. В частности, имена путей, связанные с пространством имён таблиц будут передаваться без изменений, поэтому основной и резервный серверы должны иметь одинаковые пути монтирования для пространств имён таблиц, если Вы используете эту возможность. Имейте в виду, что если CREATE TABLESPACE выполнен на основном сервере, любую новую точку монтирования, в которой есть потребность, необходимо создать на мастере и резервном сервере до того, как будет выполнена эта команда. Оборудование не обязательно должно быть идентичным, но опыт показывает, что обслуживание двух идентичных систем проще, чем разнородных в течение всего срока использования приложения и этой системы. В любом случае, аппаратная архитектура должна быть одинаковой - пересылка от, скажем, 32-разрядной к 64-разрядной системе работать не будет.
Обычно пересылка журналов между серверами под управлением различных мажорных релизов PostgreSQL не возможна. Такова политика PostgreSQL Global Development Group: не вносить изменения в формат диска в минорных релизах, так что вполне вероятно, что запуск различных минорных релизов на мастере и резервном сервере будет успешно работать. Тем не менее, в этом случае не даётся никаких гарантий и обещаний поддержки и мы советуем вам держать основной и резервный серверы на одинаковых релизах как можно дольше. При обновлении на новый минорный релиз, безопасней всего обновить сперва резервные серверы - более вероятно, что новый минорный релиз сможет читать WAL файлы предыдущего минорного релиза, чем наоборот.

25.2.2. Операции на резервном сервере

В режиме ожидания сервер непрерывно применяет WAL, полученные от главного сервера. Резервный сервер может читать WAL из WAL архива (см. restore_command) или непосредственно с мастера через TCP соединение (потоковая репликация). Резервный сервер также будет пытаться восстановить любой WAL, найденный в каталоге pg_xlog резервного кластера. Обычно это происходит после перезапуска сервера, когда резервный сервер воспроизводит WAL, переданный от мастера до перезагрузки, но Вы также можете вручную скопировать файлы в pg_xlog в любое время, чтобы они были применены.
При запуске резервный сервер начинает с восстановления всех WAL, находящихся в архиве, вызывая restore_command. Как только он достигает конца доступного WAL и restore_command выдаёт ошибку, он пытается восстановить любой WAL доступный в каталоге pg_xlog. Если и это не удается, и настроена потоковая репликация, резервный сервер попытается подключиться к основному серверу и запустить поток WAL после последней корректной записи в архиве или pg_xlog. Если и это не удается или потоковая репликация не настроена, или же если соединение разрывается, резервный сервер возвращается к шагу 1 и пытается снова восстановить файл из архива. Этот цикл попыток восстановления из архива, pg_xlog, и через потоковую репликацию продолжается пока сервер не будет остановлен или не возникнет ошибка на основном сервере и не будет вызван триггер файл.
Режим ожидания завершается и сервер переключается в обычный режим либо когда запускается pg_ctl promote либо когда обнаруживается триггер-файл (trigger_file). До возникновения ошибки любой WAL доступный в архиве или в pg_xlog будет немедленно восстановлен, но попыток подключиться к мастеру не происходит.

25.2.3. Подготовка мастера для резервных серверов

Настройте непрерывное архивирование на мастере в любую директорию директорию, доступную для резервного сервера, как это описано в разделе 24.3. Место, отведённое под архивирование, должно быть доступным для резервного сервера даже когда мастер выключен, т.е. оно должно находиться на самом резервном сервере или другом доверенном сервере, а не на главном сервере.
Если вы хотите использовать потоковую репликацию, настройте аутентификацию на мастере, чтобы разрешить подключения для репликации от резервного серера, то есть, создайте роль и подходящие записи в pg_hba.conf, где поле базы данных имеет значение replication. Также убедитесь, что max_wal_senders имеет ​​на достаточно большое значение в файле конфигурации мастера.
Используйте базовый бакуп, как это описано в разделе 24.3.2 для начальной загрузки на резервный сервер.

25.2.4. Настройка резервного сервера

Чтобы настроить резервный сервер, восстановите базу из резервной копии, полученной с основного сервера (см. раздел 24.3.3 ). Создайте коммандный файл восстановления recovery.conf в каталоге с данными резервного кластера и включите режим standby_mode. Задайте в качестве restore_command простую команду копирования файлов из архива WAL. Если вы планируете иметь несколько резервных серверов для обеспечения высокой доступности, установите recovery_target_timeline в значение latest, чтобы резервный сервер следовал хронике изменений, которые происходят при ошибке на другом резервном сервере.
Примечание: Не используйте pg_standby или аналогичные инструменты вместе со встроенным режимом ожидания, описаным здесь. restore_command должна немедленно завершиться, если файл не существует, сервер повторит команду снова, если это необходимо. См. раздел 25,4 по поводу использования таких инструментов, как pg_standby.
Если вы хотите использовать потоковую репликацию, задайте значение primary_conninfo строкой соединения libpq, включающей имя хоста (или IP-адрес) и любые дополнительные данные, необходимые для подключения к основному серверу. Если мастер требует пароль для авторизации, то пароль тоже должен быть указанн в primary_conninfo.
Если вы настраиваете резервный сервер для обеспечения высокой доступности, настройте WAL архивирование, связь и аутентификацию, как на главном сервере, потому что резернвый сервер будет работать в качестве первичного сервера после сбоя мастера.
Если вы используете WAL архив, его размер может быть уменьшен при помощи параметра archive_cleanup_command, удаляющего файлы, которые больше не требуются резервному серверу. Утилита pg_archivecleanup предназначена для использования с archive_cleanup_command в типичных конфигурациях с одним резервным сервером, см. pg_archivecleanup. Заметим, однако, что если Вы используете архив для целей резервного копирования, Вы должны хранить файлы, необходимые для восстановления как минимум последней резервной копии базы, даже если они больше не нужны резервному серверу.
Вот простой пример recovery.conf:

standby_mode = 'on'
primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
restore_command = 'cp /path/to/archive/%f %p'
archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'

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

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

Потоковая репликация позволяет резервному серверу поддерживать большую актуальность данных, чем это возможно на основе пересылки файлов журналов. Резервный сервер подключается к мастеру, который передаёт WAL записи резервному серверу по мере их создания, не дожидаясь, пока WAL файл будет заполнен.
Потоковая репликация является асинхронной, так что всё еще есть небольшая задержка между совершением транзакции на мастере и тем, что изменения будут видны на резервном сервере. Эта задержка, однако, намного меньше, чем в случае пересылки файлов журнала; обычно это где-то одна секунда, если предположить, что резервный сервер достаточно мощен, чтобы идти в ногу с нагрузкой. При потоковой репликации не требуется archive_timeout для уменьшения окна потери данных.
Если вы используете потоковую репликацию без файлового непрерывного архивирования, вы должны задать для параметра wal_keep_segments на мастере достаточно высокое значение, чтобы быть уверенным, что старые сегменты WAL не слишком рано удаляются, в то время как резервный сервер может всё ещё нуждаться в них. Если резервнвый сервер слишком сильно отстаёт, его нужно реинициализировать из новой резервной копии базы. Если вы создали архив WAL, который доступн для резервных серверов, wal_keep_segments не требуется, поскольку резервные сервера всегда могут воспользоваться архивом, чтобы наверстать упущенное.
Для использования потоковой репликации настройте резервный сервер для пересылки журналов, как описано в разделе 25.2 . Шаг, который превращает резервный сервер на основе пересылки файлов журналов в сервер на основе потокового репликации - установка primary_conninfo в файл recovery.conf указывающий на основной сервер. Задайте listen_addresses и опции аутентификации (см. pg_hba.conf) на мастере, так чтобы резервный сервер мог подключиться к псевдобазе replication на мастер-сервере (см. раздел 25.2.5.1 ).
В системах, которые поддерживают keepalive опцию сокета, задание tcp_keepalives_idle, tcp_keepalives_interval и tcp_keepalives_count помогает мастеру оперативно заметить сломанные связи.
Установите максимальное число одновременных соединений от резервных серверов (см. max_wal_senders где об этом говорится подробнее).
Если резервный сервер запускается и primary_conninfo настроен правильно, то в режиме ожидания он будет подключаться к мастеру после применения всех файлов WAL, доступных в архиве. Если соединение установлено, Вы увидите процесс walreceiver на резервном сервере, и соответствующий процесс walsender на мастере.

25.2.5.1. Аутентификация

Очень важно, чтобы права доступа для епликации были настроена так, чтобы только доверенные пользователи могли читать WAL поток, потому что из них очень легко извлечь привилегированную информацию. Резервные серверы должны быть идентифицированы мастером как имеющие привелегии REPLICATION. Таким образом, на мастере должны быть заданы привилегии REPLICATION и LOGIN.
Примечание: Рекомендуется использовать выделенного пользователя для репликации. Хотя привилегия REPLICATION предоставляется по умолчанию учетной записи суперпользователя, не рекомендуется использовать эту учетную запись для репликации. Хотя привилегия REPLICATION дает очень высокие разрешения, она не позволяет пользователю изменять любые данные на основной системе, что даёт привилегия SUPERUSER.
Аутентификация клиента для репликации контролируется записями в pg_hba.conf, где в поле database стоит replication. Например, если резервный сервер запущен на хосте с IP 192.168.1.100 и имя учетной записи для репликации - foo, то администратор может добавить следующую строку в файл pg_hba.conf на мастере:
# Разрешить пользователю "foo" с хоста 192.168.1.100 подключения к мастеру
# в качестве резервного сервера для репликации, если правильно указан пароль.
# # TYPE DATABASE USER ADDRESS METHOD
host replication foo 192.168.1.100/32 md5
Имя хоста и номер порта мастера, имя пользователя для подключения и пароль, указанны в файле recovery.conf. Пароль также может быть задан в файле ~/.pgpass на резервном сервере (если в поле database указано replication). Например, если мастер работате на хосте с IP 192.168.1.50, порт 5432, имя учетной записи для репликации foo, пароль foopass, то администратор может добавить следующую строку в файл recovery.conf на резервном сервере:
# Резервный сервер подключается к мастеру, который работает на хосте 192.168.1.50
# с портом 5432, в качестве пользователя "foo" с паролем "foopass".
primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass

25.2.5.2. Мониторинг

Важным показателем "здоровья" потоковой репликации является количество WAL записей, созданных на мастере, но ещё не применённых на резервном сервере. Вы можете вычислить это отставание сравнивая текущие записи WAL на мастере с последними WAL, полученными на резервном сервере. Они могут быть получены с помощью pg_current_xlog_location на мастере и pg_last_xlog_receive_location на резервном сервере соответственно (см. таблицу 9-56 и таблицу 9-57 в поисках деталей). Последний WAL, полученный резервным сервером также отображается в статусе процесса получения WAL, увидеть который можно с помощью команды ps (см. раздел 27.1).
Вы можете получить список процессов-отправителей WAL при помощи pg_stat_replication. Большая разница между pg_current_xlog_location и sent_location может указывать на то, что мастер находится под большой нагрузкой, в то время как различия между sent_location и pg_last_xlog_receive_location на резервном сервере может указывать на задержки в сети, или на большую нагрузку на резервный сервер.

25.2.6. Синхронная репликация

PostgreSQL потоковая репликация по умолчанию является асинхронной. Если основной сервер выходит из строя, в таком случае некоторые транзакции, которые были подтверждены, могут быть не реплицированы на резервный сервер, в результате чего может произойти потеря данных. Количество потерянных данных будет пропорционально задержке репликации в момент краха мастера.
Синхронная репликация предоставляет возможность быть уверенным, что все изменения, сделанные транзакцией были переданы одному синхронному резервному серверу. Это расширяет стандартный уровень надёжности, предоставляемой транзакциями. Этот уровень защиты называют 2-жды безопасной репликацией в computer science theory.
При запросе синхронной репликации, каждое подтверждение транзакции на запись будет отложено до тех пор, пока не придёт подтверждение, что транзакция была записана в журнал транзакций на дисках основного и резервного серверов. Единственная возможность, где данные могут быть потеряны - когда мастер и резервный сервера засбоят в одно и то же время. Такая репликация может обеспечить более высокий уровень надёжности, но только в том случае, если системный администратор внимательно отнесётся к размещению и управлению двумя серверами. Ожидание подтверждение повышает уверенность пользователей, что изменения не будут потеряны в случае аварии сервера, но также обязательно увеличивает время отклика для запрашивающего транзакцию. Минимальное время ожидания составляет время обмена информацией в оба конца, между мастером и резервным сервером.
Транзакции только на чтение и отмена транзакций не требуют ожидания ответа от резервных серверов. Подтверждение подтранзакций так же не требует ожидания ответа от резервных серверов, только подтверждения транзакции верхнего уровня. Длительные действия, такие как загрузка данных или построение индекса тоже не требует ожидания выполнения. Все двухфазные подтверждения требуют ожидания подтверждения, в том числе подготовка и завершение.

25.2.6.1. Базовая конфигурация

После настройки потоковой репликации настройка синхронной репликации требует только одного дополнительного шага:synchronous_standby_names должно быть задано непустое значение. synchronous_commit также должно быть присвоено значение on, но, так как это является значением по умолчанию, как правило, никаких изменений не требуется. Эта конфигурация заставляет мастера после каждой транзакции ожидать подтверждения что резервный сервер записал транзакцию в надёжное хранилище, даже если это занимает очень много времени. synchronous_commit может быть установлен отдельными пользователями, поэтому его можно настроить в файле конфигурации для конкретных пользователей или баз данных, или настроить его динамически для приложениий, для того, чтобы контролировать надёжность на уровне транзакций.
После подтверждения того, что запись была записана на диск мастера, WAL запись затем отправляется к резервному серверу. Резервный сервер посылает ответное сообщение каждый раз, когда новая партия WAL данных записывается на диск, если wal_receiver_status_interval не установлен в нуль на неё. Если резервный сервер является первым соответствующим сервером, указанным в synchronous_standby_names на мастере, ответное сообщение от этого сервера будет использовано для прекращения ожидания пользователями подтверждения того, что уведомление о фиксации записи было получено. Эти параметры позволяют администратору определить резервные сервера, которые должны быть синхронными. Обратите внимание, что конфигурация синхронной репликации в основном проводится на мастере.
Ожидание пользователей будет прервано если будет запрошено быстрое выключение. Однако, как и при использовании асинхронной репликации, сервер не будет полностью остановлен до тех пор, пока все невыполненные WAL записи не будут переданы подключённым в данный момент резервным серверам.

25.2.6.2. Планирование производительности

Синхронная репликация, как правило, требует тщательной планировки и правильного размещения резервных серверов для обеспечения приемлемой производительности приложений. Ожидание не использует системные ресурсы, но блокировки транзакции сохраняются до подтверждения транзакции. В результате неосторожного использования синхронной репликации может уменьшиться производительность приложений баз данных из-за увеличения времени отклика и высокой конкуренции (higher contention).
PostgreSQL позволяет разработчикам приложений определить требуемый уровень надёжности с помощью репликации. Он может быть определен для системы в целом,или для конкретного пользователя или подключения, или даже для отдельных операций.
Например, нагрузка приложения может состоять из: 10% изменений важных для клиента и 90% менее важных изменений, чью потерю бизнес может пережить гораздо легче, например, чат между пользователями.
Если синхронная репликация определена на прикладном уровне (на мастере) мы можем предложить синхронную репликацию наиболее важных изменений, не замедляя остальную часть общей нагрузки. Такой вид репликации являются важным и практичным инструментом для совмещения преимущества синхронной репликации и обеспечения высокой производительности приложения.
Вы должны учитывать, что пропускная способность сети должна быть выше, чем скорость генерации данных WAL.

25.2.6.3. Планирование высокой доступности

Коммиты, сделанные при synchronous_commit, имеющим значение on, будут ожидать ответа от синхронного резервного сервера. Ответ же может и не придти, если последний, или единственный, резервный сервер упадёт.
Лучшее решение для предотвращения потери данных - убедиться, что Вы не потеряли последний оставшийся резервный сервер. Это может быть достигнуто перечислением нескольких потенциальных синхронных резервных серверов, используя synchronous_standby_names. Первый названный резервный сервер будет использоваться как синхронный резервный сервер. Остальные сервера, перечисленных после него, возьмут на себя роль синхронного резервного сервера, если первый выйдет из строя.
Когда резервный сервер первый раз подключается к мастеру, он ещё не синхронизирован с ним должным образом. Это описывается как catchup режим. После того, как в первый раз разрыв между резервным серером и мастером достигает нуля, мы переходим в режим реального времени streaming. catch-up период может продолжаться достаточно долго с момента создщания резервного сервера. Если резервный сервер выключен, то catchup период будет увеличен на то время, пока резервный сервер выключен. Резервный сервер может стать синхронным только после того, как он достигает режима streaming.
Если мастер перезагружается во время ожидания подтверждения, то эти ожидающие транзакции будут помечены полностью подтвеждёнными только после того, как база данных мастера будет восстановлена. Не существует способа убедиться, что все резервные сервера получили все необработанные данные WAL на момент падения мастера. Некоторые транзакции могут не быть отмеченными как подтверждённые на резервном серере, даже если они отражены как совершенные на мастере. Мы лишь гарантируем, что приложение не получит явное подтверждение успешной транзакции, до тех пор, пока WAL данные не будут точно полученными резервным сервером.
Если вы действительно потеряете свой последний резервный сервер, то Вы должны отключить synchronous_standby_names и перезагрузить конфигурационный файл на мастере.
Если мастер изолирован от остальных резервных серверов, то Вы должны переключиться на лучшего кандидата из оставшихся резервных серверов.
Если вам нужно заново создать резервный сервер, во время ожидания транзакций, убедитесь, что команды для запуска pg_start_backup() и pg_stop_backup() выполняются в сессии с synchronous_commit = off, в противном случае эти запросы будут вечно ждать появления резервного сервера.

Комментариев нет:

Отправить комментарий