Запуск PostgreSQL с Supervisord

Я хочу запустить PostgreSQL 9.1 с помощью Supervisor в Ubuntu 10.04. На данный момент я вручную запускаю PostgreSQL с помощью скрипта инициализации:

/etc/init.d/postgresql start

Согласно этому сообщению: http://nicksergeant.com/using-postgresql-with-supervisor-on-ubuntu-1010/, мне нужно изменить конфигурацию PostgreSQL, чтобы она работала на порту TCP вместо сокета Unix, чтобы PostgreSQL работал с Supervisor.

У меня есть два вопроса относительно этого подхода:

  1. Учитывая, что это скорее взлом, есть ли какие-либо последствия (например, безопасность/разрешения, производительность и т. д.) для этого?

  2. Почему мы не можем просто запустить тот же сценарий инициализации postgresql в конфигурации супервизора? Вместо этого, как показано в ссылке выше, он запускает postmaster?

ОБНОВЛЕНИЕ:

Благодаря полезным предложениям из обоих ответов ниже, я настроил скрипт для Supervisor для прямого вызова PostgreSQL:

#!/bin/sh

# This script is run by Supervisor to start PostgreSQL 9.1 in foreground mode

if [ -d /var/run/postgresql ]; then
    chmod 2775 /var/run/postgresql
else
    install -d -m 2775 -o postgres -g postgres /var/run/postgresql
fi

exec su postgres -c "/usr/lib/postgresql/9.1/bin/postgres -D /var/lib/postgresql/9.1/main -c config_file=/etc/postgresql/9.1/main/postgresql.conf"

Я также установил конфиг: /etc/postgresql/9.1/main/start.conf в manual, чтобы PostgreSQL не запускался автоматически при загрузке (правда, мне непонятно, загружается ли этот конфиг). Затем я настраиваю конфигурацию Supervisor для postgres следующим образом:

[program:postgres]
user=root
group=root
command=/usr/local/bin/run_postgresql.sh
autostart=true
autorestart=true
stderr_logfile=/home/www-data/logs/postgres_err.log
stdout_logfile=/home/www-data/logs/postgres_out.log
redirect_stderr=true
stopsignal=QUIT

Итак, теперь я могу запустить PostgreSQL в supervisorctl, выполнив start postgres, и все работает нормально. Однако после того, как я выдал stop postgres, хотя supervisorctl объявляет, что postgres остановлен, сервер, по-видимому, все еще работает, так как я могу подключиться к нему с помощью psql.

Интересно, это проблема конфигурации Supervisor или проблема PostgreSQL? Любое предложение приветствуется!


person MLister    schedule 18.06.2012    source источник


Ответы (3)


Сообщение в блоге написано довольно плохо. Там нет «режима TCP»: предложенный в сообщении метод по-прежнему будет прослушивать сокет Unix, просто в другом каталоге. Комментарии в сообщении, такие как «внешний файл pid - не требуется для режима TCP», очень вводят в заблуждение.

postmaster — это традиционное имя исполняемого файла postgresql (чтобы отличить главный диспетчерский процесс от серверных подчиненных). С некоторых пор нет отдельного экзешника, и теперь он устанавливается как просто "postgres".

Предполагая, что Supervisor в целом похож на схему qmail/daemontools supervise, было бы вполне возможно (на самом деле вполне нормально) запустить сценарий, который устанавливает каталоги и среду, а затем запускает postgres с необходимыми аргументами (или распространяет аргументы, переданные сценарию-оболочке, что было бы необычно для супервизора, но имеет больше смысла, когда у вас есть файл конфигурации, в который можно поместить аргументы).

Способ supervise работал (и я собираюсь продолжать предполагать, что «Supervisor» тот же самый) заключается в том, чтобы процесс супервизора запускал подпроцесс, как указано, и просто перезапускал новый подпроцесс, если он завершается. Это основано на идее, что запускаемый процесс является долгоживущим процессом-демоном, который завершается только тогда, когда что-то идет не так, и что простой его перезапуск является допустимым решением. Напротив, сценарии инициализации, такие как в /etc/init.d, запускают подпроцесс и отсоединяют его, а также возвращают управление вызывающей стороне — если подпроцесс завершается, ничего особенного не происходит, и его необходимо перезапустить вручную. Если вы попытаетесь просто запустить /etc/init.d/postgresql start из супервизора, он будет постоянно порождать демоны postgresql, поскольку возврат из сценария инициализации будет интерпретироваться как завершение процесса демона, хотя на самом деле он был запущен и отсоединен.

person araqnid    schedule 18.06.2012
comment
спасибо за то, что вы указали на мой второй вопрос, это было хорошо объяснено! Что касается моего первого вопроса (и вашей интерпретации того, что на самом деле происходит со скриптом в ссылке), вы предлагаете мне написать скрипт, который создает необходимый каталог для postgresql, а затем запускает postmaster (или postgres?) с исходным postgresql config и вместо этого вызвать этот сценарий в файле конфигурации Supervisor? - person MLister; 19.06.2012
comment
Правильно, у вас может быть сценарий оболочки, который в основном выполняет [ -d /run/postgresql ] || make_rundir ; exec /usr/lib/postgresql/9.1/postgres "$@", который при необходимости создаст каталог, а затем соединит исполняемый файл postgres (postmaster теперь является устаревшим именем). С супервизией это буквально называлось бы run внутри сервисного каталога. - person araqnid; 19.06.2012
comment
Ваше предположение, что supervisord работает так же, как supervise, верно; он запустит и возродит подпроцесс для демонов, находящихся под его ответственностью. - person Martijn Pieters; 19.06.2012

Чтобы избежать автоматического запуска службы с помощью сценариев /etc/init.d, пакет для postgresql 9.1 предоставляет файл /etc/postgresql/9.1/main/start.conf, который содержит:

# Automatic startup configuration
# auto: automatically start/stop the cluster in the init script
# manual: do not start/stop in init scripts, but allow manual startup with
#         pg_ctlcluster
# disabled: do not allow manual startup with pg_ctlcluster (this can be easily
#           circumvented and is only meant to be a small protection for
#           accidents).

auto

Это файл, который нужно изменить, чтобы избежать автоматического запуска, а не удалять /etc/init.d/postgresql, как предлагает сообщение в блоге.

Кроме того, изменение параметров unix-сокетов из-за отсутствия /var/run/postgresql выглядит не лучшей идеей, потому что это значение по умолчанию для любой программы, связанной с libpq, и потому что создать этот каталог с соответствующими правами несложно, как это делает последовательность запуска пакета в /usr/share/postgresql-common/init.d-functions:

# create socket directory
if [ -d /var/run/postgresql ]; then
    chmod 2775 /var/run/postgresql
else
install -d -m 2775 -o postgres -g postgres /var/run/postgresql
fi

И хотя значение по умолчанию не должно вызывать проблем, обратите внимание, что то, останется ли postmaster в конечном итоге на переднем плане или разветвится и запустится в фоновом режиме, контролируется silent_mode в postgresql.conf. Убедитесь, что он выключен.

person Daniel Vérité    schedule 19.06.2012
comment
спасибо за длинное объяснение. Два вопроса: 1. почему мы хотим избежать автозапуска /etc/init.d/postgresql? Это мне непонятно в исходной статье; 2. Основываясь на вашем ответе выше, кажется, что нужно изменить только две вещи, чтобы это работало с Supervisor: во-первых, перейти на ручной в /etc/postgresql/9.1/main/start.conf, а во-вторых, установить параметр «silent_mode» в /etc/postgresql/9.1/main/postgresql.conf выкл. Это правильно? - person MLister; 19.06.2012
comment
1: если бы postgresql запускался при загрузке, он был бы вне контроля супервизора, что противоречит цели: держать демонов под контролем супервизора. 2: да - person Daniel Vérité; 19.06.2012
comment
Понимаю. Замечательно! Но мне нужно создать скрипт, содержащий указанную выше часть для создания необходимого каталога и установки разрешений, а затем вызвать исполняемый файл postresql (кстати, какой исполняемый файл я должен использовать: /usr/lib/postgresql/9.1/bin/postgres или /usr/lib/postgresql/9.1/bin/pg_ctl?)? А затем запустить этот скрипт с супервизором? еще раз спасибо! - person MLister; 19.06.2012
comment
Да, вам нужно создать этот скрипт. И он должен запускать /usr/lib/postgresql/9.1/bin/postgres (не pg_ctl) как минимум с аргументом -D для каталога данных. - person Daniel Vérité; 20.06.2012
comment
еще раз спасибо. Я пробовал вышеописанное с этой строкой, которая вызывает PostgreSQL: exec /bin/su - postgres -c "/usr/lib/postgresql/9.1/bin/postgres -D /var/lib/postgresql/9.1/main -c config_file=/etc/postgresql/9.1/main/postgresql.conf, которая следует за созданием/разрешением каталога, как указано выше. Однако, когда я запускаю сценарий через Supervisor, он терпит неудачу, и я получаю «su: необходимо запустить с терминала» в журнале. Возможно, проблема с разрешением в Supervisor? - person MLister; 20.06.2012
comment
@MLister Я думаю, вы просто хотите su postgres -c ..., а не su - postgres -c ... (дополнительный тире пытается настроить новую оболочку входа в систему, что в данном случае не совсем подходит) - person araqnid; 21.06.2012
comment
@araqnid, спасибо, что указали на это, поэтому я изменил его, но он по-прежнему жалуется на то же сообщение, и скрипт не выполнен (кстати, в моем комментарии выше в конце должен был быть - просто опечатка) Я подозреваю, что это файл проблема с разрешением/владением, и вот подробности: -rwxr-xr-x 1 root root. Они выглядят нормально для меня. - person MLister; 21.06.2012
comment
@araqnid, обновление: поэтому я меняю пользователя на root в файле конфигурации Supervisor для запуска postgres, и теперь скрипт запускается нормально. Однако, когда я пытаюсь остановить его через Supervisor, то есть stop postgres в supervisorctl, он, похоже, не останавливает сервер, хотя утверждает, что делает это... Интересно, что происходит. - person MLister; 21.06.2012
comment
@MLister процесс postgres принадлежит непосредственно супервизору? (т. е. если вы сделаете ps uaxf, сможете ли вы увидеть, что postgres напрямую связано с supervisord). Глядя на postgresql.org/docs/current/static/server-shutdown. html SIGQUIT должен работать (хотя вам может понадобиться другой параметр stopsignal в долгосрочной перспективе). Если между supervisord и postgres есть дополнительный процесс оболочки, вам может понадобиться где-то дополнительный exec. - person araqnid; 21.06.2012
comment
@MLister ах, если бы вы запускали su без полномочий root, он хотел бы, чтобы терминал запрашивал пароль. Иногда sudo удобнее использовать как способ запуска команд под разными пользователями. - person araqnid; 21.06.2012
comment
давайте продолжим это обсуждение в чате - person MLister; 21.06.2012
comment
@araqnid, на самом деле дерево процессов показывает, что postgres не связан с supervisord, а существует как отдельный процесс. Это может объяснить, почему supervisord не может его остановить. Это потому, что подход сценария-оболочки, который я использую для вызова postgres? - person MLister; 21.06.2012

Я пытаюсь запустить как tomcat, так и postgres под супервизором и нашел здесь несколько советов: https://serverfault.com/questions/425132/controlling-tomcat-with-supervisor

Вот мой модифицированный run_postgresql.sh с использованием bash:

#!/bin/bash

# This script is run by Supervisor to start PostgreSQL 9.1 in foreground mode

function shutdown()
{
    echo "Shutting down PostgreSQL"
    pkill postgres
}

if [ -d /var/run/postgresql ]; then
    chmod 2775 /var/run/postgresql
else
    install -d -m 2775 -o postgres -g postgres /var/run/postgresql
fi

# Allow any signal which would kill a process to stop PostgreSQL
trap shutdown HUP INT QUIT ABRT KILL ALRM TERM TSTP

exec sudo -u postgres /usr/lib/postgresql/9.1/bin/postgres -D /var/lib/postgresql/9.1/main --config-file=/etc/postgresql/9.1/main/postgresql.conf

С этим скриптом postgresql корректно останавливается после supervisorctl stop postgres.

person grams    schedule 10.04.2014