Как ждать, пока PostgreSQL будет запущен / восстановлен?

8

Я тестирую обновление PostgreSQL с 8.2.1 до 9.2 на виртуальной машине, работающей под управлением специального дистрибутива Linux. Процедура обновления выглядит следующим образом:

  1. Запустить pgсервис
  2. Вакуумные все БД (не уверен, если это необходимо)
  3. Резервное копирование с pg_dumpall
  4. Остановить pgслужбу
  5. Уберите каталог, в котором хранятся данные ( /var/pgэто простая настройка для одного сервера)
  6. Установите PostgreSQL 9.2
  7. initdb
  8. Запустите сервер
  9. Восстановить сброшенные данные
  10. reindexdb все БД
  11. Воссоздать referential_constraintsвид
  12. Очистить все базы данных (AFAIK требуется после этого обновления)

Эта процедура прекрасно работает на одном хосте, резервное копирование и восстановление без помех. На другом компьютере с другой базой данных точки с 1 по 7 работают нормально, но сервер не запустится, пока я не добавлю sleep 1после initdb, и даже тогда сброшенные данные не могут быть восстановлены, потому что «система базы данных запускается ». Каковы стандартные способы борьбы с этим, кроме этих ужасных хаков:

  1. sleepв течение некоторого времени перед любой операцией,
  2. цикл до тех пор, пока он не сработает, или пока не будет достигнут щедрый таймаут, или
  3. цикл до тех пор, пока он не примет тривиальный запрос или не истечет время ожидания.

Изменить: « Решение » не сработало в конце концов. Что нужно для того, чтобы база данных была готова к восстановлению?

l0b0
источник
Просто идея: вы можете проверить initdbстатус выхода? Я полагаю, когда он установлен, работа сделана.
Дезсо
@dezso Нет, initdbвыполняется синхронно, поэтому, когда сервер запущен, initdbон уже успешно завершен.
10
Тогда у меня нет лучшей идеи, чем зациклить простой тест, который проверяет, что все готово.
Дезсо
2) не нужно. 10) также не требуется, поскольку при восстановлении дампа восстанавливаются все индексы.
a_horse_with_no_name

Ответы:

5

initdb не возвращается, пока не закончится, поэтому не должно быть никакой паузы между ним и запуском сервера. В PostgreSQL были ошибки, когда он завершался без предварительной записи всего на диск. Я не знаю ни одного левого в данный момент, но природа ошибок заключается в том, что вы не всегда знаете о них.

Если вы используете команду pg_ctl для запуска базы данных, используйте параметры "-w", чтобы дождаться завершения запуска перед возвратом. Он не делает ничего особенного - он просто "готов?" петля для вас.

Обратите внимание, что если вы получаете сбой сервера с большим количеством данных, которые необходимо воспроизвести перед запуском сервера, время ожидания, установленное параметром -t в ожидании pg_ctl, может быть слишком низким.

Нет никаких оснований для VACUUM исходных баз данных перед выполнением их pg_dump. Хотя это может немного ускорить сброс, сам вакуум займет больше времени, чем это улучшение.

Грег Смит
источник
Требуется ли 12. шаг? Я ожидаю, что таблицы будут смежными (или почти смежными после pg_restore -j{morethan1}).
Дезсо
Мы бежим, postmasterчтобы запустить демона, и у него нет такой возможности.
10
2

за работойНеисправным решением было модифицировать сценарий инициализации, чтобы повторно проверять, используется ли соответствующий порт. Если он не появляется через минуту, запуск считается сбойным. Псевдо-код:

start() {
    pg start
    checks=0
    while checks < 30:
        return true if the port is in use
        sleep 2
        checks++
    return false
}

Edit: оказывается , что это не достаточно. Шаг восстановления:

PGOPTIONS='--client-min-messages=warning' psql \
    --no-psqlrc \
    --variable=ON_ERROR_STOP=1 \
    --quiet \
    --log-file="$restore_log" \
    --single-transaction \
    --username postgres \
    --file="$sql_backup"

Сообщение об ошибке:

psql: FATAL:  the database system is starting up
l0b0
источник