Инструкция содержит подробное пошаговое описание процесса настройки репликации на основе Londiste, системы асинхронной мастер-слэйв репликации из пакета SkyTools от Skype.Допустим есть 2 сервера - host1 и host2. На host1 работает кластер с одной или несколькими базами, которые необходимо реплицировать на host2. Другими словами host1 будет мастером, а host2 слейвом.
Прежде всего необходимо установить пакет SkyTools. Его исходники можно найти на официальном сайте проекта http://developer.skype.com/SkypeGarage/DbProjects/SkyTools или в wiki http://wiki.postgresql.org/wiki/Skytools . Там же найдёте всю документацию и ссылки на дополнительные материалы. Советую обращаться к ним если захотите узнать дополнительные подробности о вещах, которых я буду в данной статье касаться поверхностно.
Итак, всё ПО необходимое для репликации установлено, но, прежде чем начать настройку, хочу рассказать о принципах работы Londiste в очень общих словах.
Londiste базируется на механизме очередей PgQ, который тоже входит в пакет SkyTools. Информация об изменениях данных попадает в эти очереди из спец-триггеров, навешиваемых на реплицируемые таблицы. PgQ, в свою очередь, основывается на пакетной обработке и использует так называемый ticker, утилиту (демон), генерирующую события готовности пачек данных. Эти события слушает демон Londiste и по их наступлению переносит пачки с мастера на слейв.
Репликация на базе Londiste может работать по схеме - один мастер на несколько слейвов. В связи с этим я буду делать пометки, различающие установку репликации первого слейва и последующих. Также я буду различать репликацию отдельной базы и кластера целиком.
Описанный процесс не требует даунтайма.
Замечание: В данном описании будут часто встречаются обобщения более узких ситуаций, которые не тестировались во всех возможных вариантах. Так что прежде чем внедрять её в продакшн, тщательно протестируйте ваш процесс. Если вы найдёте какую-нибудь ошибку или не рабочую ситуацию, буду благодарен если сообщите.
++ 1. Первым делом подготовим мастер-сервер
1.1. Права на мастере
В данном примере все утилиты будут работать под системным пользователем postgres. Операции с БД я доверю также пользователю postgres (который в базе). Но в реальности будет правильнее сделать отдельного пользователя для этих утилит, смотрите по вашей ситуации.
Дадим пользователю postgres доверительный доступ (без пароля) к базам на мастере со слейва.
/var/lib/postgres/8.4/data/pg_hba.conf:
...
# TYPE DATABASE USER CIDR-ADDRESS METHOD
# host2 IP
host db1 postgres 192.168.10.2/32 trust
.. .
Если реплицируются конкретные базы, а не весь комплект, то добавьте такие записи для каждой из них. В случае же репликации всех БД достаточно одной записи, где в колонке DATABASE указываем all. Не забудьте сделать reload серверу.
++ 1.2. Настрока ticker-а
Далее создадим файл конфигурации ticker-а.
/etc/skytools/db1-ticker.ini:
[pgqadm]
job_name = db1-ticker
db = dbname=db1
# Задержка между запусками обслуживания (ротация очередей и т.п.) в секундах
maint_delay = 600
# Задержка между проверками наличия активности (новых пакетов данных) в секундах
loop_delay = 0.1
logfile = /var/log/skytools/%(job_name)s.log
pidfile = /var/run/skytools/%(job_name)s.pid
Создайте подобные конфигурации для каждой реплицируемой базы.
++ 1.3. Запускаем ticker
Теперь необходимо инсталлировать служебный код (SQL) и запустить ticker как демона для каждой из баз. Делается это с помощью утилиты pgqadm.py следующими командами:
python pgqadm.py /etc/skytools/db1-ticker.ini install
python pgqadm.py /etc/skytools/db1-ticker.ini ticker -d
Проверим, что в логах (/var/log/skytools/db1-tickers.log) всё нормально. На данном этапе там должны быть редкие записи (раз в минуту).
++ 2. Далее настроим слейв
2.1. Убедимся что Londiste остановлен
python londiste.py -s /etc/skytools/db1-londiste.ini
Повторите для всех реплицируемых баз.
++ 2.2. Востанавливаем схему базы
Замечание: В данном примере подразумевается что целевая система не содержит баз с такими же именами как у реплицируемых.
Если реплицируются отдельные базы, то прежде всего необходимо создать пользователей, идентичных тем, которые работали с ними на мастере. Далее переносим схемы этих баз на слейв (повторяем для каждой):
pg_dump -s -C -h host1 -U postgres db1 |
psql -U postgres 1>db1-restore.stdout 2>db2-restore.stderr
Если реплицируем все базы целиком, то достаточно один раз сделать так:
pg_dumpall -s -h host1 -U postgres |
psql -U postgres 1>all-restore.stdout 2>all-restore.stderr
Убедимся, что в лог-файлах *-restore.stderr отсутствуют ошибки кроме "роль postgres уже существует" (ч.г. не могу понять для чего вообще pg_dumpall дампит эту роль).
++ 2.3. Создаём конфигурацию репликатора
Для каждой из реплицируемых баз создадим конфигурационные файлы:
/etc/skytools/db1-londiste.ini:
[londiste]
job_name = db1-londiste
provider_db = dbname=db1 port=5432 host=host1
subscriber_db = dbname=db1
# Это будет использоваться в качестве SQL-идентификатора, т.ч. не используйте
# точки и пробелы.
# ВАЖНО! Если есть живая репликация на другой слейв, именуем очередь так-же
pgq_queue_name = db1-londiste-queue
logfile = /var/log/skytools/%(job_name)s.log
pidfile = /var/run/skytools/%(job_name)s.pid
log_size = 5242880
log_count = 3
++ 2.4. Устанавливаем Londiste в базы на мастере и слейве
Теперь необходимо установить служебный SQL для каждой из созданных в предыдущем пункте конфигураций.
Устанавливаем код на стороне мастера:
python londiste.py /etc/skytools/db1-londiste.ini provider install
и подобным образом на стороне слейва:
python londiste.py /etc/skytools/db1-londiste.ini subscriber install
После этого пункта на мастере будут созданы очереди для репликации.
++ 2.5. Запускаем процессы Londiste
Для каждой реплицируемой базы делаем:
python londiste.py /etc/skytools/db1-londiste.ini replay -d
Таким образом запустятся слушатели очередей репликации, но, т.к. мы ещё не указывали какие таблицы хотим реплицировать, они пока будут работать в холостую.
Убедимся что в логах нет ошибок (/var/log/skytools/db1-londistes.log).
++ 2.6. Добавляем реплицируемые таблицы
Для каждой конфигурации указываем что будем реплицировать с мастера:
python londiste.py /etc/skytools/db1-londiste.ini provider add --all
и что со слейва:
python londiste.py /etc/skytools/db1-londiste.ini subscriber add --all
В данном примере я использую спец-параметр --all, который означает все таблицы, но вместо него вы можете перечислить список конкретных таблиц, если не хотите реплицировать все.
++ 2.7. Добавляем реплицируемые последовательности (sequence)
Так же для всех конфигураций.
Для мастера:
python londiste.py /etc/skytools/db1-londiste.ini provider add-seq --all
Замечание: В версиях SkyTools до 2.1.9 включительно была обнаружена ошибка при добавлением последовательностей на мастере используя параметр --all, т.ч. если у вас такая версия используйте следующий хак:
for seq in $(
psql -t -A -U postgres toozla -c "\ds" |
awk -F '|' '{ if ($1 != "pgq" && $1 != "londiste") { print $1"."$2 } }');
do
python londiste.py /etc/skytools/db1-londiste.ini provider add-seq $seq;
done
Для слейва:
python londiste.py /etc/skytools/db1-londiste.ini subscriber add-seq --all
Точно также как и с таблицами можно указать конкретные последовательности вместо --all.
++ 2.8. Проверка
Итак, всё что надо сделано. Теперь Londiste запустит так называемый bulk copy процесс, который массово (с помощью COPY) зальёт присутствующие на момент добавления таблиц данные на слейв, а затем перейдёт в состояние обычной репликации.
Мониторим логи на предмет ошибок:
less /var/log/skytools/db1-londiste.log
Если всё хорошо, смотрим состояние репликации. Данные уже синхронизированы для тех таблиц, где статус отображается как "ok".
python londiste.py /etc/skytools/db1-londiste.ini subscriber tables
Table State
public.table1 ok
public.table2 ok
public.table3 in-copy
public.table4 -
public.table5 -
public.table6 -
...
Для удобства представляю следующий трюк с уведомление в почту об окончании первоначального копирования (мыло поменять на своё ;):
(
while [ $(
python londiste.py /etc/skytools/db1-londiste.ini subscriber tables |
tail -n+2 | awk '{print $2}' | grep -v ok | wc -l) -ne 0 ];
do sleep 60; done; echo '' | mail -s 'Replication done EOM' user@domain.com
) &
Ссылки на публикации, которые мне помогли в написании этой статьи:
SkyTools - PostgreSQL Wiki http://wiki.postgresql.org/wiki/Skytools
SkyTools - Skype Developer Zone https://developer.skype.com/SkypeGarage/DbProjects/SkyTools
PostgreSQL master slave(s) asynchronous replication - tail -f /dev/dim http://tapoueh.org/skytools.html
URL: http://gray-hemp.blogspot.com/2010/04/londiste.html
Обсуждается: http://www.opennet.me/tips/info/2364.shtml