Skip to content

Instantly share code, notes, and snippets.

@gmile
Forked from akrymets/postgre_pipiliendb_replication
Last active February 23, 2017 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gmile/8198df776682c2d4c2f3aebd76ab6e2c to your computer and use it in GitHub Desktop.
Save gmile/8198df776682c2d4c2f3aebd76ab6e2c to your computer and use it in GitHub Desktop.
Репликация из postgresql в PiepelineDB

Постановка задачи

Не так давно на рабочем проекте была поставлена задача настроить механизм репликации данных из основной базы PostgreSQL в базу PipelineDB.

В этой статье я изложу ход решения данной задачи.

Пара слов о PipelineDB

PipelineDB - одна из реализаций ныне набирающих популярность стриминговых СУБД. О преимуществах стриминговых СУБД в различных кейсах (https://www.pipelinedb.com/use-cases) вы можете без труда прочитать сегодня на множестве ресурсов. Очень просто принцип их работы визуализирован на сайте www.pipelinedb.com в разделе “How It Works”.

PipelineDB это форк PostgreSQL с дополнительной функциональностью, позволяющей хранить только агрегированные данные, рассчитывая дельту из поступающего стрима (отсюда и название этого типа СУБД) на лету. Эти данные хранятся в специальных объектах PipelineDB, называемых continuous views. Сам же стрим в простейшем случае получается из обычных таблиц, хранимых в этой же БД.

Начальные условия

Рассмотрим кейс, в котором:

  1. на продуктовой среде у нас уже работает СУБД PostgreSQL версии 9.4+,
  2. нам нужно получить ее read-only реплику.

Read-only реплика необходима для того, что-бы разгрузить основную базу от множественных и тяжелых SELECT-запросов которые генерируют многочисленные внутренние сервисы аналитики.

Выбор инструмента для репликации

Стриминговая асинхронная репликация

Первое решение, которое приходит в голову: замечательный встроенных механизм потоковой асинхронной репликации PostgreSQL, который появился в версии 9.0 (http://peter.eisentraut.org/blog/2015/03/03/the-history-of-replication-in-postgresql/). Но практически сразу стало ясно, что этот механиз репликации мне не подходит в силу своих ограничений в рамках поставленой задачи:

  • мастер и реплика должны иметь одинаковую мажорную версию PostgreSQL, а по возможности и крутиться на идентичном “железе”,
  • реплика при этом работает в режиме “hot standby”, в котором она доступна только для чтения.

В моем случае первое ограничение помешало мне поднять реплику мастер-сервера, работающего под управлением Postgre 9.6, т.к. версия этой СУБД, используемая как базовая для последней версии PipelineDB - только 9.5. Если у Вас мастер работает под управлением Postgre 9.5, то вы можете попробовать такой фокус, но скорее всего мастер просто не распознает PipelineDB как полноценный и равный себе PostgreSQL.

Второе ограничение оказалось значительно более существенным. Как я писал в начале, PipelineDB хранит в базе свои метаданные для обслуживания этих самых continuous views, ради которых все и затевается. Но согласно принципам работы стриминговой репликации - реплика должна выглядеть один-в-один с мастером: реплика существует в формате read-only и исключает любые возможные различия с мастером. В моем случае это было не допустимо.

Логическая репликации

Стриминговая репликация мне не подошла, поэтому очевидный вывод: нужно смотреть в сторону логической репликации. И тут открывается целый океан возможностей.

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

Среди популярных инструментов:

  • slony (trigger-based),
  • pgpool / pgpool-II (middleware).

Мой выбор пал на slony.

Две недели работы над конфигурацией slony для моего случая успехом так и не увенчалась. Упрощая конфигурацию среды и сводя количество внешних факторов к минимуму настроить slony не удавалось.

В конце-концов изначальный эксперимент по репликации упростился до следующих исходных условий:

  • мастер и слейв были запущены в docker-контейнерах (хост система – macOS),
  • образы для контейнеров содержали Alpine Linux с PostgreSQL 9.6.

Но даже в этом случае демон slony упорно не хотел запускаться, падая с ошибкой Segmentation fault. Не исключено что мои исходные условия в том или ином смысле были несовместимы со Slony, и в другой системной конфигурации у вас наверняка все получится.

Впрочем после прочтения статьи дальше вы можете не захотеть колупаться в этой древней утилите. Не стоит забывать и об этом: http://howfuckedismydatabase.com/postgres/slony.php

До pgpool / pgpool-II я так и не добрался, потому что по дороге нашел то, что и стало в конечном итоге решением: утилита pglogical от 2ndQuadrant (https://2ndquadrant.com/en/resources/pglogical/), которая вообще не использует никаких триггеров, а подключается к СУБД в качестве плагина.

Решение

Чтение документации по утилите и осознание кто же такие 2ndQuadrant сразу расположило меня к этому решению. Главным разработчиком pglogical является человек по имени Petr Jelinek, активный контрибутор PostgreSQL. Он реализовал логическую репликацию из коробки (а так-же ряд ее улучшений, см. 1 и 2, которая будет доступна с выходом версии PostgreSQL предположительно в 3м квартале 2017 года.

Похоже что pglogical явился своеобразным успешным proof-of-concept-ом, и одновременно единственным стабильным решением логической репликации для версий PostgreSQL 9.4+.

В свете вышеизложенного стоит ли говорить что я принял решение подвинуть pgpool в пользу pglogical?

Тем не менее практически сразу меня ждал неприятный сюрприз. В эта утилита существует только для PostgreSQL версий 9.4, 9.5 и 9.6. Официальной поддержкой PipelineDB и не пахло: утилита наотрез отказалась устанавливаться на хост с PipelineDB, радостно сообщая:

unmet dependency postgresql-9.5

Казалось что замечательный эксперимент закончился так по сути и не начавшись.

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

На хост с PipelineDB утилита pglogical устанавливается следующим образом (все делалось в docker-контейнере под рутом):

  1. Добавляем репозиторий и скачиваем пакеты утилиты:
echo "deb [arch=amd64] http://packages.2ndquadrant.com/pglogical/apt/ jessie-2ndquadrant main" > /etc/apt/sources.list.d/2ndquadrant.list
wget --quiet -O - http://packages.2ndquadrant.com/pglogical/apt/AA7A6805.asc | apt-key add -
apt-get update && apt-get download libpq5 postgresql-9.5-pglogical
  1. Устанавливаем необходимые библиотеки и сам пакет с игнорированием зависимостей, решая нашу проблему нежелания утилиты устанавливаться на что либо кроме PostgreSQL:
dpkg -i --ignore-depends=postgresql-9.5 libpq5_9.4.10-0+deb8u1_amd64.deb
dpkg -i --ignore-depends=postgresql-9.5 postgresql-9.5-pglogical_1.2.2-1jessie_amd64.deb
  1. Удаляем запись о зависимости из файла /var/lib/dpkg/status, чтобы при дальнейшей работе apt-get она не ругалась на ненайденную зависимость и не предлагала нам удалить pglogical:
sed 's/, postgresql-9.5//g' /var/lib/dpkg/status > /var/lib/dpkg/status-new && \
mv /var/lib/dpkg/status /var/lib/dpkg/status.bkp && \
mv /var/lib/dpkg/status-new /var/lib/dpkg/status
  1. Утилита установлена на хост с PipelineDB.

Но вот снова незадача - утилита устанавливается в папки с именами PostgreSQL, а PipelineDB имеет аналогичную структуру папок, но с именами PipelineDB. Ну так не будем по этому поводу унывать и переместим файлы утилиты в соответствующие папки уже PipelineDB:

mv /usr/lib/postgresql/9.5/lib/* /usr/lib/pipelinedb/lib/pipelinedb/
mv /usr/lib/postgresql/9.5/bin/* /usr/lib/pipelinedb/bin/
mv /usr/share/postgresql/9.5/extension/* /usr/lib/pipelinedb/share/pipelinedb/extension/

Все!

Получлся готовый к использованию работающий сервер с PipelineDB с установленной утилитой pglogical.

После непродолжительной настройки кластера мастер-слейв (PostgreSQL-PipilineDB), описание которой можно найти на миллионе ресурсов, включая документацию PostgreSQL, а так-же после прохождения простеньких шагов настройки самой утилиты (https://2ndquadrant.com/en/resources/pglogical/pglogical-docs/) мы можем убедиться, что репликация работает.

Буду рад услышать замечания по сути и предложения по повествованию. Самые лучшие предложения будут реализованы в виде правок к статье.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment