четверг, 12 сентября 2013 г.

Кластер postgresql с pgpool

Небольшая хаутушечка по настройке 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).

40 комментариев:

  1. Этот комментарий был удален автором.

    ОтветитьУдалить
    Ответы
    1. Здравствуйте! помогите, пожалуйста, разобраться в настройках pgpool-ii для файловера и on-line восстановления, а то уже такая каша в голове!.. Простите заранее глупые вопросы, но я профан в этом деле...
      У меня есть три машины:
      1-pgpool-ii (ip=192.168.1.1);
      2 - master в потоковой репликации (ip=192.168.1.2);
      3 - slave (ip=192.168.1.3).
      Порядок моих дествий такой:
      1.Настраиваю потоковую репликацию между 2 и 3 машиной.
      2.Устанавливаю pgpool-ii на первую машину.
      3.Устанавливаю функции pgpool-recovery, pgpool-regclass, pgpool-walrecrunning на все машины в базы postgres и template1.
      4.настраиваю ключи доступа для пользователя postgres и рассылаю всем
      машинам,также сделала свободный доступ для root-а к 2 и 3 с машины pgpool-ii и установила права доступа:
      chmod 700 .../.ssh
      chmod 600 .../.ssh/authorized_keys
      5.файл pgpool.conf настраиваю:
      ...
      listen_addresses = '*'
      port = 9999
      socket_dir = '/tmp'
      pcp_port = 9898
      pcp_socket_dir = '/tmp'
      backend_hostname0 = '192.168.1.2' #master
      backend_port0 = 5432
      backend_weight0 = 1
      backend_data_directory0 = '/usr/local/pgsql/data'
      backend_flag0 = 'ALLOW_TO_FAILOVER'
      backend_hostname1 = '192.168.1.3' #slave
      backend_port1 = 5432
      backend_weight1 = 1
      backend_data_directory1 = '/usr/local/pgsql/data'
      backend_flag1 = 'ALLOW_TO_FAILOVER'
      enable_pool_hba = on
      authentication_timeout = 60
      num_init_children = 32
      max_pool = 4
      child_life_time = 300
      child_max_connections = 0
      connection_life_time = 0
      client_idle_limit = 0
      insert_lock = on
      load_balance_mode = on
      master_slave_mode = on
      master_slave_sub_mode = 'stream'
      delay_threshold = 0
      #follow_master_command = ''
      system_db_hostname = 'localhost'
      system_db_port = 5432
      system_db_dbname = 'pgpool'
      system_db_schema = 'pgpool_catalog'
      system_db_user = 'pgpool'
      system_db_password = ''
      health_check_period = 0
      health_check_timeout = 20
      health_check_user = 'postgres'
      health_check_password = 'my_password'
      health_check_max_retries = 0
      health_check_retry_delay = 1
      failover_command = '/usr/local/pgsql/failover_stream.sh %D %H /usr/local/pgsql/data/trigger'
      failback_command = ''
      fail_over_on_backend_error = on
      recovery_user = 'postgres'
      recovery_password = 'my_password'
      recovery_1st_stage_command = '/usr/local/pgsql/data/basebackup.sh'
      #recovery_2nd_stage_command = ''
      recovery_timeout = 90
      client_idle_limit_in_recovery = 20
      ...
      вопросы и проблемы у меня возникают следующие:
      1мастер в бекендах пишется на месте backend_hostname0 или нет разницы?
      2надо ли что писать в "follow_master_command"
      3вобще файловер срабатывает при таких настройках, но иногда повисает и почему-то не сразу создает файл trigger хотя и переименовывает recovery.conf в recovery.done. (trigger появляется после рестарта postgres-а на новом мастере).
      4пока я не выполню запрос файловер не сработает - не видит отключения мастера. Запрос,который делался вовремя отключения мастера не исполняется - это нормально?
      5файл failover_stream.sh помещаю в /usr/local/pgsql на машине pgpool-ii и устанавливаю права доступа: chmod 755 .../failover_stream.sh. Вот такой скрипт:
      failed_node=192.168.1.2
      new_master=192.168.1.3
      trigger_file=/usr/local/pgsql/data/trigger
      if [ $failed_node = 1 ]; then
      exit 0;
      fi
      /usr/bin/ssh -T $new_master /bin/touch $trigger_file
      exit 0;
      подскажите пожалуйста как правильно

      Удалить
    2. 1. без разницы. во время запуска пгпул сам выполняет поиск мастера среди описанных бакэндов
      2. в случае с одним слейвом - ничего не нужно. в случае каскадной репликации (master -> slave1 -> slave2 -> ... -> slaveN) нужно сюда помещать скрипт, который перенастроит слейв2 на нового мастера, а остальные на slave2. Но я с этим не разбирался.
      3. по четче объясните, что у вас за чем происходит. переименованием recovery.conf в recovery.done занимается сам посгрес, а не пгпул, и делает он это после того, как увидит триггер-файл. кроме того, пгпул ведет свою "таблицу состояний", т.е. если нода упала - он это отметит и пока ему не дать команду на восстановление или присоединение ноды - он будет ее считать упавшей, даже если она в реальности уже работает (ну или файлик pool_status удалить и перезапустить пгпул).
      4. у вас health_check выключен (значение 0), отредактируйте параметры health_check_* и все будет определяться.
      в момент файловера все запросы обрываются - это похоже by design, я об этом писал в выводах.
      5. либо опечатка, либо скрипт кривой - в if-е проверка параметра, который задан выше статически (failed_node=192.168.1.99), а должен быть переменной от пгпула. ну и new_master - аналогично

      Удалить
    3. я говорю о том, что когда вырубается мастер и срабатывает файловер на бывшем слейве

      файл trigger не видно (скрытый формат тоже проверяла и папку обновляла - нету), но

      recovery.conf переименовывается в recovery.done. Но когда я уже просто стопонула, а

      потом стартанула postgres на этой машине (бывшем слейве) при выключенном pgpool

      trigger файл проявился.
      failover_stream:

      failed_node=$1
      new_master=$2
      t r i g g e r_f i l e=$3
      i f [ $fai l ed_node = 1 ] ; then
      e x i t 0 ;
      f i
      / us r / bin / s sh -T $new_master / bin / touch $ t r i g g e r_f i l e
      e x i t 0 ;

      т.е. там где $1,$2 - это динамические адреса их прописывать не надо как я поняла, а $3 -

      это же путь к триггер-файлу его надо задавать или он берется из recovery.conf со слейва?

      Удалить
    4. дык все правильно, что его не видно - по событию файловер пгпул файловер-скриптом создает триггер-файл, посгрес на слейве _почти сразу_ (секунда или даже быстрее) это замечает, переименовывает recovery.conf в recovery.done и удаляет триггер-файл - после этого он работает полноценным мастером. вот откуда он вдруг появился при выключенном пгпуле - мне не ясно. точно пгпул был выключен?

      по скрипту - если failover_command = '/usr/local/pgsql/failover_stream.sh %D %H /usr/local/pgsql/data/trigger' (как вы выше написали), то $3 берется из строки вызова (/usr/local/pgsql/data/trigger), ни скрипт, ни сам пгпул recovery.conf не читает.
      вообще, в таком виде этот скрипт корректно работать не будет (точнее - сработает только один раз, когда слейв на 1.2; в обратной ситуации - когда 1.2 мастер, а 1.1 слейв - уже не сработает).
      в скрипте нужно сравнивать упавшую ноду со старым мастером (оба параметра передаются пгпулом), если это так - промоутить слейва. пример скрипта и файловер_комманд - в моем исходном посте.

      Удалить
    5. доброе утро! пгпул точно был выключен,но был выключен и мастер, поэтому-то наверно и проявлялся trigger_fail повторно.
      спасибо.Файловер я сделала по вашему примеру, вроде все сработало кроме одного-

      когда слейв становится мастером в него очень долго пишутся изменения(я бы даже сказала,что pgpool-ii подвисает-пока не нажмешь ctrl-c дальше не идет), но потом изменения все-таки проявляются-как с этим быть? дело в том что он натыкается на отключенную ноду под №0 а дальше не читает почему?(health_check-я исправила)

      Удалить
    6. мистика прям. пока не увижу сам, что-либо сказать по этому поводу не могу. сам посгрес (ни мастер, ни слейв) триггер-файл не создают ни в каких условиях, насколько я знаю - это должен делать пгпул или юзер ручками.

      по второму вопросу:
      sr_check_* параметры заданы? что пишется в логах пгпула в момент и после файловера? что выводит pcp_node_info для обеих нод до и после файловера? ну и лог пгпула при его запуске нужно посмотреть - какую ноду он определил мастером

      Удалить
  2. И еще для online восстановления:
    создаю файл basebackup.sh и помещаю его на машину мастера(бывшего слейва - правильно я рассуждаю???) в папку /usr/local/pgsql/data и задаю права доступа chmod 755. Скрипт:
    PRIMARY_DATA=/usr/local/pgsql/data
    SLAVE_IP=192.168.1.2
    SLAVE_DATA=/usr/local/pgsql/data
    PRIMARY_IP=$(ifconfig eth0| sed -n '2 {s/^.*inet addr:\([0-9.]*\) .*/\1/;p}')
    TMP_DIR=/usr/local/pgsql/data
    cd $PRIMARY_DATA
    rm -f recovery.* trigger
    cat postgresql.conf | grep '#hot_standby = on'
    if [ $? = 1 ]
    then
    sed -i 's/hot_standby = on/#hot_standby = on/' postgresql.conf
    /usr/bin/pg_ctl restart -D $PGDIR
    fi
    ssh -T postgres@$SLAVE_IP "/usr/bin/pg_ctl stop -D $SLAVE_DATA"
    psql -c "SELECT pg_start_backup('Streaming Replication', true)" postgres
    rsync -a $PRIMARY_DATA/ $SLAVE_IP:$SLAVE_DATA/ --exclude postmaster.pid --exclude
    postmaster.opts
    mkdir $TMP_DIR
    cd $TMP_DIR
    cp $PRIMARY_DATA/postgresql.conf $TMP_DIR/
    sed -i 's/#hot_standby = on/hot_standby = on/' postgresql.conf
    echo "standby_mode = 'on'" > recovery.conf
    echo "primary_conninfo = 'host=$PRIMARY_IP port=5432 user=postgres'" >> recovery.conf
    echo "trigger_file = 'failover'" >> recovery.conf
    ssh -T postgres@$SLAVE_IP rm -f $SLAVE_DATA/recovery.*
    scp postgresql.conf postgres@$SLAVE_IP:$SLAVE_DATA/postgresql.conf
    scp recovery.conf postgres@$SLAVE_IP:$SLAVE_DATA/recovery.conf
    psql -c "SELECT pg_stop_backup()" postgres
    cd ..
    rm -fr $TMP_DIR

    на машинах мастера и слейва создаю файл pgpool_remote_start.sh в папке /usr/local/pgsql/data. SLAVE_IP будет одинаковым на обоих машинах (другая машина ведь мастер),т.е.файлы одинаковые и надо ли их прописывать в pgpool.conf? Скрипт:
    if [ $# -ne 2]
    then
    echo "pgpool_remote_start remote_host remote_datadir"
    exit 1
    fi
    SLAVE_IP=192.168.1.2
    SLAVE_DIR=/usr/local/pgsql/data
    PGCTL=/usr/local/pgsql/bin/pg_ctl
    ssh -T $SLAVE_IP $PGCTL -w -D $SLAVE_DIR start 2>/dev/null 1>/dev/null </dev/null &

    Запускаю pgpool-ii и там под postgres-ом выполняю команду:
    pcp_recovery_node 20 192.168.1.1 9898 postgres my_password 0 #где my_password - пароль "в открытом виде" из файла pcp.conf,но команда не исполняется, а пишется:AuthorizationError. Я так понимаю, что пользователь не проходит авторизацию, но где в каком месте? Подскажите,пожалуйста, что не правильно уже все попробовала.

    ОтветитьУдалить
    Ответы
    1. во всех скриптах не стоит писать конкретные айпишники - ибо получается жесткая привязка, что слейв - на 1.2; после файловера уже бывший мастер такими скриптами не восстановить. я бы все-таки рекомендовал во всех скриптах определять мастера/слейва (передачей параметров от пгпула), как в моих примерах.
      по авторизации pcp - в pcp.conf пароль задается в виде хэша md5, а не в открытую, хэш генерится командой pg_md5. а вот при вызове pcp_recovery_node - пароль нужно передавать в открытом виде.
      кроме того, для запуска рекавери пгпул пинает не скрипт, а подключается к посгресу с реквизитами recovery_user / recovery_pass и выполняет функцию pgpool_recovery, а уже посгрес этой функцией запускает скрипты. соответственно, необходимо убедится, что пгпул может подключится к бд посгреса с этими реквизитами (банально - в pg_hba.conf включена md5 авторизация для юзера postgres? юзеру задан пароль в посгресе?) и что скрипты рекавери лежат в $PGDATA каталоге и посгрес может их запустить.

      Удалить
    2. sr_check_* -заданы
      pcp_node_info также как и pcp_recovery_node у меня "ошибка авторизации"
      а команда SHOW pool_nodes выводит
      до файловера:
      1 | 192.168.1.2 | 5432 | 2 | 0.500000 | replication
      2 | 192.168.1.3 | 5432 | 2 | 0.500000 | replication

      после файловера:
      1 | 192.168.1.2 | 5432 | 3 | 0.500000 | standby
      2 | 192.168.1.3 | 5432 | 2 | 0.500000 | primary

      а в логах вот че он пишет-вроде определяет правильно:
      2013-10-01 05:09:40 LOG: pid 32709: find_primary_node: primary node id is 1
      health_check: 1 th DB node status: 1

      2013-10-01 05:17:36 DEBUG: pid 32709: health_check: 0 th DB node status: 3
      2013-10-01 05:17:36 DEBUG: pid 32709: health_check: 1 th DB node status: 2

      2013-10-01 05:17:36 DEBUG: pid 32709: pool_ssl: SSL requested but SSL support is not available
      2013-10-01 05:17:36 DEBUG: pid 32709: s_do_auth: auth kind: 0
      2013-10-01 05:17:36 DEBUG: pid 32709: s_do_auth: backend key data received
      2013-10-01 05:17:36 DEBUG: pid 32709: s_do_auth: transaction state: I
      2013-10-01 05:17:41 DEBUG: pid 32743: pool_ssl: SSL requested but SSL support is not available
      2013-10-01 05:17:41 DEBUG: pid 32743: s_do_auth: auth kind: 0
      2013-10-01 05:17:41 DEBUG: pid 32743: s_do_auth: backend key data received
      2013-10-01 05:17:41 DEBUG: pid 32743: s_do_auth: transaction state: I
      2013-10-01 05:17:41 DEBUG: pid 32709: starting health checking
      и так всю дорогу...
      наверно че-то с ключами доступа намудрила?..

      Удалить
    3. что-то вообще не то, почему до файловера ноды со статусом "replication"? должно быть primary/standby с кодом 2
      replication_mode=off в конфиге есть? перед запуском пгпула посгрес на мастере и слейве был запущен и работал? (мастер должен рапортовать "database system is ready to accept connections", слейв "database system is ready to accept read only connections").
      попробуйте выключить пгпул, удалить файлик pgpool_status, привести мастера и слейва в рабочее состояние и снова запустить пгпул, а уже после этого продолжать эксперименты.

      по авторизации - все же в pcp.conf пароль в виде хэша задан или как?

      s_do_auth и pool_ssl дебаг сообщения - это нормально, проверка репликации у него с такими сообщениями и проходит.
      Больший интерес представляет лог в момент файловера.

      Удалить
    4. настройки pgpool.conf как у вас,а в pcp.conf - пароль в виде хэша так же как там в примере (postgres:password(хэш)), только USERID:MD5PASSWD-здесь надо что или нет?

      Удалить
    5. "USERID:MD5PASSWD" - это лишь пример формы записи реквизитов, строка эта должна быть закомментарена.
      в логах при запуске пгпула нет ругани на недоступность pcp.conf?
      версия пгпула 3.3?

      Удалить
    6. в логах ничего нет о pcp
      до файловера я ошиблась show все правильно расставляет: мастер и слейв
      у меня - pgpool-3.2.1

      Удалить
    7. только вот это, но это еще запроса в БД не поступало а при файловере:
      2013-10-01 07:33:46 LOG: pid 3934: worker process received restart request
      2013-10-01 07:33:46 DEBUG: pid 4043: pool_initialize_private_backend_status: initialize backend status
      2013-10-01 07:33:46 LOG: pid 3890: failover done. shutdown host 192.168.1.2(5432)
      2013-10-01 07:33:46 DEBUG: pid 4052: I am 4052
      2013-10-01 07:33:46 DEBUG: pid 4052: pool_initialize_private_backend_status: initialize backend status
      2013-10-01 07:33:46 DEBUG: pid 4051: I am 4051
      2013-10-01 07:33:46 DEBUG: pid 4051: pool_initialize_private_backend_status: initialize backend status
      2013-10-01 07:33:47 LOG: pid 3933: pcp child process received restart request
      2013-10-01 07:33:47 DEBUG: pid 3890: reap_handler called
      2013-10-01 07:33:47 DEBUG: pid 3890: reap_handler: call wait3
      2013-10-01 07:33:47 DEBUG: pid 3890: child 3891 exits with status 0
      2013-10-01 07:33:47 DEBUG: pid 3890: child 3893 exits with status 0
      2013-10-01 07:33:47 DEBUG: pid 3890: child 3895 exits with status 0
      когда выполняю запрос:
      2013-10-01 07:35:42 DEBUG: pid 4051: statement2: DROP DATABASE tu;
      2013-10-01 07:35:42 DEBUG: pid 4051: pool_set_query_in_progress: done
      2013-10-01 07:35:42 DEBUG: pid 4051: send_to_where: 0 query: DROP DATABASE tu;
      2013-10-01 07:35:42 DEBUG: pid 4051: Query: sending SIGUSR1 signal to parent
      2013-10-01 07:35:42 DEBUG: pid 3890: failover_handler called
      2013-10-01 07:35:42 DEBUG: pid 4014: child receives close connection request

      Удалить
    8. попробуйте все же обновиться до 3.3 - у меня было много необъяснимых глюков на ровном месте с 3.2

      ну и лог все же хочется увидеть полнее - с момента падения ноды (connect_inet_domain_socket: connect() failed: Connection refused и далее) + pool_status до этого момента, после и после выполнения какого-нибудь запроса.

      Удалить
  3. а еще у вас в тексте написано помещать пароль в pool_passwd это тот хэш пароля,что и в pcp.conf или надо только в pcp.conf?

    ОтветитьУдалить
    Ответы
    1. в pool_password заносятся реквизиты посгресовых пользователей для их авторизации через пгпул, нужно чтобы был выставлен pool_hba=on в конфиге, в pg_hba.conf для этих пользователей установлен режим md5 и пароль в посгресе совпадал с паролем в pool_passwd.
      без pool_hba авторизация будет проходить только при выставленном режиме "trust" в pg_hba.conf (т.е. без авторизации вообще)
      к pcp это не имеет никакого отношения, pcp и его конфиг отвечает только за авторизацию на интерфейсе управления пгпула (запускать рекавери, подключать/отключать ноды, статус и т.п.)

      Удалить
  4. здравствуйте,Юрий! извините, что сразу не ответила: пока переставляла пгпул на 3.3 и тестировала,но опять подвисают запросы при передаче прав с мастера на слейв, вот логи:
    DEBUG: pid 24938: health check: clearing alarm
    DEBUG: pid 24938: health check: clearing alarm
    DEBUG: pid 24938: starting health checking
    DEBUG: pid 24938: health check: clearing alarm
    DEBUG: pid 24938: health_check: 0 th DB node status: 3
    DEBUG: pid 24938: health_check: 1 th DB node status: 2
    DEBUG: pid 24938: pool_ssl: SSL requested but SSL support is not available
    DEBUG: pid 24938: s_do_auth: auth kind: 0
    DEBUG: pid 24938: s_do_auth: backend key data received
    DEBUG: pid 24938: s_do_auth: transaction state: I
    ...
    DEBUG: pid 25173: I am 25173 accept fd 6
    LOG: pid 25173: connection received: host=[local]
    DEBUG: pid 25173: read_startup_packet: application_name: createdb
    DEBUG: pid 25173: Protocol Major: 3 Minor: 0 database: postgres user: postgres
    DEBUG: pid 25173: new_connection: connecting 0 backend
    DEBUG: pid 25173: new_connection: skipping slot 0 because backend_status = 3
    DEBUG: pid 25173: new_connection: connecting 1 backend
    DEBUG: pid 25173: pool_ssl: SSL requested but SSL support is not available
    DEBUG: pid 25173: pool_read_message_length: slot: 1 length: 8
    DEBUG: pid 25173: pool_do_auth: auth kind:0
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 30
    DEBUG: pid 25173: 1 th backend: name: application_name value: createdb
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 25
    DEBUG: pid 25173: 1 th backend: name: client_encoding value: UTF8
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 23
    DEBUG: pid 25173: 1 th backend: name: DateStyle value: ISO, DMY
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 25
    DEBUG: pid 25173: 1 th backend: name: integer_datetimes value: on
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 27
    DEBUG: pid 25173: 1 th backend: name: IntervalStyle value: postgres
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 20
    DEBUG: pid 25173: 1 th backend: name: is_superuser value: on
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 25
    DEBUG: pid 25173: 1 th backend: name: server_encoding value: UTF8
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 25
    DEBUG: pid 25173: 1 th backend: name: server_version value: 9.2.1
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 35
    DEBUG: pid 25173: 1 th backend: name: session_authorization value: postgres
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 35
    DEBUG: pid 25173: 1 th backend: name: standard_conforming_strings value: on
    DEBUG: pid 25173: pool_read_message_length2: master slot: 1 length: 18
    DEBUG: pid 25173: 1 th backend: name: TimeZone value: W-SU
    DEBUG: pid 25173: pool_read_message_length: slot: 1 length: 12
    DEBUG: pid 25173: pool_do_auth: cp->info[i]:0x7f631d486088 pid:11724
    DEBUG: pid 25173: pool_send_auth_ok: send pid 11724 to frontend
    DEBUG: pid 25173: select_load_balancing_node: selected backend id is 1
    DEBUG: pid 25173: selected load balancing node: 1
    DEBUG: pid 25173: pool_unset_query_in_progress: done
    DEBUG: pid 25173: pool_unset_command_success: done
    DEBUG: pid 25173: pool_unset_writing_transaction: done
    DEBUG: pid 25173: pool_unset_failed_transaction: done
    DEBUG: pid 25173: pool_unset_transaction_isolation: done
    DEBUG: pid 25173: pool_unset_skip_reading_from_backends: done
    DEBUG: pid 25173: pool_unset_ignore_till_sync: done
    DEBUG: pid 25173: read_kind_from_one_backend: read kind from 1 th backend Z
    DEBUG: pid 25173: read_kind_from_backend: kind: Z from 1 th backend
    DEBUG: pid 25173: read_kind_from_backend: read kind from 1 th backend Z NUM_BACKENDS: 2
    DEBUG: pid 25173: ProcessBackendResponse: kind from backend: Z
    DEBUG: pid 25173: pool_read_message_length: slot: 1 length: 5
    DEBUG: pid 25173: ReadyForQuery: transaction state:
    DEBUG: pid 25173: ProcessBackendResponse: Ready For Query

    ОтветитьУдалить
  5. и еще:
    DEBUG: pid 25173: ProcessFrontendResponse: kind from frontend Q(51)
    DEBUG: pid 25173: pool_unset_doing_extended_query_message: done
    DEBUG: pid 25173: statement2: CREATE DATABASE new2;
    DEBUG: pid 25173: pool_set_query_in_progress: done
    DEBUG: pid 25173: send_to_where: 0 query: CREATE DATABASE new2;
    DEBUG: pid 25173: wait_for_query_response: waiting for backend 1 completing the query
    DEBUG: pid 25176: pool_ssl: SSL requested but SSL support is not available
    DEBUG: pid 25176: s_do_auth: auth kind: 0
    DEBUG: pid 25176: s_do_auth: backend key data received
    DEBUG: pid 25176: s_do_auth: transaction state: I
    DEBUG: pid 24938: starting health checking
    DEBUG: pid 24938: health check: clearing alarm
    DEBUG: pid 24938: health_check: 0 th DB node status: 3
    DEBUG: pid 24938: health_check: 1 th DB node status: 2
    DEBUG: pid 24938: pool_ssl: SSL requested but SSL support is not available
    DEBUG: pid 24938: s_do_auth: auth kind: 0
    DEBUG: pid 24938: s_do_auth: backend key data received
    DEBUG: pid 24938: s_do_auth: transaction state: I
    DEBUG: pid 24938: health check: clearing alarm
    DEBUG: pid 24938: health check: clearing alarm
    ...
    DEBUG: pid 25173: pool_flush_it: write failed to frontend. reason: Broken pipe offset: 0 wlen: 43
    ERROR: pid 25173: wait_for_query_response: frontend error occured while waiting for backend reply
    DEBUG: pid 25173: Cancel request received
    DEBUG: pid 25173: con_info: address:0x7f631d288000 database: user: pid:0 key:0 i:0
    DEBUG: pid 25173: con_info: address:0x7f631d288088 database: user: pid:0 key:0 i:0
    ...
    DEBUG: pid 25173: con_info: address:0x7f631d486000 database: user: pid:0 key:0 i:30
    DEBUG: pid 25173: con_info: address:0x7f631d486088 database:postgres user:postgres pid:11724 key:1416384456 i:30
    DEBUG: pid 25173: found pid:11724 key:1416384456 i:30
    LOG: pid 25173: cancel_request: canceling backend pid:11724 key: 1416384456
    DEBUG: pid 25173: pool_unset_query_in_progress: done
    LOG: pid 25173: do_child: exits with status 1 due to error
    DEBUG: pid 24938: reap_handler called
    DEBUG: pid 24938: reap_handler: call wait3
    DEBUG: pid 24938: child 25173 exits with status 256
    DEBUG: pid 24938: fork a new child pid 25183
    DEBUG: pid 24938: reap_handler: normally exited
    DEBUG: pid 25183: I am 25183
    DEBUG: pid 25183: pool_initialize_private_backend_status: initialize backend status
    DEBUG: pid 25176: pool_ssl: SSL requested but SSL support is not available
    DEBUG: pid 25176: s_do_auth: auth kind: 0
    DEBUG: pid 25176: s_do_auth: backend key data received
    DEBUG: pid 25176: s_do_auth: transaction state: I
    DEBUG: pid 24938: starting health checking
    DEBUG: pid 24938: health check: clearing alarm
    DEBUG: pid 24938: health_check: 0 th DB node status: 3
    DEBUG: pid 24938: health_check: 1 th DB node status: 2
    DEBUG: pid 24938: pool_ssl: SSL requested but SSL support is not available
    DEBUG: pid 24938: s_do_auth: auth kind: 0
    DEBUG: pid 24938: s_do_auth: backend key data received
    DEBUG: pid 24938: s_do_auth: transaction state: I
    DEBUG: pid 24938: health check: clearing alarm
    DEBUG: pid 24938: health check: clearing alarm
    DEBUG: pid 25172: I am 25172 accept fd 6
    LOG: pid 25172: connection received: host=[local]
    DEBUG: pid 25172: read_startup_packet: application_name: psql.bin
    DEBUG: pid 25172: Protocol Major: 3 Minor: 0 database: postgres user: postgres
    DEBUG: pid 25172: new_connection: connecting 0 backend
    DEBUG: pid 25172: new_connection: skipping slot 0 because backend_status = 3
    DEBUG: pid 25172: new_connection: connecting 1 backend
    DEBUG: pid 25172: pool_ssl: SSL requested but SSL support is not available
    DEBUG: pid 25172: pool_read_message_length: slot: 1 length: 8
    DEBUG: pid 25172: pool_do_auth: auth kind:0
    DEBUG: pid 25172: pool_read_message_length2: master slot: 1 length: 30
    DEBUG: pid 25172: 1 th backend: name: application_name value: psql.bin
    ...
    DEBUG: pid 25172: pool_read_message_length: slot: 1 length: 12
    DEBUG: pid 25172: pool_do_auth: cp->info[i]:0x7f631d475088 pid:11737
    DEBUG: pid 25172: pool_send_auth_ok: send pid 11737 to frontend

    ОтветитьУдалить
  6. хм, ну почему-то соединение от нового мастера рвется в момент отдачи ответа пгпулу
    "pool_flush_it: write failed to frontend. reason: Broken pipe"
    посмотрите, а что в логах самого посгреса происходит в этот момент (с дебагом)? подобная реакция на все запросы после файловера или только первый? а если этот же эксперимент провести, поменяв местами ноды (т.е. чтобы прошел файловер и новый мастер был нода 0)?

    ОтветитьУдалить
  7. реакция на все запросы,после файловера. попробовала ноды прописать наоборот-та же шляпа...
    и еще: а может это из-за того,что я примонтировала отдельную папку для записи логов постгреса, а когда мастер отключается,то и эта папка тоже становится недоступной, и логи начинают писаться по умолчанию в pg_xlog. как быть?

    ОтветитьУдалить
    Ответы
    1. вполне возможно. а, пардон, зачем?
      для шиппинга бинлогов на слейв можно (и нужно) использовать средства посгреса. в postgres.conf:
      achive_mode on
      archive_command = 'rsync -aq %p slavename:/somedir/archive/%f'
      в recovery.conf:
      restore_command='cp /somedir/archive/%f %p' archive_cleanup_command='/usr/pgsql-9.2/bin/pg_archivecleanup /somedir/archive %r'
      ессно, должен быть rsync, должны быть права на эту папку для юзера postgres и ssh-вход по ключам без пароля.

      Удалить
  8. я на мастере создаю папку расширяю ее и подключаю как nfs-сервер-туда пишутся логи,а на слейве монтирую папку мастера через nfs-клиент и там все логи проявляютя. в postgresql.conf: archive_command = ’ cp %p /path_to/archive/%f ’но вот похоже когда мастер вырубается слейв не успевает дописать все логи(((
    а Ваша команда у меня че-то не срабатывает: обычный rsync,где прописываются пути работает,т.е. ключи и доступ все настроены, а когда пишу в кофиге,то логи просто пишутся в свою папку xlog и файловер опять висит!
    и не подскажите еще:pcp_recovery пишет,что:"error while loading shared libraries:libpcp.so.0 cannot open shared object file:no file or directory".эта библиотека у меня есть на всех машинах, но ее как то надо открыть или где-то прописать?(в /etc/ld.so.conf уже прописан)

    ОтветитьУдалить
    Ответы
    1. ну для начала - забейте вообще на пгпул, у вас с самой стриминг репликацией проблемы, нужно сначала с этим разобраться.
      для начала проясним - "логи" имеются ввиду бинарные логи, а не текстовый лог посгреса, так?
      дык вот посгрес и должен писать бинлоги в $PGDATA/pg_xlog , это абсолютно нормально. мастер пишет бинлоги туда, вместе с этим, если включен archive_mode - то указанной командой эти бинлоги _дополнительно_ будут копироваться куда указано (в pg_xlog при этом писаться они не перестают). слейв аналогично - свои бинлоги пишет в pg_xlog, а если в recovery.conf прописана restore_command - то периодически накатывает бинлоги из указанного места, для ускорения репликации.
      вообще, если не ошибаюсь, то смонтированная nfs-шара тупо подвешивает i/o при обращении к ней, если сервер вдруг пропадает - возможно именно это у вас и происходит со слейвом после отвала мастера (слейв ведь проверяет эту папку на наличие новых бинлогов).

      в общем, уберите nfs и сделайте так:
      - выключите пока пгпул
      - настройте мастера с archive_mode как в моем предыдущем сообщении, используйте абсолютные пути везде
      - настройте слейв аналогично, recovery.conf и т.п.
      - запустите мастер, запускаете какой-нибуть небыстрый запрос (pgbench -T 30, например), запускаете слейва через небольшой промежуток времени и смотрите логи и процессы. на мастере должен быть процесс "postgres: archiver process", в логах слейва после запуска должны быть записи "restored log file "xxx" from archive", "consistent recovery state reached", "database system is ready to accept read only connections", "streaming replication successfully connected to primary".
      после этого проведите эксперимент с ручным файловером - убейте мастера и ручками сделайте триггер файл. слейв должен поднятся, в логах что-то вроде:
      LOG: trigger file found: /opt/pgsql/9.2/data//trigger_file
      LOG: redo done at 1D/CB002060
      LOG: last completed transaction was at log time 2013-10-09 12:02:37.257117+04
      LOG: restored log file "000000080000001D000000CB" from archive
      cp: cannot stat `/opt/pgsql/archive/00000009.history': No such file or directory
      LOG: selected new timeline ID: 9
      LOG: restored log file "00000008.history" from archive
      LOG: archive recovery complete
      LOG: database system is ready to accept connections
      ну и слейв должен полноценно обслуживать запросы.

      если все это заработает - можно включать пгпул и экспериментировать с ним.

      по libpcp.so.0 - вы ручками чтоли собирали его, через make install? значит где-то косяк был. где конкретно - не подскажу, запускайте pcp_recovery через strace и смотрите где же он конкретно пытается его найти.

      Удалить
  9. добрый день! у меня наконец-то заработал файловер!!!!!!!!!! я нашла ошибку-в конфиге постгреса стояла настройка для синхронной репликации, а не для асинхронной (было:synchronous_standby_names='*').
    Я хотела у Вас уточнить насчет recovery:
    -он поднимает только слейв,а для восстановления бывшего мастера нужна полная остановка пгпула?
    -pgpool_remote_start надо прописывать в конфиге или он так запускается?
    -strace пишет,что не находит:libresolve,libcrypt,libm,libc,libpcp,но они все есть только не в той директории где он ищет-делала ссылки все тоже самое.как то можно попробовать пересобрать библиотеку или еще что посоветуете...

    ОтветитьУдалить
    Ответы
    1. Поздравляю!
      синхронная репликация действительно зависает при отвале мастера/слейва, вроде бы какие-то новые параметры для фикса этого должны были появится в postgres-9.3, но я не проверял.

      recovery:
      - по факту лежать может только слейв, ибо если лежит мастер - пгпул запускает файловер и промоутит слейва до мастера. поэтому в любом случае восстанавливает он слейва (и не важно, что раньше он был мастером)
      - pgpool_remote_start нигде прописывать не нужно (да и негде). но этот скрипт именно с таким названием должен лежать в $PGDATA каталоге, именно там его ищет посгресовая рекавери-функция.

      с шаред либами посоветую только кардинальные действия - ибо ковырятся с пересбором и линками можно много и долго, а результата будет мало. да и вообще - самосбор в пакетном дистрибутиве это моветон и путь к разведению неподдерживаемой помойки.
      поставьте чистую систему, ставьте пгпул из пакетов (rpm-ки есть на оффсайте пгпула), а не самосбором. если нет пакета с новой версией - возьмите более старую версию пакета пгпула и пересоберите; chekinstall в конце-концов в бубунте; на крайняк - поставьте все из пакетов, включая зависимости для пгпула, а уже сам пгпул соберите заново из сорцов с отдельным префиксом

      Удалить
  10. здравствуйте! спасибо за помощь! вроде все наконец-то заработало!!!!!!!!!
    дело было то ли в системе, то ли в пгпуле. я сначала ставила 3.3.1 версию, а потом 3.3.0 на новую систему сделала только ldconfig и все пошло!
    и раз огромное спасибо-я бы без вас не разобралась!

    ОтветитьУдалить
  11. Здравствуйте,Юрий!При тестировании пгпула я столкнулась с такой проблемой:при выполнении запроса,например insert на 1000 записей,если отваливается один из бекендов, то в БД оказывается столько строк сколько успеет записаться.Пгпул при этом в логах ругается на то,
    что у него отключился один из бекендов и дальше НЕ выполняет запрос(файловер срабатывает нормально).Этот запрос приходится запускать еще раз,тогда при отключенном слейве данные нормально пишутся, а потом и синхронизируются с мастером.(синхр репл-отключена)

    Подскажите,пожалуйста, как избежать пропадания данных или это для пгпула нормально,что он разрывает текущие соединения (запросы) при падении одного из бекендов?..

    ОтветитьУдалить
    Ответы
    1. насколько я понял - это его нормальное поведение, в момент файловера он обрывает текущие соединения

      Удалить
    2. Здравствуйте, Юрий! Извините меня за надоедливость, но у меня опять возникло некоторое недопонимание, а обсудить не с кем...
      Сейчас у меня настроен пгпул с потоковой репликацией мастер-слейв (без ватчдога).Как я понимаю при файловере и рекавери(т.к. делается бэкап) всегда будет обрыв соединения с текущим запросом,так?
      Но вот если во время выполнения запроса у меня просто падает слейв,то запрос должен продолжаться?-это же ассинхронная репликация!но у меня почему-то все стопорится как при синхронной(пробовала без пгпула -все работает)не подскажите, что могло повлиять?

      Удалить
    3. А это ключевой косяк пгпула: при падении ноды (не важно какой, мастер/слейв) все клиентские подключения обрываются.
      Тут разработчик пгпула пишет, что это не исправить: http://www.sraoss.jp/pipermail/pgpool-general/2011-December/000053.html

      Удалить
  12. здравствуйте! настроил я связку по Вашему примеру.. когда падает мастер, в логах вижу, что выполняется failover.sh запуском через execute.. и слейв становится мастером.. вот при обратном возвращении мастера(который нужно сделать слейвом через постгресовские функции..) как увидеть, отследить, что они запустились..видно ли это в логах пгпула??

    ОтветитьУдалить
    Ответы
    1. после отработки recovery-скрипта восстановленная нода будет работать слейвом, это можно проверить наличием wal receiver процесса на ней и wal sender с хостнеймом слейва на мастере.
      также, можно сделать select * from pg_stat_replication; он должен показать вторую ноду и режим репликации.
      пгпул об этом ничего не узнает и не будет использовать восстановленную ноду до тех пор, пока ему руками не сказать pcp_attach_node

      Удалить
    2. да, но дело в том, что не скрипт почему-то не срабатывает... и старый мастер(который должен запуститься как уже слейв), запускается как бывший мастер, потому что файлик у него называется recovery.done... а если бы отработал то перед стартом как я понимаю он запустил бы скрипт, скопировал recover.done in recovery.conf нода бы запустилась как слейв, а не как мастер.. вот как устранить эту точно..

      Удалить
    3. Ну дебажить надо скрипт, не может же он просто тихо выполниться без результата.
      Если речь про мой скрипт из статьи для ручного рекавери - там есть пара ошибок: где вызывается pg_start_backup - должен быть cluster_master а не recovery_host, внутри рсинка сорцом должен быть просто recovery_dir, без cluster_master
      Собсна эти ошибки видно при первом запуске скрипта.
      Если какой-то Ваш самописный - проверяйте его, смысл-то должен быть понятен что от него требуется.

      Удалить
    4. здравствуйте) скрипты я брал сугубо из Вашей статьи.. у меня тут появились такие вопросы:
      1) можно ли настроить резервирование на двух машинах, то есть на одной машине настроить бд1 и пгпул1, а на второй - бд2 и пгпул2.. ??
      2) я выполняю online recovery по 2 варианту, то есть через постгресовские функции и библиотеку.. так вот, собственно сам вопрос: когда я выполняю под пользователем пострес команду pcp_recovery_node у меня в логах пгпула видно, что запускаемая команда на восстановление со статусом failed, а в pcp_recovery_node -d видна ошибка command failed. reason = recovery failed BackendError// хотя если руками запустить скрипт из строки recovery_1st_stage_command, то он корректно отрабатывает.. в чем может быть проблема??

      Удалить
    5. 1. можно, раздел 3 в статье
      2. из разряда "а вдруг" - попробуйте от рута запускать pcp_*, ну и перепроверьте все параметры авторизации и pcp.conf
      если не поможет - повысить уровень дебага и дебажить, может понятно что станет; попробовать strace-ом запустить

      ps: я сильно разочаровался в pgpool-е, слишком много граблей вылезают в разных местах. я бы посоветовал посмотреть в сторону pacemaker и его ресурса pgsql, настройка проще и ведет себя в разы предсказуемее, чем pgpool.

      Удалить