Высокодоступный Postgres. Кластер Active/Standby со stream-репликацией между узлами. Реализация

Продолжение, начало здесь. Итак, как же я построил всю эту конструкцию? А вот так:

Краткое описание решения

Clipboard08

Тип кластера: active/standby

Кол-во узлов: 2

Репликация данных между узлами осуществляется средствами встроенной потоковой репликации Postgres, в асинхронном режиме.

Виртуальный IP адрес кластера (VIP), к которому подсоединяются клиенты, управляется кластерным ПО и всегда находится на том же узле кластера, на котором запущен postgres в режиме master.

Для определения состояния сетевой изоляции оба узла кластера пингуют внешний IP адрес: рекомендуется в качестве такого адреса использовать кластерный адрес NLB-кластера  серверов приложения (если он в той же подсети) либо адрес маршрутизатора по умолчанию.

Для передачи межузлового heartbeat используется протокол  UDPU через unicast.

Версии компонентов: ОС CentOS 6.6, СУБД Postgres 9.3, кластерное ПО —  corosync 1.4.7; cman 3.0.12;pacemaker 1.1.12, ресурсный агент pgsql RA (https://github.com/ClusterLabs/resource-agents/blob/master/heartbeat/pgsql)  по состоянию на 22.04.2015

Cкрипты и настроечные файлы: лежат здесь.

Установка

Операции 1 — 4 выполняются на основном и на резервном серверах.

  1. Установить CentOS 6.6 (я пользовался минимальным дистрибутивом)
  2. Обновить дистрибутив:

# yum update

и перезагрузить после обновления:

# reboot

  1. Отключить SELinux и IPtables:

# setenforce 0

и в файле /etc/selinux/config

SELINUX=enforcing заменить на SELINUX=disabled

# /etc/init.d/iptables stop

# chkconfig iptables off

  1. Удостовериться, что установлен верный часовой пояс:

# date

Sat Apr 18 08:41:57 PDT 2015

и, при необходимости, поправить:

# rm -f /etc/localtime

# ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime

# date

Sat Apr 18 18:44:15 MSK 2015

4.Рекомендуется

В файле /etc/host прописать IP адреса и имена основного и резервного хостов, например:

192.168.0.109 pg01 pg01.test.local

192.168.0.112 pg02 pg02.test.local

установить, настроить (вписать в случае необходимости локальные серверы времени в файл /etc/ntp.conf) и запустить сервис ntpd:

# yum install ntp

# service ntpd start

# chkconfig ntpd on

Операция 5 выполняется ТОЛЬКО НА ОСНОВНОМ СЕРВЕРЕ.

  1. Загрузить на сервер в каталог /root/depot файлы pgclsetup.sh pgclcontrol.sh cluster_config.crm pgsql

Запустить скрипт установки

# cd ~/depot

# chmod 755 pgclsetup.sh

# ./pgclsetup.sh <пароль пользователя postgres> <имя или адрес удаленного (резервного) сервера> <кластерный IP адрес, на который будут коннектиться клиенты>

В качестве последнего параметра рекомендуется использовать кластерный адрес кластера  серверов приложений (если они в той же подсети) либо адрес маршрутизатора по умолчанию.

например

# ./setup_cluster.sh password pg02 192.168.0.125 192.168.0.1

В процессе установки необходимо будет ввести пароль пользователя root резервного сервера.

Эксплуатация

1. Порядок включения-выключения

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

Включать — наоборот, сначала мастер, потом slave.

2. Проверка состояния кластера

/usr/bin/pgclcontrol.sh status

Пример вывода в штатном состоянии:

Online: [ pg01 pg02 ] - оба узла кластера должны быть в состоянии online

Full list of resources:

 Resource Group: master-group
     vip (ocf::heartbeat:IPaddr2):       Started pg01 - VIP должен находиться на том же узле, что 
                                                        и мастер и быть запущен
 Master/Slave Set: msPostgresql [postgresql]
     Masters: [ pg01 ]
     Slaves: [ pg02 ]

Node Attributes:
* Node pg01:
    + master-pgsql                      : 1000
    + pgsql-data-status                 : LATEST    
    + pgsql-master-baseline             : 0000000009000080
    + pgsql-status                      : PRI   - статус мастера должен быть PRI. Подробнее о статусах
                                                   - здесь.
* Node pg02:
    + master-pgsql                      : 100
    + pgsql-data-status                 : STREAMING|ASYNC   - состояние репликации
    + pgsql-status                      : HS:async -         - режим репликации

Подробности о режимах и состояниях репликации - здесь.

3. Перемещение роли мастер-сервера на другой хост:

Все операции производятся на хосте, с которого перемещается роль мастера.

  • убедиться, что репликация между серверами работает: /usr/bin/pgclcontrol.sh status
  • выполнить перемещение: /usr/bin/pgclcontrol.sh switchover

Ошибки и нештатные ситуации в ходе эксплуатации

1. Если по каким либо причинам отпал, на время вышел из строя или был восстановлен с резервной копии резервный сервер:

Все операции производятся на резервном сервере.

  •  убедиться, что основной сервер доступен и работает/usr/bin/pgclcontrol.sh status
  •  включить в кластер резервный сервер: /usr/bin/pgclcontrol.sh recovery
  •  проверить статус кластера /usr/bin/pgclcontrol.sh status
  •  проверить состояние postgres: tail -f /var/lib/pgsql/9.3/data/pg_log/postgresql-<день недели>.log

2. Если по каким либо причинам отпал, на время или полностью вышел из строя основной сервер:

  • (операция проводится на уцелевшем сервере) убедиться, что произошло переключение на резервный сервер и теперь резервный сервер является мастером: /usr/bin/pgclcontrol.sh status
  • восстановить вышедший из строя сервер с резервной копии, если нужно

Все операции производятся на восстановленном сервере.

  • превратить его  в резервный: /usr/bin/pgclcontrol.sh recovery
  • проверить статус кластера /usr/bin/pgclcontrol.sh status
  • проверить состояние postgres: tail -f /var/lib/pgsql/9.3/data/pg_log/postgresql-<день недели>.log

3. Если вышли из строя или отключались оба сервера одновременно, и после старта оба находятся в состоянии STOP:

  • на обоих хостах (последовательно) запустить /usr/bin/pgclcontrol.sh recovery
  • определить какой сервер стал резервным, проверить его состояние  /usr/bin/pgclcontrol.sh status
  • в случае необходимости, восстановить, запустив на нем /usr/bin/pgclcontrol.sh recovery
  • проверить статус кластера /usr/bin/pgclcontrol.sh status
  • проверить состояние postgres: tail -f /var/lib/pgsql/9.3/data/pg_log/postgresql-<день недели>.log

4. Если по каким-либо причинам потерян мастер и остался только slave в состоянии HS:alone

  • его нужно директивно назначить мастером: /usr/bin/pgclcontrol.sh setlocalhostasmaster

5. Если по каким-либо причинам полностью потерян slave (например, было проведено восстановление согласно предыдущему пункту), то чтобы добавить новый slave в кластер, необходимо

  • установить сервер с настройками, идентичными потерянному (имя, IP адрес)
  • загрузить на сервер в каталог /root/depot файлы pgclsetup_slave.sh pgclcontrol.sh cluster_config.crm pgsql
  • запустить скрипт установки

# cd ~/depot

# chmod 755 pgclsetup_slave.sh

# ./pgclsetup_slave.sh  <пароль пользователя postgres> <имя или адрес удаленного мастер сервера>

В процессе установки необходимо будет ввести пароль пользователя root мастера.

6. Перенос БД со standalone-сервера на кластер

  • установить кластер стандартным способом (пароль пользователя postgres должен совпадать с паролем на сервере-источнике);
  • остановить обе ноды кластера: /usr/bin/pgclcontrol.sh stop
  • удалить на обоих нодах кластера файлы блокировки: rm -f /var/lib/pgsql/9.3/tmpdir/PGSQL.lock

Следующие действия выполняются на сервере-источнике!

  • вставить строку  «host replication postgres IP-адрес-хоста-приемника/32 trust» в файл pg_hba.conf сразу после закомментированных строк

IP-адрес-хоста-приемника — IP адрес хоста, на который будет скопирована база (см след шаг). Для postgres 9.3 на centos 6 файл pg_hba.conf расположен в каталоге /var/lib/pgsql/9.3/data/

  • отредактировать файл postgresql.conf (для postgres 9.3 на centos 6 файл pg_hba.conf расположен в каталоге /var/lib/pgsql/9.3/data/), раскомментировав и заменив в нем

#wal_level = minimal на  wal_level = hot_standby,

#max_wal_senders = 0 на max_wal_senders = 5 и

#wal_keep_segments = 0 на wal_keep_segments = 32

  • перезапустить  postgres, для postgres 9.3, на centos 6 команда на перезапуск будет: service postgresql-9.3 restart

Следующие действия выполняются на одной (любой) ноде кластера!

  • скопировать файл БД: /usr/bin/pgclcontrol.sh recoveryfrom <Имя-или-IP-адрес-сервер-источника>, например /usr/bin/pgclcontrol.sh recoveryfrom 10.0.0.5
  • в случае необходимости ноду нужно директивно назначить мастером: /usr/bin/pgclcontrol.sh setlocalhostasmaster

Следующие действия выполняются на второй ноде кластера!

  • запустить ноду в режиме восстановления с мастера: /usr/bin/pgclcontrol.sh recovery

Вот и все, собственно. Осталось только еще раз (на всякий случай) дать ссылку на упомянутые выше скрипты и настроечные файлы: вот они

и рассказать про

Источники вдохновения

Реклама

13 thoughts on “Высокодоступный Postgres. Кластер Active/Standby со stream-репликацией между узлами. Реализация

  1. Уведомление: Postres HA, две площадки, разные IP сети | Системная архитектура и все-все-все

  2. Уведомление: PostgreSQL — репликация, ссылки | Pilat66 blog

    • Попробуйте перекачать, м.б. просто скачался не полностью. Сам файл на dropbox — норм, не битый. Только что проверил.

  3. Добрый день. Огромная благодарность за такой материал и скрипты. Все отлично работает на centos 6.7 и PG 9.3. Возникло пару вопросов. Если можете, дайте ответ. Вопрос №1 — Пробовал изменить скрипты для работы с PG 9.4 и 9.5. После запуска скрипта установка проходит нормально, а вот кластер запускается с ошибками unknown error. Может я что-то неправильно указываю в скрипте. Есть ли у Вас скрипт для PG 9.4 или PG 9.5?
    Вопрос №2 — В процессе тестирования выключал мастер-ноду все красиво переходило на слэйв и работало дальше. А вот после включения старого мастера я так понимаю руками на нем надо запустить /usr/bin/pgclcontrol.sh recovery? Иначе автоматом он в кластер не добавляется. Можно ли этот процесс как-то автоматизировать?
    Вопрос №3 — Если мне надо изменить IP адреса у всего кластера включая VIPs, где эти параметры можно подправить в конфиг файлах?
    Заранее благодарю за ответы.

    • Добрый день, рад, что пригодилось.
      1. Скриптов для для PG 9.4 или PG 9.5 не писал. Возможно, что нужна новая версия pgsql RA.
      2. Можно, но не желательно. Ситуации всякие бывают и с такой автоматизацией можно запросто уйти в восстановление всей базы с резервных копий.
      3. Самое простое — crm configure edit
      Конфигурация откроется в текстовом редакторе, там поредактировать в двух местах
      primitive pgvip ocf:heartbeat:IPaddr2 \
      params \
      ip=»Новый IP» \

      primitive postgresql ocf:heartbeat:pgsql \
      params \

      master_ip=»Новый IP» \

      И записать. Для уверенности можно рестартовать кластер.

  4. Добрый день. Подскажите, как в уже установленный кластер добавить еще одну ноду? Благодарю за ответ

    • Добавить можно, только зачем?;) Опять же, совсем не уверен, что ресурсный агент pg с такой конфигурацией будет работать.
      Если все же очень хочется, то можете попробовать на тестовой системе:
      1. Уточнить имя добавляемого узла, выполнив на нем uname -n
      2. Убедиться что записи для всех узлов присутствуют на всех узлах в файле /etc/hosts
      3. Добавить описание нового узла в /etc/corosync/corosync.conf
      Скопировать файл на все узлы
      4. На мастер-узле выполнить
      ccs -f /etc/cluster/cluster.conf —addnode Имя_Нового_Узла
      ccs -f /etc/cluster/cluster.conf —addmethod pcmk-redirect Имя_Нового_Узла
      ccs -f /etc/cluster/cluster.conf —addfenceinst pcmk Имя_Нового_Узла pcmk-redirect port=Имя_Нового_Узла
      5. На добавляемом узле выполнить pgclsetup_slave.sh

      Но, повторюсь, шанс, что трехузловой кластер заработает невелик.

  5. Благодарю за все ответы.

    Доделал немного скрипт, получилось установить PG 9.4. И вот с чем столкнулся — Кластер собирается, все шаги проходит, а после запуска получаем следующую картину:

    Нода с которой запускались скрипты:

    * Node pg1.domain.local:
    + default_ping_set : 100
    + master-postgresql : 1000
    + postgresql-data-status : LATEST
    + postgresql-master-baseline : 0000000003000090
    + postgresql-status : PRI

    Вторая нода:
    * Node pg2.domain.local:
    + default_ping_set : 100
    + postgresql-data-status : DISCONNECT

    Failed actions:
    postgresql_stop_0 on pg2.domain.local ‘invalid parameter’ (2): call=33, status=complete,

    Если можете, помогите разобраться? Куда выслать скрипты?

  6. Спасибо за интересный материал! Обдумываю сейчас похожую архитектуру для отказоустойчивого zabbix сервера. Вы случайно не знаете, возможно ли использовать streaming replication вместе с partitioning? В документации пока не нашёл ответа.

  7. crm(live)# status

    Failed actions:
    postgresql_monitor_2000 on test-pr-nn-001 ‘not running’ (7): call=53, status=complete, last-rc-change=’Mon Jul 25 17:40:12 2016′, queued=0ms, exec=154ms

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

w

Connecting to %s