Последнюю версию этого документа можно попробовать получить по адресу: http://www.kuzin.net/work/sloniki-privet.html
Этот документ описывает настройку репликации базы данных PostgreSQL с главного сервера на один ведомый сервер. Будет рассмотрено также добавление ещё одного ведомого узла в имеющуюся систему репликации.
Рекомендуется прочитать документацию на Slony, которая располагается по адресу: http://linuxfinances.info/info/slony.html, README из дистрибутива, также полный список команд консоли slonik находится в файле slonik-commands.html, в поставке.
Home page проекта: http://gborg.postgresql.org/project/slony1/projdisplay.php
Далее подразумевается что читатель знаком с терминами "кластер", "узел" (node), "набор" (replication set). Если нет, некоторые моменты могут быть не ясны. Не помешает также некоторое знание SQL ,)
Вопрос установки системы Slony не рассматривается в данном документе. В документации, поставляемой с системой рассмотрена базовая установка.
У меня используется Slony на Linux с версиями PostgreSQL от 7.4.7 до 8.3.5. Slony, как и СУБД, установлены из дистрибутивных пакетов.
Slony это система репликации реального времени, позволяющая организовать синхронизацию нескольких серверов PostgreSQL по сети. Slony использует триггеры Postgre для привязки к событиям INSERT/DELETE/UPDATE и хранимые процедуры для выполнения действий.
Система Slony с точки зрения администратора состоит из двух главных компонент, репликационного демона slony и административной консоли slonik. Администрирование системы сводится к общению со slonik-ом, демон slon только следит за собственно процессом репликации. А админ следит за тем, чтобы slon висел там, где ему положено.
Все команды slonik принимает на свой stdin. До начала выполнения скрипт slonik-a проверяется на соответствие синтаксису, если обнаруживаются ошибки, скрипт не выполняется, так что можно не волноваться если slonik сообщает о syntax error, ничего страшного не произошло. И он ещё ничего не сделал. Скорее всего.
Рассмотрим теперь установку на гипотетическую базу данных customers (названия узлов, кластеров и таблиц являются вымышленными).
Наши данные
Важно: не рекомендую использовать идущий в комплекте скрипт slony_setup.pl на момент написания этого документа (версия Slony 1.0.5) этот скрипт не делал ряд важных проверок при генерации репликационных скриптов, из-за чего могли возникать труднообъяснимые и трудноуловимые глюки.
Для начала нам нужно создать пользователя Postgres, под которым будет действовать Slony. По умолчанию, и отдавая должное системе, этого пользователя обычно называют slony.
Также на каждом из узлов лучше завести системного пользователя slony, чтобы запускать от его имени репликационного демона slon. В дальнейшем подразумевается, что он (и пользователь и slon) есть на каждом из узлов кластера.
Здесь я рассматриваю, что серверы кластера соединены посредством сети Internet (как в моём случае), необходимо чтобы с каждого из ведомых серверов можно было установить соединение с PostgreSQL на мастер-хосте, и наоборот. То есть, команда:
должна подключать нас к мастер-серверу (после ввода пароля, желательно). Если что-то не так, возможно требуется поковыряться в настройках firewall-a, или файле pg_hba.conf, который лежит в $PGDATA.
Теперь устанавливаем на slave-хост сервер PostgreSQL. Следующего обычно не требуется, сразу после установки Postgres "up and ready", но в случае каких-то ошибок можно начать "с чистого листа", выполнив следующие команды (предварительно сохранив конфигурационные файлы и остановив postmaster):
Запускаем postmaster.
Внимание! Обычно требуется определённый владелец для реплицируемой БД. В этом случае необходимо завести его тоже!
Эти две команды можно запускать с customers_master, к командной строке в этом случае нужно добавить "-h customers_slave", чтобы все операции выполнялись на slave.
На slave, как и на master, также нужно установить Slony.
Следующие команды выполняются от пользователя slony. Скорее всего для выполнения каждой из них потребуется ввести пароль (slony_user_password). Итак:
Внимание! Все таблицы, которые будут добавлены в replication set должны иметь primary key. Если какая-то из таблиц не удовлетворяет этому условию, задержитесь на этом шаге и дайте каждой таблице primary key командой ALTER TABLE ADD PRIMARY KEY.
Если столбца который мог бы стать primary key не находится, добавьте новый столбец типа serial (ALTER TABLE ADD COLUMN), и заполните его значениями. Настоятельно НЕ рекомендую использовать "table add key" slonik-a.
Продолжаем.
Создаём таблицы и всё остальное на slave:
pg_dump -s сдампит только структуру нашей БД.
pg_dump -s customers должен пускать без пароля, а вот для psql -U slony -h customers_slave.com customers придётся набрать пароль (slony_user_pass). Важно: я подразумеваю что сейчас на мастер-хосте ещё не установлен Slony (речь не про make install), то есть в БД нет таблиц sl_*, триггеров и прочего. Если есть, то возможно два варианта:
Тогда до переноса структуры на slave выполните
следующее:
Y - число. Любое. Важно: если это действительно ошибка, cluster name может иметь какой-то другое значение, например T1 (default). Нужно его выяснить и сделать uninstall.
Если структура уже перенесена (и это действительно ошибка), сделайте uninstall с обоих узлов (с master и slave).
Если Сейчас мы имеем два сервера PgSQL которые свободно "видят" друг друга по сети, на одном из них находится мастер-база с данными, на другом - только структура.
На мастер-хосте запускаем такой скрипт:
Здесь мы инициализируем кластер, создаём репликационный набор, включаем в него две таблицы. And something else. Важно: нужно перечислить все таблицы, которые нужно реплицировать, id таблицы в наборе должен быть уникальным, таблицы должны иметь primary key.
Важно: replication set запоминается раз и навсегда. Чтобы добавить узел в схему репликации не нужно заново инициализировать set.
Важно: если в набор добавляется или удаляется таблица нужно переподписать все узлы. То есть сделать unsubscribe и subscribe заново (см slonik-commands.html).
Скрипт:
Теперь, на обоих узлах необходимо запустить демона репликации.
и
Сейчас слоны обменяются сообщениями и начнут передачу данных. Начальное наполнение происходит с помощью COPY, slave DB на это время полностью блокируется.
В среднем время актуализации данных на slave-системе составляет до 10-ти секунд. slon успешно обходит проблемы со связью и подключением к БД, и вообще требует к себе достаточно мало внимания.
по пунктам:
выполнить 2.1
выполнить 2.2
Новый узел имеет id = 3. Находится на хосте customers_slave3.com, "видит" мастер-сервер по сети и мастер может подключиться к его PgSQL.
после дублирования структуры (п 2.2) делаем следующее:
Это нужно чтобы удалить схему, триггеры и процедуры, которые были сдублированы вместе с таблицами и структурой БД.
Инициализировать кластер не надо. Вместо этого записываем информацию о новом узле в сети:
Новый узел имеет id 3, потому что 2 уже есть и работает. Подписываем новый узел 3 на replication set:
Теперь запускаем slon на новом узле, так же как и на остальных. Перезапускать slon на мастере не надо.
Репликация должна начаться как обычно.
Периодически, при добавлении новой машины в кластер возникает следующая ошибка: на новой ноде всё начинает жужжать и работать, имеющиеся же отваливаются с примерно следующей диагностикой:
Это означает что в служебной таблице _<имя кластера>.sl_path;, например _customers_rep.sl_path на уже имеющихся узлах отсутствует информация о новом узле. В данном случае, id нового узла 4, пара (1,4) в sl_path отсутствует.
Видимо, это баг Slony. Как избежать этого и последующих ручных вмешательств пока не ясно.
Чтобы это устранить, нужно выполнить на каждом из имеющихся узлов приблизительно следующий запрос (добавить путь, в данном случае (1,4)):
Если возникают затруднения, да и вообще для расширения кругозора можно посмотреть на служебные таблицы и их содержимое. Они не видны обычно и находятся в рамках пространства имён _<имя кластера>, например _customers_rep.
В процессе эксплуатации наблюдаю как со временем растёт нагрузка на master-сервере, в списке активных бекендов - постоянные SELECT-ы со слейвов. В pg_stat_activity видим примерно такие запросы:
Не забываем что _customers_rep - имя схемы из примера, у вас будет другое имя.
Таблица sl_event почему-то разрастается со временем, замедляя выполнение этих запросов до неприемлемого времени. Удаляем ненужные записи:
Производительность должна вернуться к изначальным значениям. Возможно имеет смысл почистить таблицы _customers_rep.sl_log_* где вместо звёздочки подставляются натуральные числа, по-видимому по количеству репликационных сетов, так что _customers_rep.sl_log_1 точно должна существовать.
Комментарии
не происходит синхронизация slave-сервера с мастером
Все сделано по этой инструкции, с поправкой на версию slony. Все прошло, все запустилось, но после запуска самого демона на обоих серверах, сами демоны работают, а синхронизации не происходит. В режиме отладки на консоль бесконечно пишется:
2012-09-17 01:51:57 JST DEBUG2 remoteWorkerThread_1: SYNC 5000002857 processing
2012-09-17 01:51:57 JST DEBUG1 remoteWorkerThread_1: no sets need syncing for this event
2012-09-17 01:51:59 JST DEBUG2 remoteListenThread_1: queue event 1,5000002858 SYNC
2012-09-17 01:51:59 JST DEBUG2 remoteWorkerThread_1: Received event #1 from 5000002858 type:SYNC
2012-09-17 01:51:59 JST DEBUG1 calc sync size - last time: 1 last length: 2002 ideal: 29 proposed size: 3
2012-09-17 01:51:59 JST DEBUG2 remoteWorkerThread_1: SYNC 5000002858 processing
2012-09-17 01:51:59 JST DEBUG1 remoteWorkerThread_1: no sets need syncing for this event
2012-09-17 01:52:00 JST CONFIG slon: child terminated signal: 9; pid: 27853, current worker pid: 27853
И за эти ничего больше не происходит. Может кто-то подскажет как это лечить и заставить слона работать?