Репликации баз данных PostgreSQL при помощи SkyTools Londiste

Исходный код SkyTools был размещен на Pgfoundry, а теперь на GitHub, технический руководитель - Марко Крин.

Список других вариантов настройки репликации баз данных PostgreSQL.

Londiste асинхронная Master-Slave Что такое репликация баз данных из состава утилит Skytools для сервера Использование и настройка PostgreSQL.

Принцип работы. Londiste базируется на механизме очередей PgQ, который входит в пакет SkyTools. Информация об изменениях данных попадает в эти очереди из специальных триггеров, навешиваемых на реплицируемые таблицы. PgQ, в свою очередь, основывается на пакетной обработке и использует утилиту (демон) ticker, генерирующую события готовности пачек данных. Эти события слушает демон Londiste и по их наступлению переносит пачки с мастера на слейв.

Задача. Настройка синхронизации (репликации) между двумя серверами PostgreSQL в режиме Master-Slave (Master реплицирует данные на Slave).

  1. Сервер (IP 10.161.85.55) Fedora 13 2.6.34.9-69.fc13.x86_64; PostgreSQL 8.4.8 - настраиваем как Master. БД mbill.
  2. Сервер (IP 10.161.85.109) Fedora 14 2.6.35.14-106.fc14.x86_64; PostgreSQL 8.4.9 - настраиваем как Slave. БД mbillcz5054.

Решение.

  1. Установим дополнительные библиотеки и pg_config
    # yum install slang-devel glib2-devel gcc.x86_64 make.x86_64 postgresql-devel.x86_64 zlib-devel.x86_64 -y
  2. Устанавливаем на обоих серверах Python-2.5. После чего в системе будет присутствовать две версии Синтаксис Python - наша и установленная из репозиториев дистрибутива (Fedora 13 - Python 2.6.4; Fedora 14 - Python 2.7).
    # python --version
    Python 2.7
    # tar xvf Python-2.5.tgz
    # cd Python-2.5
    # ./configure # для Fedora 13
    # ./configure --with-zlib=/usr/include # для Fedora 14 так как Pyton 2.5 не мог самостоятельно найти модуль zlib в /usr/include
    # make
    # make install
    # /usr/local/bin/python --version
    Python 2.5
  3. Устанавливаем пакет Skytools-2.1.12
    # tar -xvf skytools-2.1.12.tar.gz
    # cd skytools-2.1.12
    # ./configure --with-python=/usr/local/bin/python2.5 --with-pgconfig=/usr/bin/pg_config
    # make
    # make install
  4. Устанавливаем пакет Psycopg psycopg2-2.4.2
    # tar -xvf psycopg2-2.4.2.tar.gz
    # cd psycopg2-2.4.2
    # /usr/local/bin/python2.5 setup.py build
    # /usr/local/bin/python2.5 setup.py install
    Writing /usr/local/lib/python2.5/site-packages/psycopg2-2.4.2-py2.5.egg-info
  5. Необходимое программное обеспечение установлено. Далее непосредственно настройка репликации.
  6. Разрешим доверительный(без пароля) доступ между базами серверов. Все утилиты будут работать под системным пользователем postgres. Операции с БД будет выполнять одноименный пользователь postgres из Использование и настройка PostgreSQL. На Master- сервере добавим строку в pg_hba.conf
    # nano /var/lib/pgsql/data/pg_hba.conf
    # TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
    host    mbillcz5054   postgres   10.161.85.109/32      trust
     
    # /etc/init.d/postgresql reload

    На Slave- сервере добавим строку в pg_hba.conf

    # nano /etc/postgresql/8.3/main/pg_hba.conf
    # TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
    host    mbillcz5054         postgres   10.161.85.55/32      trust
    
    # /etc/init.d/postgresql reload

    В этом случае реплицируются только БД mbill в БД mbillcz5054, если нужно реплицировать все БД в колонке DATABASE указываем all. После reload, должна выполняться команда с мастера - подключение к слейву

    # psql -h 10.161.85.109 -U postgres -d mbillcz5054
  7. Настраиваем postgresql.conf на Master и Slave (примеры настроек лежат в директории skytools-2.1.12/tests/walmgr/). Оставил по умолчанию, ничего не менял:
    listen_addresses = '*'
    port = 5432                             # (change requires restart)
    max_connections = 100                   # (change requires restart)
    #superuser_reserved_connections = 3     # (change requires restart)
    #unix_socket_directory = ''             # (change requires restart)
    #unix_socket_group = ''                 # (change requires restart)
    #unix_socket_permissions = 0777         # begin with 0 to use octal notation
    #ssl = off                              # (change requires restart)
  8. Настройка ticker на стороне Master. Создадим файл конфигурации для БД mbill (можно взять из примеров и отредактировать). Подобные конфигурации нужно создавать для каждой реплицируемой базы данных. Права чтения/записи для пользователя postgres на директорию.
    # mkdir /etc/skytools
    # mv pgqadm.ini mbill-ticker.ini
    # nano /etc/skytools/mbill-ticker.ini
    # mkdir /var/log/skytools/
    # mkdir /var/run/skytools
    # chown -R postgres:postgres /etc/skytools
    # chown -R postgres:postgres /var/log/skytools
    # chown -R postgres:postgres /var/run/skytools
    # nano mbill-ticker.ini
    [pgqadm]
    job_name = mbill-ticker
    db = dbname=mbill
    
    # Задержка между запусками обслуживания (ротация очередей и т.п.)
    # how often to run maintenance [minutes]
    maint_delay_min = 5
    
    # Задержка между проверками наличия активности (новых пакетов данных) в секундах
    # how often to check for activity [secs]
    loop_delay = 0.1
    
    logfile = /var/log/skytools/%(job_name)s.log
    pidfile = /var/run/skytools/%(job_name)s.pid
    
    use_skylog = 0
  9. Теперь необходимо инсталлировать служебный код (SQL) и запустить ticker как демона (ключ -d) для каждой из БД. Делается это с помощью утилиты pgqadm.py от пользователя postgres:
    # sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/pgqadm.py /etc/skytools/mbill-ticker.ini install
    2012-03-22 09:36:51,800 27555 INFO plpgsql is installed
    2012-03-22 09:36:51,807 27555 INFO txid_current_snapshot is installed
    2012-03-22 09:36:51,807 27555 INFO Installing pgq
    2012-03-22 09:36:51,808 27555 INFO   Reading from /usr/local/share/skytools/pgq.sql
    # sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/pgqadm.py /etc/skytools/mbill-ticker.ini ticker -d

    Проверим лог /var/log/skytools/mbill-ticker.ini.log на ошибки или запросом

    # sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/pgqadm.py /etc/skytools/mbill-ticker.ini status
  10. Настройка Slave. Londiste должен быть остановлен. Теперь нужно создать БД mbillcz5054 на Slave в которую будет происходить репликация БД mbill. Для этого выкачаем схему БД mbill на Master и воссоздадим ее на Slave c новым именем БД mbillcz5054
    # sudo -u postgres pg_dump -s mbill > mbill_schema.sql # на Master сервере
    # sudo -u postgres createdb mbillcz5054 # на Slave сервере
    # sudo -u postgres psql mbillcz5054 < mbill_schema.sql  # на Slave сервере
  11. Создаём конфигурацию репликатора на Master и Slave (файлы отличаются названием БД). Для каждой из реплицируемых баз создадим конфигурационные файлы:
    # cp londiste.ini mbill-londiste.ini
    # nano /etc/skytools/mbill-londiste.ini
    [londiste]
    # MASTER
    job_name = mbill-londiste
    provider_db = dbname=mbill port=5432 host=127.0.0.1
    subscriber_db = dbname=mbillcz5054 port=5432 host=10.161.85.67
    pgq_queue_name = mbill-londiste-queue
    
    logfile = /var/log/skytools/%(job_name)s.log
    pidfile = /var/run/skytools/%(job_name)s.pid
    log_size = 5242880
    log_count = 3
    pgq_lazy_fetch = 500 # указывает не брать более 500 событий в один пакет запросов, этим контролируется использование ЦП и ОЗУ
    
    #loop_delay = 1
    #lock_timeout = 10.0
    [londiste]
    # SLAVE
    job_name = mbill-londiste
    provider_db = dbname=mbill port=5432 host=10.161.85.54
    subscriber_db = dbname=mbillcz5054 port=5432 host=127.0.0.1
    pgq_queue_name = mbill-londiste-queue
    
    logfile = /var/log/skytools/%(job_name)s.log
    pidfile = /var/run/skytools/%(job_name)s.pid
    log_size = 5242880
    log_count = 3
    
    #loop_delay = 1
    # max locking time on provider (in seconds, float)
    lock_timeout = 100
  12. Устанавливаем Londiste в базы на Маster и Slave. Теперь необходимо установить служебный SQL для каждой из созданных в предыдущем пункте конфигураций. Устанавливаем код на стороне мастера:
    # sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini provider install

    и подобным образом на стороне слейва:

    # sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber install

    После этого пункта на мастере будут созданы очереди для репликации.

  13. Запускаем процессы Londiste на Маster для каждой реплицируемой базы делаем:
    # sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini replay -d

    Таким образом запустятся слушатели очередей репликации, но, т.к. мы ещё не указывали какие таблицы хотим реплицировать, они пока будут работать в холостую. Убедимся что в логах нет ошибок (/var/log/skytools/db1-londistes.log). Добавляем реплицируемые таблицы. Для каждой конфигурации указываем что будем реплицировать с мастера:

    # sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini provider add --all

    и что со слейва:

    # sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber add --all

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

  14. Добавляем реплицируемые последовательности (sequence). Так же для всех конфигураций. Для мастера:
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini provider add-seq --all

    Для слейва:

    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber add-seq --all

    Точно также как и с таблицами можно указать конкретные последовательности вместо –all.

  15. Проверяем на Master должно быть запущено два процесса, на Slave ни одного:
    # ps -ef | grep sky
    postgres  6645     1  0 17:54 ?        00:00:09 /usr/local/bin/python2.5 /usr/local/bin/pgqadm.py /etc/skytools/mbill-ticker.ini ticker -d
    postgres 10840     1  0 19:36 ?        00:00:00 /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini replay -v -d
  16. Проверяем на каком этапе находится синхронизация таблиц. Состояние OK сообщает, что синхронизация таблицы nases завершена.
    # sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber tables
    Table                                           State
    public.nases                                       ok
  • Запустить SkyTools (ticker и Londiste)
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/pgqadm.py /etc/skytools/mbill-ticker.ini ticker -d
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini replay -d
  • Остановить SkyTools (Londiste и ticker)
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini -s
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/pgqadm.py /etc/skytools/mbill-ticker.ini ticker -s
  • Посмотреть состояние репликации. Данные уже синхронизированы для тех таблиц, где статус отображается как "ok".
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber tables
  • Просмотреть добавленные последовательности
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini provider seqs
    или
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber seqs
  • Master добавление одиночной таблицы и ее последовательности
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini provider add nases
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini provider add-seq nases_id_seq
  • Slave добавление одиночной таблицы и ее последовательности
    sudo -u postgres /usr/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber add nases
    sudo -u postgres /usr/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber add-seq nases_id_seq
  • Slave удаление всех таблиц и и их sequence
    sudo -u postgres /usr/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber remove-seq --all
    sudo -u postgres /usr/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini subscriber remove --all
  • Время отставание репликации. Запрос выполняется на Master. В столбце lag показывается время отставания от мастера в синхронизации, last_seen - время последнего запроса от слейва.
    select queue_name, consumer_name, lag, last_seen from pgq.get_consumer_info();
    или из командной строки
    sudo -u postgres psql -d mbillcz5054 --command="select queue_name, consumer_name, lag, last_seen from pgq.get_consumer_info()"
  • Посмотреть состояние ticker
    sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/pgqadm.py /etc/skytools/mbill-ticker.ini status

Если в логе Londiste появились ошибки можно попробовать сбросить очереди:

sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini replay --reset

Для более точного определения ошибок можно запустить Londiste в дебаговом режиме

sudo -u postgres /usr/local/bin/python2.5 /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini replay -v

Для полного удаление SkyTools 2.1.12 нужно выполнить:

Остановить Londiste
sudo -u postgres /usr/local/bin/python /usr/local/bin/londiste.py -s /etc/skytools/mbill-londiste.ini
Остановить ticker
sudo -u postgres /usr/local/bin/python /usr/local/bin/pgqadm.py -s /etc/skytools/mbill-ticker.ini
Удалить sequence (последовательности)
sudo -u postgres /usr/local/bin/python /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini provider remove-seq --all
Удаляем реплицируемые таблицы
sudo -u postgres /usr/local/bin/python /usr/local/bin/londiste.py /etc/skytools/mbill-londiste.ini provider remove --all

Удаляем схему pgg (schema pgq)

drop schema if exists pgq cascade;

Удаляем схему londiste (schema londiste)

drop type if exists ret_provider_table_list cascade;
drop schema if exists londiste cascade;

И соответственно вручную удалить бинарные файлы из /usr/local/bin.

PQ VPS сервера в 28+ странах.