Введение в PostgreSQL BDR.
PostgreSQL это не только стабильная и надежная СУБД но и плюс ко всем это динамично развивающийся продукт, в котором от релиза к релизу появляются самые разные прорывные вещи. Одной из таких технологий является потоковая репликация которая позволяет очень легко и дешево масштабировать базу данных на чтение. В статье речь пойдет о новой технологии BDR (Bi-Directional Replication).Немного терминов для тех кто не в теме:
WAL (Write Ahead Log) - журнал транзакции, на нем основана встроенная потоковая репликация в постгресе, СУБД пишет туда все что происходит с данными в БД.
SR (Streaming Replication) - общее название встроенной потоковой репликации которая которая основана на WAL, все что пишется в WAL, затем отправляется на слейвы и воспроизводится. Бывает физическая и логическая потоковая репликация.
PLSR (Physical Log Streaming Replication) - физическая потоковая репликация (то что уже реализовано и работает), все что попало в WAL без последующего разбора реплицируется на слейв сервера, это и изменение данных/схемы и более низкоуровневые вещи (full page writes, vacuum, hint bit settings).
LLSR (Logical Log Streaming Replication) - логическая потоковая репликация (появится в 9.4) также основана на WAL журналах, но уже более интеллектуальная и для репликации извлекается только определенная часть журналов в которых описываются изменения схемы и данных БД (то есть некоторые низкоуровневые вещи отсеиваются).
Что скрывается под термином BDR?
BDR (Bi-Directional Replication) это новая функциональность добавленая в ядро PostgreSQL которая предоставляет расширенные средства для репликации. На данный момент это реализовано в виде небольшого патча и модуля. Заявлено что полностью будет только в PostgreSQL 9.5 (сейчас 9.3-stable и 9.4-beta1).
Если коротко, то BDR позволяет создавать географически распределенные асинхронные мульти-мастер конфигурации (о да, детка) используя для этого встроенную логическую потоковую репликацию LLSR.
Тем не менее, BDR не является инструментом для кластеризации, т.к. здесь нет каких-либо глобальных менеджеров блокировок или координаторов транзакций (привет Postgres-XC/XL). Каждый узел не зависит от других, что было бы невозможно в случае использования менеджеров блокировки. Каждый из узлов содержит локальную копию данных идентичную данным на других узлах. Запросы также выполняются только локально (чтобы было более понятно о чем речь, приведу сравнение с Postgres-XC/Postgres-XL, там все серверы работают как бы в одной упряжке, транзакции рулятся глобальным менеджером транзакции, а запросы от приложения поступают на координатора(ов) который отправляет выполняться пришедшие запросы на любой рабочий узел, вот). При этом каждый из узлов внутренне консистентен в любое время, целиком же группа серверов является согласованной в конечном счете (eventually consistent)
Уникальность BDR заключается в том что она непохожа ни на встроенную потоковую репликацию, ни на существующие trigger-based решения (Londiste, Slony, Bucardo).
Самым заметным отличием от потоковой репликации является то, что BDR (LLSR) оперирует базами (per-database replication), а классическая PLSR реплицирует целиком инстанс (per-cluster replication), т.е. все базы внутри инстанса.
Существующие ограничения и особенности:
- Все изменения данных вызываемые INSERT/DELETE/UPDATE реплицируются (TRUNCATE на момент написания статьи пока не реализован)
- Большинство операции изменения схемы (DDL) реплицируются успешно. Неподдерживаемые DDL фиксируются модулем репликации и отклоняются с выдачей ошибкой (на момент написания статьи не работал CREATE TABLE ... AS)
- Определения таблиц, типов, расширений и т.п. должны быть идентичными между upstream и downstream мастерами.
- Действия которые отражаются в WAL, но непредставляются в виде логических изменений не реплицируются на другой узел (запись полных страниц, вакуумация таблиц и т.п.). Таким образом логическая потоковая репликация (LLSR) избавлена от некоторой части накладных расходов которые присутствуют в физической потоковой репликации PLSR (тем не менее это не означает что LLSR требуется меньшая пропускная способность сети чем для PLSR).
Установка выполняется на двух виртуальных машинах с CentOS 6.5 minimal. Устанавливаем необходимые для сборки пакеты:
# yum install curl readline-devel zlib-devel yum-utils -y
# yum groupinstall "Development Tools" -y
Переходим в аккаунт postgres и выполняем установку postgresql с поддержкой BDR. Тут стоит отметить что парни из 2ndQuadrant написали установщик чтобы желающие попробовать не прилагали больших усилий по установке и настройке, за что им пучок зелени.
# su - postgres
$ curl -s "http://git.postgresql.org/gitweb/?p=2ndquadrant_bdr.git;a=blob_plain;f=contrib/bdr/scripts/bdr_quickstart.sh;hb=refs/heads/bdr-next" | bash
Добавляем каталог с исполняемыми файлами postgres в переменную окружения PATH и тут же проверяем на psql. Кто не знает, команда export одноразовая, поэтому если вы планируете долго использовать или играться с BDR, то добавьте эту команду в .bashrc вашего пользователя (если у вас bash конечно же).
$ export PATH=$HOME/2ndquadrant_bdr/bdr/bin:$PATH
$ psql --version
psql (PostgreSQL) 9.4beta1_bdr0601
Инициализируем каталоги баз данных на обоих узлах после чего сразу же запускаем. Предварительно править postgresql.conf необязательно, при первом запуске мы создадим тестовую базу которая и будет в дальнейшем реплицироваться.
$ initdb -D data/ -A trust -U postgres
$ pg_ctl -l logfile -D data/ -w start
$ psql -c 'create database staging_db'
Создали базу, после чего переходим к настройке postgresql.conf. Сначала настраиваем upstream мастер. В конфигурации ниже, мы указываем необходимость загрузки библиотеки bdr (shared_preload_libraries), определяем уровень подробности WAL журналов в значение logical (wal_level), определяем количество слотов для репликации, максимально возможное количество процессов занятых в отправке WAL журналов (wal_senders) и включаем трекинг времени для операции COMMIT что необходимо для разрешения конфликтов (last-UPDATE-wins). Затем в конце файла определяем конфигурацию для BDR: указываем название соединения и настройки для подключения к удаленному узлу. Стоит отметить, что имя указываемое в bdr.connections является произвольным (у меня это имя виртуальной машины), главное что указанное имя должно участвовать в именах нижележащих параметров.
$ vi data/postgresql.conf
listen_address = '*'
shared_preload_libraries = 'bdr'
wal_level = logical
wal_senders = 4
max_replication_slots = 4
track_commit_timestamp = on
bdr.connections = 'vm13'
bdr.vm13_dsn = 'host=192.168.122.13 port=5432 user=postgres dbname=staging_db'
Теперь конфигурация downstream мастера. Сначала привожу описание конфигурации и затем ее разбор ниже.
$ vi data/postgresql.conf
listen_address = '*'
shared_preload_libraries = 'bdr'
wal_level = logical
wal_senders = 4
max_replication_slots = 4
track_commit_timestamp = on
bdr.connections = 'vm12'
bdr.vm12_dsn = 'host=192.168.122.12 port=5432 user=postgres dbname=staging_db'
bdr.vm12_init_replica = on
bdr.vm12_replica_local_dsn = 'host=127.0.0.1 port=5432 user=postgres dbname=staging_db'
Настройка второго узла отличается немногим, в частности здесь в конфигурации BDR мы указываем необходимость выполнить инициализацию реплики (bdr.vm12_init_replica) с узла указанного в bdr.vm12_dsn на локальную базу чьи реквизиты указаны в bdr.vm12_replica_local_dsn. Последний параметр является обязательным в случае если кластер БД инициализрован с помощью initdb (как раз наш случай) и в таком случае в кластере должна существовать пустая база которая будет в дальнейшем участвовать в репликации.
В случае инициализации через pg_basebackup опция bdr.vm12_replica_local_dsn не нужна.
Теперь определяем настройки аутентификации на обоих узлах, в моем случае все разрешено. Для production инсталяции так конечно же делать нельзя.
$ vi data/pg_hba.conf
host all all 192.168.122.0/24 trust
host replication postgres 192.168.122.0/24 trust
Выполняем перезапуск обоих узлов и смотрим журналы
$ pg_ctl -l logfile -D data/ -w restart
upstream мастер:
vm12 ~ $ tail -f logfile
LOG: unexpected EOF on standby connection
LOG: starting logical decoding for slot bdr_16384_6029905891437956874_1_16384__
DETAIL: streaming transactions committing after 0/1898F90, reading WAL from 0/1898C30
LOG: logical decoding found consistent point at 0/1898C30
DETAIL: running xacts with xcnt == 0
LOG: starting background worker process "bdr (6029905879776466735,1,16384,): vm13: apply"
downstream мастер:
vm13 ~ $ tail -f logfile
LOG: registering background worker "bdr (6029905891437956874,1,16384,): vm12: apply"
LOG: starting background worker process "bdr (6029905891437956874,1,16384,): vm12: apply"
LOG: logical decoding found consistent point at 0/18A4290
DETAIL: running xacts with xcnt == 0
LOG: exported logical decoding snapshot: "0000071B-1" with 0 xids
LOG: starting logical decoding for slot bdr_16384_6029905879776466735_1_16384__
DETAIL: streaming transactions committing after 0/18A42C8, reading WAL from 0/18A4290
LOG: logical decoding found consistent point at 0/18A4290
DETAIL: running xacts with xcnt == 0
В журналах все хорошо и ERROR сообщений нет (а если есть, проверяйте конфиги или грешите на разработчиков))) . На этом настройка и запуск завершен. Теперь можно проверить работу через создание таблиц в обеих базах.
Еще пара моментов. Временная остановка репликации осуществляется выключением downstream мастера. Однако стоит отметить что остановленная реплика приводит к тому что upstream мастер продолжит накапливать WAL журналы что в свою очередь может привести к неконтролируемому расходу пространства на диске. Поэтому крайне не рекомендуется надолго выключать реплику.
Удаление реплики навсегда осуществляется через удаление конфигурации BDR на downstream сервере с последующим перезапуском downstream мастера. Затем нужно удалить соответствующий слот репликации на upstream мастере с помощью функции pg_drop_replication_slot('slotname'). Доступные слоты можно просмотреть с помощью функции pg_get_replication_slots().
В качестве заключения скажу свои впечатления... У меня конечно есть некоторые вопросы по эксплуатации BDR, ответы на которые, скорей всего придется выяснять опытно-экспериментальным путем. Но уже на данном этапе мне нравится этот новый инструмент, настраивается оно легко и быстро, плюс к этому оно уже работает несмотря на то, что официально появится только в 9.5 (а это примерно через год). Таким образом, с релизом добавится еще один инструмент с помощью которого можно будет создавать надежные отказоустойчивые конфигурации, и это прекрасно. PostgreSQL от релиза к релизу становится только лучше и лучше.
Собственно на этом все. Всем спасибо за внимание.
P.S. Ссылки на почитать:
BDR User Guide
Logical Log Streaming Replication
PostgreSQL WAL Shipping and Streaming Replication
На главную "Virtualizing Linux"
Комментариев нет:
Отправить комментарий