Небольшая хаутушечка по настройке pgpool-кластера с steaming replication postgres.
1. Подготовка посгреса.
Необходимо настроить потоковую репликацию.
Первым делом необходимо настроить авторизацию юзера postgres на машинах кластера по ssh-ключам без пароля (причем, не забыть про коннект по ssh к самому себе). ssh-keygen и ssh-copy-id в помощь.
Конфиг postgresql.conf лучше иметь одинаковый (за исключением директивы archive_command), что на мастере, что на слейве - так удобнее и проще, тоже самое касается каталогов с базой и архивлогами.
Добавляем директивы:
hot_standby = on // указывает что слейв будет в одноименном режиме, т.е. с него возможны селекты; на мастере она игнорируется
wal_level = hot_standby // директива для мастера, указывает режим репликации; на слейве игнорируется
max_wal_senders = 4 // число процессов репликации, должно быть не меньше числа слейвов
wal_keep_segments = 12 // сколько хранить wal-логов, если число будет слишком маленьким - слейв не сможет засинхронизироваться после длительного оффлайна
archive_mode = on // дополнение к потоковой репликации, ускоряет синхронизацию после длительного оффлайна
archive_command = 'rsync -aq %p <slave-name>:/somedir/archive/%f' // команда для отправки файликов архив-логов. единственный параметр, который будет различаться на мастере и слейве (мастер указывает на слейв, слейв на мастер)
Кроме того, listen_address не должен быть localhost, иначе слейв не сможет подключиться (извращения со слейвом на том же хосте опустим), а так же необходимо настроить pg_hba.conf для разрешения подключения replication-юзера, что-то вроде такого:
host replication postgres 192.168.1.0/24 trust
После этого запускаем мастер-сервер. Готовим слейв.
Проще всего сделать pg_basebackup с работающего мастера, указать в archive_command хостнейм мастера и добавить файлик recovery.conf:
standby_mode='on'
primary_conninfo='host=master port=5432 user=postgres' // реквизиты подключения к мастеру
trigger_file='/somedir/trigger_file' // путь до триггер-файла. при его появлении посгрес будет считать что мастер сдох и нужно самому становиться мастером
restore_command='cp /somedir/archive/%f %p' // команда для применения архивлогов
archive_cleanup_command='/usr/pgsql-9.2/bin/pg_archivecleanup /somedir/archive %r' // очистка примененных архивлогов
После этого можно можно запускать слейва, он должен успешно подключиться к мастеру и войти в режим hot_standby.
2. Настройка pgpool
Поставить pgpool под rhel/centos можно из пакетов, так что про традиционное для подобных хаутушечек configure&&make&&make install можно забыть.
Правим pgpool.conf:
backend_hostname0 = 'hostname'
backend_port0 = 5432
backend_weight0 = 1
backend_data_directory0 = '/opt/pgsql/9.2/data'
backend_flag0 = 'ALLOW_TO_FAILOVER'
Такими директивами (с увеличением порядкового номера) описываются все ноды кластера.
Включаем авторизацию через pgpool:
enable_pool_hba = on
authentication_timeout = 60
pool_passwd = 'pool_passwd' #имя файлика с юзерами/паролями в каталоге /etc/pgpool-II
Для авторизации по паролям через pgpool необходимо чтобы юзер и пароль совпадали, что в pgpool-е, что в посгресе, тип авторизации в посгресе должен быть md5. Например, создаем юзера "root" с паролем "qwerty":
createuser -lP root
в pg_hba.conf добавляем
host all root pgpool-host-ip md5
pg_md5 -u root -p
вывод добавляем в pool_passwd, права на файл должны позволять юзеру postgres его прочитать.
Возвращаемся к pgpool.conf:
load_balance_mode = on # включаем балансировку нагрузки - селекты смогут выполняться в т.ч. на слейве
master_slave_mode = on
master_slave_sub_mode = 'stream' # включаем streaming replication
sr_check_period = 10 # период проверки репликации
sr_check_user = 'root' # реквизиты для проверки репликации
sr_check_password = 'qwerty'
health_check_period = 5 # проверка доступности нод
health_check_timeout = 10
health_check_user = 'root' # реквизиты для проверки
health_check_password = 'qwerty'
failover_command = '/opt/pgsql/failover.sh %d %P %H %R' # самое важное - команда для файловера, будет исполняться при падении какой-либо из нод
Скрипт файловера довольно простой: если упал слейв - не делать ничего, если мастер - создать триггер-файл на слейве. А чтобы все это получилось - ssh-ключики и создавались.
#!/bin/bash
failed_id=$1
old_primary_id=$2
new_master_host_name=$3
new_database_path=$4
trigger=trigger_file
if [ $failed_id = $old_primary_id ];then # master failed
ssh $new_master_host_name touch $new_database_path/$trigger # let standby take over
fi
На этом минимум - закончен. pgpool сможет обслуживать соединения, отслеживать состояния нод и промоутить слейва в случае падения мастера.
Остается решить вопрос с рекавери - восстановлением работы упавшей ноды. Для этого есть 2 варианта:
восстанавливать ноду ручками (т.е. без участия pgpool-а) и давать pgpool-у команду на присоединение ноды
настроить online-recovery в pgpool-е, но все равно восстанавливать ручками :D хотя бы потому, что команду на восстановление придется все же давать руками (через консоль или модный pgpoolAdmin)
Первый вариант довольно прост и по-сути полностью повторяет официальный посгресовый гайд: сделать бейсбэкап с работающего мастера, создать recovery.conf и запустить ноду как слейв. Это все можно оформить в удобный скрипт:
#!/bin/bash
cluster_master=$1
recovery_host=$2
recovery_dir=$3
psql -h $cluster_master -c "SELECT pg_start_backup('Streaming Replication', true)" postgres
rsync -C -a -c --delete --exclude postgresql.conf --exclude postmaster.pid \
--exclude postmaster.opts --exclude pg_log \
--exclude recovery.conf --exclude recovery.done \
--exclude pg_xlog \
$recovery_dir/ $recovery_host:$recovery_dir/
psql -h $cluster_master -c "SELECT pg_stop_backup()" postgres
ssh $recovery_host "mkdir $recovery_dir/pg_xlog; chmod 700 $recovery_dir/pg_xlog"
rec=`mktemp`
cat > $rec << EOF
standby_mode='on'
primary_conninfo='host=$cluster_master port=5432 user=postgres'
trigger_file='$recovery_dir/trigger_file'
restore_command='cp /opt/pgsql/archive/%f %p'
archive_cleanup_command='/usr/pgsql-9.2/bin/pg_archivecleanup /opt/pgsql/archive %r'
EOF
scp $rec $recovery_host:$recovery_dir/recovery.conf
rm -f $rec
ssh $recovery_host sed -i "s/slave-hostname/$cluster_master/g" $recovery_dir/postgresql.conf
Соответственно алгоритм восстановления по этому варианту таков:
Запустить скрипт с работающего мастера, указать хостнеймы мастера, восстанавливаемого слейва и каталог pg_data. Он подготовит слейв
Запустить слейв. Если нигде ничего не напутано - он успешно подключится к мастеру и начнет работать хот-стендбаем.
Дать команду пгпулу на присоединение ноды: pcp_attach_node timeout hostname port# username password nodeID. nodeID восстанавливаемой ноды можно увидеть из вывода pcp_pool_status.
После этого нода будет вновь доступна в пгпуле.
Второй вариант - online-recovery в pgpool.
Механизм работы пгпула в этом варианте несколько неочевиден. В отличие от fileover и прочих функций - рекавери запускается не напрямую скриптом, а через вызов посгресовых функций pgpool_recovery и pgpool_remote_start, которые уже вызывают непосредственные скрипты (нафига такой изврат??!). Соответственно, чтобы все это работало - в посгрес должны быть загружены эти функции (в базу postgres и template), а для загрузки этих функций необходима шаред-библиотека под посгрес pgpool-recovery.so.
После добавления пгпуловских фукнций в посгрес нужно создать 2 скрипта в каталоге $pg_data: pgpool_remote_start (именно с таким названием!) и recover-online (тут уже название произвольное).
Первый скрипт, как видно из названия - скрипт удаленного запуска посгреса. Я предлагаю юзать системные инит-скрипты и судо, скрипт такого вида:
#!/bin/bash
if [ $# -ne 2 ]
then
echo "pgpool_remote_start remote_host remote_datadir"
exit 1
fi
DEST=$1
DESTDIR=$2
PGCTL=/usr/pgsql-9.2/bin/pg_ctl
ssh -T $DEST "sudo service postgresql-9.2 start"
Естественно, для его работы в судоерс необходимо разрешить юзеру посгрес выполнять "service postgresql-9.2 start" без запроса пароля.
Второй скрипт - собственно процедура рекавери. Скрипт такой:
#!/bin/bash
if [ $2 = "slave.hostname" ]
then
cluster_master="master.hostname"
else
cluster_master="slave.hostname"
fi
recovery_host=$2
recovery_dir=$3
psql -c "SELECT pg_start_backup('Streaming Replication', true)" postgres
rsync -C -a -c --delete --exclude postmaster.pid \
--exclude postmaster.opts --exclude pg_log \
--exclude recovery.conf --exclude recovery.done \
$recovery_dir/ $recovery_host:$recovery_dir/
psql -c "SELECT pg_stop_backup()" postgres
rec=`mktemp`
cat > $rec << EOF
standby_mode='on'
primary_conninfo='host=$cluster_master port=5432 user=postgres'
trigger_file='$recovery_dir/trigger_file'
restore_command='cp /opt/pgsql/archive/%f %p'
archive_cleanup_command='/usr/pgsql-9.2/bin/pg_archivecleanup /opt/pgsql/archive/%r'
EOF
scp $rec $recovery_host:$recovery_dir/recovery.conf
rm -f $rec
ssh -T $recovery_host sed -i "s/hostname/$cluster_master/g" $recovery_dir/postgresql.conf
Скрипт похож на "ручной" скрипт рекавери, но слегка изменен, т.к. приходится определять хостнейм текущего мастера (функция pgpool_recovery не передает имя мастера).
Когда все скрипты на месте, функции в базу загружены - можно переходить к конфигу пгпула.
Править нужно раздел "online recovery":
recovery_user = 'postgres' # юзер (посгресовый)
recovery_password = 'pass' # пароль
recovery_1st_stage_command = 'recover-online.sh' # имя рекавери-скрипта
Остальные параметры можно не трогать. Перезапускаем пгпул и можно пробовать - механизм должен работать.
Тут и подходим к самому главному - нафига было столько геморроя? Ибо пгпул не будет пытаться самостоятельно восстанавливать ноду после падения - он будет терпиливо ждать команды pcp_recovery_node (или нажатия кнопки в pgpool-admin-е) и только после получения ее с нужными параметрами соизволит восстановить ноду.
А раз ручками лезть все равно надо - по-моему проще "ручным" скриптом восстановить ноду и жмакнуть pcp_attach_node.
3. Устраняем единую точку отказа.
Pgpool в единственном числе - общая точка отказа. Для устранения этой проблемы - необходим еще один (или более) пгпул и настроенный watchdog. В случае с 2-мя хостами посгреса, master/slave - очевидным вариантом будет установка пгпула на каждый из хостов.
Конфиги пгпула должны быть одинаковые (включая скрипты файловера, рекавери и т.п.), различия есть только в разделе watchdog в параметрах.
use_watchdog = on #включаем вотчдог
trusted_servers = '192.168.222.2' #лучше указать один/несколько гарантированно доступных хостов - для исключения split-brain ситуации
wd_hostname = 'hostname' # имя хоста, на котором этот пгпул запущен; свое для каждого хоста
wd_port = 9000 # порт должен быть открыт на фаерволле
wd_authkey = 'qwerty' # ключик авторизации вотчдога, должен быть одинаковый. можно вообще без него
delegate_IP = '192.168.222.220' # виртуальный айпи, по которому будет доступен кластер. именно на него нужно натравливать приложение, желающее соединиться с базой
wd_lifecheck_method = 'heartbeat' #метод работы вотчдога, heartbeat появился с версии 3.3. query у меня не заработал (как и вотчдог в 3.2 вообще)
wd_interval = 5
wd_heartbeat_port = 9694 #порт для хартбита. должен быть открыт в фаерволле
wd_heartbeat_keepalive = 2
wd_heartbeat_deadtime = 15
heartbeat_destination0 = 'hostname2' #имя другого хоста
heartbeat_destination_port0 = 9694
other_pgpool_hostname0 = 'hostname2' #имя другого хоста
other_pgpool_port0 = 5432
other_wd_port0 = 9000
Таким образом, конфиги различаются только параметрами wd_hostname, heartbeat_destination0 и other_pgpool_hostname0. Еще один важный момент - если пгпул запускается не от рута (а это так, если ставился из пакетов; да и вообще - нефиг), то для поднятия/опускания сетевых алиасов необходимо поставить suid-бит на /sbin/ifconfig и /usr/sbin/arping.
Если не ошиблись с хостнеймами и портами, то при запуске пулов они друг-друга увидят, один станет мастером и поднимет алиас, другой будет в стендбае, на случай падения мастера.
4. Результат
В целом, как отказоустойчивый кластер - pgpool справляется со своей задачей. Ослеживание доступности посгресов, файловер, рекавери, балансировка селектов, без единой точки отказа - это все есть и работает. Но, на мой взгляд - слишком много неочевидных мелочей в настройке и общее впечатление "нестабильности" всего этого хозяйства. Кроме того, хоть название и предполагает пулер соединений, но по-факту клиентские соединения разрываются при файловере. Поэтому использовать подобный кластер можно только в том случае, если клиенсткое приложение спокойно переваривает обрывы соединений и недоступность базы в течении 1-10сек (при срабатывании вотчдога и переключении на резервный пгпул).
По скорости работы: плохая новость - даже в режиме асинхронной репликации скорость посгреса на апдейтах/инсертах проседает раза в 3-4, по сравнению с одиночным посгресом (мерил pgbench-ем при дефолтном postgresql.conf, наличие/отсутствие пгпула на результат не влияет); хорошая новость - с включенным load-balancing-ом и memory cache скорость селектов в 2-4 раза выше, чем одиночный посгрес (опять же pgbench).
Взято отсюда.
1. Подготовка посгреса.
Необходимо настроить потоковую репликацию.
Первым делом необходимо настроить авторизацию юзера postgres на машинах кластера по ssh-ключам без пароля (причем, не забыть про коннект по ssh к самому себе). ssh-keygen и ssh-copy-id в помощь.
Конфиг postgresql.conf лучше иметь одинаковый (за исключением директивы archive_command), что на мастере, что на слейве - так удобнее и проще, тоже самое касается каталогов с базой и архивлогами.
Добавляем директивы:
hot_standby = on // указывает что слейв будет в одноименном режиме, т.е. с него возможны селекты; на мастере она игнорируется
wal_level = hot_standby // директива для мастера, указывает режим репликации; на слейве игнорируется
max_wal_senders = 4 // число процессов репликации, должно быть не меньше числа слейвов
wal_keep_segments = 12 // сколько хранить wal-логов, если число будет слишком маленьким - слейв не сможет засинхронизироваться после длительного оффлайна
archive_mode = on // дополнение к потоковой репликации, ускоряет синхронизацию после длительного оффлайна
archive_command = 'rsync -aq %p <slave-name>:/somedir/archive/%f' // команда для отправки файликов архив-логов. единственный параметр, который будет различаться на мастере и слейве (мастер указывает на слейв, слейв на мастер)
Кроме того, listen_address не должен быть localhost, иначе слейв не сможет подключиться (извращения со слейвом на том же хосте опустим), а так же необходимо настроить pg_hba.conf для разрешения подключения replication-юзера, что-то вроде такого:
host replication postgres 192.168.1.0/24 trust
После этого запускаем мастер-сервер. Готовим слейв.
Проще всего сделать pg_basebackup с работающего мастера, указать в archive_command хостнейм мастера и добавить файлик recovery.conf:
standby_mode='on'
primary_conninfo='host=master port=5432 user=postgres' // реквизиты подключения к мастеру
trigger_file='/somedir/trigger_file' // путь до триггер-файла. при его появлении посгрес будет считать что мастер сдох и нужно самому становиться мастером
restore_command='cp /somedir/archive/%f %p' // команда для применения архивлогов
archive_cleanup_command='/usr/pgsql-9.2/bin/pg_archivecleanup /somedir/archive %r' // очистка примененных архивлогов
После этого можно можно запускать слейва, он должен успешно подключиться к мастеру и войти в режим hot_standby.
2. Настройка pgpool
Поставить pgpool под rhel/centos можно из пакетов, так что про традиционное для подобных хаутушечек configure&&make&&make install можно забыть.
Правим pgpool.conf:
backend_hostname0 = 'hostname'
backend_port0 = 5432
backend_weight0 = 1
backend_data_directory0 = '/opt/pgsql/9.2/data'
backend_flag0 = 'ALLOW_TO_FAILOVER'
Такими директивами (с увеличением порядкового номера) описываются все ноды кластера.
Включаем авторизацию через pgpool:
enable_pool_hba = on
authentication_timeout = 60
pool_passwd = 'pool_passwd' #имя файлика с юзерами/паролями в каталоге /etc/pgpool-II
Для авторизации по паролям через pgpool необходимо чтобы юзер и пароль совпадали, что в pgpool-е, что в посгресе, тип авторизации в посгресе должен быть md5. Например, создаем юзера "root" с паролем "qwerty":
createuser -lP root
в pg_hba.conf добавляем
host all root pgpool-host-ip md5
pg_md5 -u root -p
вывод добавляем в pool_passwd, права на файл должны позволять юзеру postgres его прочитать.
Возвращаемся к pgpool.conf:
load_balance_mode = on # включаем балансировку нагрузки - селекты смогут выполняться в т.ч. на слейве
master_slave_mode = on
master_slave_sub_mode = 'stream' # включаем streaming replication
sr_check_period = 10 # период проверки репликации
sr_check_user = 'root' # реквизиты для проверки репликации
sr_check_password = 'qwerty'
health_check_period = 5 # проверка доступности нод
health_check_timeout = 10
health_check_user = 'root' # реквизиты для проверки
health_check_password = 'qwerty'
failover_command = '/opt/pgsql/failover.sh %d %P %H %R' # самое важное - команда для файловера, будет исполняться при падении какой-либо из нод
Скрипт файловера довольно простой: если упал слейв - не делать ничего, если мастер - создать триггер-файл на слейве. А чтобы все это получилось - ssh-ключики и создавались.
#!/bin/bash
failed_id=$1
old_primary_id=$2
new_master_host_name=$3
new_database_path=$4
trigger=trigger_file
if [ $failed_id = $old_primary_id ];then # master failed
ssh $new_master_host_name touch $new_database_path/$trigger # let standby take over
fi
На этом минимум - закончен. pgpool сможет обслуживать соединения, отслеживать состояния нод и промоутить слейва в случае падения мастера.
Остается решить вопрос с рекавери - восстановлением работы упавшей ноды. Для этого есть 2 варианта:
восстанавливать ноду ручками (т.е. без участия pgpool-а) и давать pgpool-у команду на присоединение ноды
настроить online-recovery в pgpool-е, но все равно восстанавливать ручками :D хотя бы потому, что команду на восстановление придется все же давать руками (через консоль или модный pgpoolAdmin)
Первый вариант довольно прост и по-сути полностью повторяет официальный посгресовый гайд: сделать бейсбэкап с работающего мастера, создать recovery.conf и запустить ноду как слейв. Это все можно оформить в удобный скрипт:
#!/bin/bash
cluster_master=$1
recovery_host=$2
recovery_dir=$3
psql -h $cluster_master -c "SELECT pg_start_backup('Streaming Replication', true)" postgres
rsync -C -a -c --delete --exclude postgresql.conf --exclude postmaster.pid \
--exclude postmaster.opts --exclude pg_log \
--exclude recovery.conf --exclude recovery.done \
--exclude pg_xlog \
$recovery_dir/ $recovery_host:$recovery_dir/
psql -h $cluster_master -c "SELECT pg_stop_backup()" postgres
ssh $recovery_host "mkdir $recovery_dir/pg_xlog; chmod 700 $recovery_dir/pg_xlog"
rec=`mktemp`
cat > $rec << EOF
standby_mode='on'
primary_conninfo='host=$cluster_master port=5432 user=postgres'
trigger_file='$recovery_dir/trigger_file'
restore_command='cp /opt/pgsql/archive/%f %p'
archive_cleanup_command='/usr/pgsql-9.2/bin/pg_archivecleanup /opt/pgsql/archive %r'
EOF
scp $rec $recovery_host:$recovery_dir/recovery.conf
rm -f $rec
ssh $recovery_host sed -i "s/slave-hostname/$cluster_master/g" $recovery_dir/postgresql.conf
Соответственно алгоритм восстановления по этому варианту таков:
Запустить скрипт с работающего мастера, указать хостнеймы мастера, восстанавливаемого слейва и каталог pg_data. Он подготовит слейв
Запустить слейв. Если нигде ничего не напутано - он успешно подключится к мастеру и начнет работать хот-стендбаем.
Дать команду пгпулу на присоединение ноды: pcp_attach_node timeout hostname port# username password nodeID. nodeID восстанавливаемой ноды можно увидеть из вывода pcp_pool_status.
После этого нода будет вновь доступна в пгпуле.
Второй вариант - online-recovery в pgpool.
Механизм работы пгпула в этом варианте несколько неочевиден. В отличие от fileover и прочих функций - рекавери запускается не напрямую скриптом, а через вызов посгресовых функций pgpool_recovery и pgpool_remote_start, которые уже вызывают непосредственные скрипты (нафига такой изврат??!). Соответственно, чтобы все это работало - в посгрес должны быть загружены эти функции (в базу postgres и template), а для загрузки этих функций необходима шаред-библиотека под посгрес pgpool-recovery.so.
После добавления пгпуловских фукнций в посгрес нужно создать 2 скрипта в каталоге $pg_data: pgpool_remote_start (именно с таким названием!) и recover-online (тут уже название произвольное).
Первый скрипт, как видно из названия - скрипт удаленного запуска посгреса. Я предлагаю юзать системные инит-скрипты и судо, скрипт такого вида:
#!/bin/bash
if [ $# -ne 2 ]
then
echo "pgpool_remote_start remote_host remote_datadir"
exit 1
fi
DEST=$1
DESTDIR=$2
PGCTL=/usr/pgsql-9.2/bin/pg_ctl
ssh -T $DEST "sudo service postgresql-9.2 start"
Естественно, для его работы в судоерс необходимо разрешить юзеру посгрес выполнять "service postgresql-9.2 start" без запроса пароля.
Второй скрипт - собственно процедура рекавери. Скрипт такой:
#!/bin/bash
if [ $2 = "slave.hostname" ]
then
cluster_master="master.hostname"
else
cluster_master="slave.hostname"
fi
recovery_host=$2
recovery_dir=$3
psql -c "SELECT pg_start_backup('Streaming Replication', true)" postgres
rsync -C -a -c --delete --exclude postmaster.pid \
--exclude postmaster.opts --exclude pg_log \
--exclude recovery.conf --exclude recovery.done \
$recovery_dir/ $recovery_host:$recovery_dir/
psql -c "SELECT pg_stop_backup()" postgres
rec=`mktemp`
cat > $rec << EOF
standby_mode='on'
primary_conninfo='host=$cluster_master port=5432 user=postgres'
trigger_file='$recovery_dir/trigger_file'
restore_command='cp /opt/pgsql/archive/%f %p'
archive_cleanup_command='/usr/pgsql-9.2/bin/pg_archivecleanup /opt/pgsql/archive/%r'
EOF
scp $rec $recovery_host:$recovery_dir/recovery.conf
rm -f $rec
ssh -T $recovery_host sed -i "s/hostname/$cluster_master/g" $recovery_dir/postgresql.conf
Скрипт похож на "ручной" скрипт рекавери, но слегка изменен, т.к. приходится определять хостнейм текущего мастера (функция pgpool_recovery не передает имя мастера).
Когда все скрипты на месте, функции в базу загружены - можно переходить к конфигу пгпула.
Править нужно раздел "online recovery":
recovery_user = 'postgres' # юзер (посгресовый)
recovery_password = 'pass' # пароль
recovery_1st_stage_command = 'recover-online.sh' # имя рекавери-скрипта
Остальные параметры можно не трогать. Перезапускаем пгпул и можно пробовать - механизм должен работать.
Тут и подходим к самому главному - нафига было столько геморроя? Ибо пгпул не будет пытаться самостоятельно восстанавливать ноду после падения - он будет терпиливо ждать команды pcp_recovery_node (или нажатия кнопки в pgpool-admin-е) и только после получения ее с нужными параметрами соизволит восстановить ноду.
А раз ручками лезть все равно надо - по-моему проще "ручным" скриптом восстановить ноду и жмакнуть pcp_attach_node.
3. Устраняем единую точку отказа.
Pgpool в единственном числе - общая точка отказа. Для устранения этой проблемы - необходим еще один (или более) пгпул и настроенный watchdog. В случае с 2-мя хостами посгреса, master/slave - очевидным вариантом будет установка пгпула на каждый из хостов.
Конфиги пгпула должны быть одинаковые (включая скрипты файловера, рекавери и т.п.), различия есть только в разделе watchdog в параметрах.
use_watchdog = on #включаем вотчдог
trusted_servers = '192.168.222.2' #лучше указать один/несколько гарантированно доступных хостов - для исключения split-brain ситуации
wd_hostname = 'hostname' # имя хоста, на котором этот пгпул запущен; свое для каждого хоста
wd_port = 9000 # порт должен быть открыт на фаерволле
wd_authkey = 'qwerty' # ключик авторизации вотчдога, должен быть одинаковый. можно вообще без него
delegate_IP = '192.168.222.220' # виртуальный айпи, по которому будет доступен кластер. именно на него нужно натравливать приложение, желающее соединиться с базой
wd_lifecheck_method = 'heartbeat' #метод работы вотчдога, heartbeat появился с версии 3.3. query у меня не заработал (как и вотчдог в 3.2 вообще)
wd_interval = 5
wd_heartbeat_port = 9694 #порт для хартбита. должен быть открыт в фаерволле
wd_heartbeat_keepalive = 2
wd_heartbeat_deadtime = 15
heartbeat_destination0 = 'hostname2' #имя другого хоста
heartbeat_destination_port0 = 9694
other_pgpool_hostname0 = 'hostname2' #имя другого хоста
other_pgpool_port0 = 5432
other_wd_port0 = 9000
Таким образом, конфиги различаются только параметрами wd_hostname, heartbeat_destination0 и other_pgpool_hostname0. Еще один важный момент - если пгпул запускается не от рута (а это так, если ставился из пакетов; да и вообще - нефиг), то для поднятия/опускания сетевых алиасов необходимо поставить suid-бит на /sbin/ifconfig и /usr/sbin/arping.
Если не ошиблись с хостнеймами и портами, то при запуске пулов они друг-друга увидят, один станет мастером и поднимет алиас, другой будет в стендбае, на случай падения мастера.
4. Результат
В целом, как отказоустойчивый кластер - pgpool справляется со своей задачей. Ослеживание доступности посгресов, файловер, рекавери, балансировка селектов, без единой точки отказа - это все есть и работает. Но, на мой взгляд - слишком много неочевидных мелочей в настройке и общее впечатление "нестабильности" всего этого хозяйства. Кроме того, хоть название и предполагает пулер соединений, но по-факту клиентские соединения разрываются при файловере. Поэтому использовать подобный кластер можно только в том случае, если клиенсткое приложение спокойно переваривает обрывы соединений и недоступность базы в течении 1-10сек (при срабатывании вотчдога и переключении на резервный пгпул).
По скорости работы: плохая новость - даже в режиме асинхронной репликации скорость посгреса на апдейтах/инсертах проседает раза в 3-4, по сравнению с одиночным посгресом (мерил pgbench-ем при дефолтном postgresql.conf, наличие/отсутствие пгпула на результат не влияет); хорошая новость - с включенным load-balancing-ом и memory cache скорость селектов в 2-4 раза выше, чем одиночный посгрес (опять же pgbench).
Взято отсюда.