Эволюция отказоустойчивости в PostgreSQL: фаза репликации

в 12:19, , рубрики: fault tolerance, internals, postgresql, sql, transactions, Блог компании PG Day'17 Russia, хранение данных, хранилища данных

Мы продолжаем публиковать серию переводов Gulcin Yildirim, разработчика компании 2ndQuadrant, об отказоустойчивости PostgreSQL и сегодня предлагаем вашему вниманию второй пост из серии.

Gulcin приедет на PG Day'17 и лично ответит на вопросы участников, а также расскажет более подробно не только о репликации в PG, но и об автоматизации апгрейдов Постгреса в облаке и не только. Готовьте свои вопросы!

Эволюция отказоустойчивости в PostgreSQL: фаза репликации - 1

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

Если вы хотите проследить за процессом эволюции с самого начала, рекомендую вам прочитать первую статью серии: Эволюция отказоустойчивости в PostgreSQL.

Репликация в PostgreSQL

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

Посмотрим на базовую архитектуру. Как правило, отдельные сервера баз данных называются узлами. Вся группа серверов баз данных, задействованных в репликации, известна как кластер. Сервер БД, позволяющий пользователю вносить изменения называется основным (master) или первичным (primary), или может быть описан как источник изменений. Сервер БД, разрешающий доступ только в режиме чтения, называется Горячий резерв или Hot Standby (термин Hot Standby подробно объясняется в разделе Режимы Standby).

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

Давайте посмотрим, как PostgreSQL справлялся с репликацией на протяжении всего своего существования и каково текущее состояние отказоустойчивости в разрезе репликации.

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

Когда-то (около 2000-2005 гг.) Постгрес поддерживал только отказоустойчивость/восстановление отдельного узла, что достигалось, в основном, с помощью WAL — журнала транзакций. Частично отказоустойчивость обеспечивается MVCC (системой управления параллельным доступом с помощью многоверсионности), но это по большей части оптимизация.

WAL (write ahead logging) был и остается основным методом обеспечения отказоустойчивости в PostgreSQL. Его суть в том, что у вас есть файлы WAL, в которые вы всё записываете, и, в случае отказа системы, можете воспроизвести их и всё восстановить. Этого было достаточно для архитектур, состоящих из одного узла, а для достижения отказоустойчивости множества узлов лучшим решением считается репликация.

Сообщество Postgres долгое время было уверено, что репликация внутри Постгреса ни к чему, и её можно выполнять внешними инструментами, поэтому появились такие инструменты, как Slony и Londiste. (Мы поговорим о триггерных решениях для репликации в следующих статьях этой серии).

В конце концов стало понятно, что устойчивости одного сервера недостаточно, и всё больше людей стали требовать полноценной отказоустойчивости аппаратных средств, а также способ переключения, встроенные в Постгрес. Тогда и появилась физическая репликация, в то время известная как physical streaming.

Мы пройдемся по всем методам репликации в этой статье, но для начала давайте проследим хронологию событий истории репликации в PostgreSQL по основным релизам:

  • PostgreSQL 7.x (~2000)
    • Репликация не должна быть частью ядра Postgres
    • Londiste – Slony (триггерная логическая репликация)
  • PostgreSQL 8.0 (2005)
    • Восстановление на момент времени, (Point-In-Time recovery, WAL)
  • PostgreSQL 9.0 (2010)
    • Потоковая репликация (физическая)
  • PostgreSQL 9.4 (2014)
    • Логическое декодирование (извлечение набора изменений [changsets])

Физическая репликация

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

Резервный инстанс в режиме чтения просто применяет изменения (из WAL), а единственные операции записи приходят всё из того же журнала WAL. В целом, именно так работает механизм потоковой репликации. Изначально репликацией считалась исходная отправка всех файлов (log shipping), но позднее она превратилась в потоковую.

В log shipping мы отправляли целые файлы с помощью команды archive_command. Логика там была довольно простая: вы просто отправляете архив и куда-то его регистрируете — например, целый WAL файл на 16MБ — а затем применяете его где-то, запрашиваете следующий, применяете его и так далее. Позднее это было поставлено на поток через сеть, благодаря использованию протокола libpq в версии PostgreSQL 9.0.

Нынешняя репликация более известна как физическая потоковая репликация, так как мы передаём ряд физических изменений от одного узла другому. Это значит, что когда мы вставляем строку в таблицу, мы генерируем записи изменений для вставки и всех записей индекса.

Когда мы применяем к таблице VACUUM, также генерируются записи изменений.

Кроме того, физическая потоковая репликация записывает все изменения на уровне byte/block, так что сделать что-либо, кроме как воспроизвести их на реплике, практически невозможно.

Эволюция отказоустойчивости в PostgreSQL: фаза репликации - 2

Рис.1 показывает, как физическая репликация работает всего с двумя узлами. Клиент выполняет запросы на главном узле, изменения записываются в журнал транзакций (WAL) и копируются по сети в WAL на резервном узле. Процесс восстановления на узле в режиме ожидания читает изменения из WAL и применяет их к файлам данных, совсем как в случае аварийного восстановления. Если резервный узел находится в режиме hot standby, клиенты могут выполнять запросы на чтение, пока всё это происходит.

Примечание: Физическая репликация — это просто отправка файлов WAL по сети от основного узла к резервному. Файлы могут отправляться разными протоколами, например, scp, rsync, ftp… Разница между физической и физической потоковой репликацией заключается в том, что потоковая репликация использует внутренний протокол для отправки WAL файлов (процессы отправителя и получателя).

Режимы Standby

Несколько узлов обеспечивают высокий уровень доступности. По этой причине современные архитектуры обычно имеют резервные узлы. Существуют разные режимы резервных узлов (“теплый” и “горячий” резерв, warm & hot standby). Далее мы поясним основные различия между режимами резервных узлов и рассмотрим случай с мультимастер архитектурой.

Warm Standby

Может быть активирован немедленно, но не может выполнять полезную работу до момента активации. Если мы непрерывно передаем последовательность WAL файлов на другую машину, на которую была загружена базовая резервная копия той же базы, то у нас система warm standby: в любой момент мы можем активировать вторую машину, и на ней будет почти актуальная копия базы данных. Warm standby не позволяет делать запросы в режиме чтения, что наглядно продемонстрировано на Рис.2.
Эволюция отказоустойчивости в PostgreSQL: фаза репликации - 3
Восстановление в режиме warm stanby происходит настолько быстро, что резервный сервер обычно становится полностью доступен через несколько мгновений после активации. Именно поэтому такой режим называется “теплой” (warm) резервной конфигурацией с высоким уровнем доступности.

Hot Standby

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

Эволюция отказоустойчивости в PostgreSQL: фаза репликации - 4

Понятие «hot standby» также относится к способности сервера перейти от восстановления к нормальной работе, в то время как пользователи продолжают выполнять запросы и/или держат свои соединения открытыми. На Рис.3 видно, что этот резервный режим разрешает запросы на чтение.

Мультимастер

Все узлы могут выполнять задачи по чтению/записи. (Мы рассмотрим мультимастер архитектуры в следующих статьях этой серии.)

Параметр WAL Level

Есть связь между настройкой параметра wal_level в файле postgresql.conf и тем, для чего подходит эта настройка. В таблице ниже показана эта связь в PostgreSQL версии 9.6.

WAL Level Подходит для
Минимальный (minimal) Аварийное восстановление
Реплика (replica) Физическая репликация
Архивирование, основанное на файлах
Логический (logical) Логическая репликация

Небольшое примечание: параметр wal_level определяет, сколько информации записывается в WAL. Значение по умолчанию — minimal, при котором записывается только информация, необходимая для восстановления после аварии или внезапного отключения. replica добавляет логирование, необходимое для архивирования WAL, а также информацию, необходимую для выполнения запросов на чтение на резервном сервере. И наконец logical добавляет информацию, необходимую для поддержки логического декодирования. Каждый уровень включает в себя информацию, записываемую на всех низких уровнях.

В версиях до 9.6 этот параметр также позволял значения archive и hot_standby. Они по-прежнему принимаются, но отображаются на уровень replica.

Failover и Switchover

При репликации с одним основным узлом, если этот узел умрет, один из резервных должен занять его место (повышение, promotion). В противном случае мы не сможем принимать новые операции записи. Таким образом, названия «основной» и «резервный» — это просто роли, которые могут быть назначены любому узлу в определенный момент времени. Чтобы передать роль основного другому узлу, мы выполняем процедуру под названием Switchover.

Если основной узел умирает и не восстанавливается, происходит более серьезная смена ролей, известная как Failover. Эти две процедуры схожи во многих отношениях, но удобнее использовать разные термины для каждого события. (Знание понятий failover и switchover поможет нам разобраться с вопросами хронологии в следующей статье.)

Заключение

В этой статье мы обсудили репликацию в PostgreSQL и её важность для обеспечения отказоустойчивости и надежности. Мы рассмотрели физическую потоковую репликацию и поговорили о режимах standby в PostgreSQL. Также были упомянуты Failover и Switchover. Мы продолжим тему разговором о временных шкалах (timelines) в PostgreSQL в следующей статье.

Помимо выступления Gulcin, мы готовим для вас серию докладов о репликации и проблемах организации отказоустойчивости различных систем хранения данных от таких докладчиков как Света Смирнова, Colin Charles, Николай Мациевский и многих других. Голосуйте за наиболее актуальные для вас темы, мы обязательно учтем все пожелания при составлении финальной программы конференции!

Автор: PG Day'17 Russia

Источник

Поделиться

* - обязательные к заполнению поля