Сигналы и перезагрузка
pg_doorman реагирует на четыре POSIX-сигнала: SIGHUP, SIGINT, SIGUSR2 и SIGTERM. Каждый делает одну конкретную вещь.
Краткая справка
| Сигнал | Эффект | Существующие соединения | Когда применять |
|---|---|---|---|
SIGHUP | Перезагрузить конфиг с диска. | Сохраняются. | Подкрутить пулы, ротировать серверные TLS-сертификаты, отредактировать pg_hba.conf. |
SIGTERM | Немедленное завершение. | Закрываются. | Остановка сервиса, когда переподключения допустимы. |
SIGUSR2 | Горячая замена процесса: новый бинарь и конфиг, затем дренирование старого процесса. | Мигрируют в новый процесс, где это возможно; TLS требует tls-migration. | Раскатить изменения, которым нужен новый процесс. |
SIGINT | Зависит от TTY (см. ниже). | По-разному. | Ctrl+C при разработке; устарело для промышленной эксплуатации. |
Перезагрузка (SIGHUP)
kill -HUP $(pidof pg_doorman)
Перечитывает файл конфига и применяет изменения. Что перезагружается:
- Определения пулов (добавлены, удалены, изменён размер).
- Списки пользователей, пароли, блоки
auth_query. - Правила
pg_hba.conf(файл или встроенное содержимое). - Серверные TLS-сертификаты и CA-бандлы (подмена без блокировок; существующие TLS-соединения сохраняют исходный контекст).
- Публичные ключи Talos и JWT.
- Уровень логирования и формат логов.
Что не перезагружается:
general.host,general.port— слушающий сокет фиксируется при старте.general.tcp_socket_buffer_sizeдля уже открытых сокетов — новое значение применяется только при приёме нового клиентского TCP-сокета или открытии нового TCP-сокета к PostgreSQL.- TLS-сертификаты для входящих клиентских подключений — нужен перезапуск процесса. Не ротируйте их во время горячей замены, где нужна миграция TLS-сессий.
- Число рабочих потоков и параметры рантайма Tokio.
После SIGHUP SHOW CONFIG показывает новые значения. Уже открытые клиентские соединения не проверяются заново по pg_hba.conf; новые правила действуют только для новых подключений. Уже открытые TCP-сокеты сохраняют размер буфера, заданный при их создании.
Немедленное завершение (SIGTERM)
kill -TERM $(pidof pg_doorman)
pg_doorman логирует, сколько клиентов ещё в транзакциях, и выходит. Он
не ждёт shutdown_timeout и не мигрирует активные транзакции. Все
клиентские соединения закрываются при выходе процесса.
shutdown_timeout относится к дренированию при горячей замене процесса
через SIGUSR2, а не к обычному завершению по SIGTERM.
Горячая замена процесса (SIGUSR2)
kill -USR2 $(pidof pg_doorman)
Рекомендуемый способ заменить процесс, не теряя мигрируемых клиентов:
- Замените бинарник и/или конфиг на диске.
- Отправьте
SIGUSR2работающему процессу. - Текущий процесс проверяет новый бинарник с конфигом через
-t. - Текущий процесс порождает дочерний процесс с теми же аргументами запуска, передаёт ему слушающий сокет и продолжает обслуживать существующих клиентов до миграции или завершения.
- Новые клиенты сразу подключаются к дочернему процессу.
- Старый процесс выходит, когда клиенты мигрировали или отключились (или по
shutdown_timeout).
Дочерний процесс отправляет sd_notify MAINPID=<new_pid>, чтобы юниты
systemd с Type=notify корректно отслеживали новый главный PID.
Если при горячей замене изменён general.tcp_socket_buffer_size, новый
процесс применяет его к мигрировавшим клиентским TCP-сокетам при
восстановлении клиента. Backend-сокеты через SCM_RIGHTS не передаются:
новые backend-соединения получают настройку при открытии, а старые
остаются в старом процессе до дренирования.
Полный протокол, миграцию TLS и откат смотрите в горячей замене процесса с переносом сессий.
SIGINT (Ctrl+C)
SIGINT зависит от контекста:
- На переднем плане с TTY (разработка,
cargo run): только завершение работы. - В режиме демона или без TTY: запускает горячую замену процесса и
дренирование старого процесса, как
SIGUSR2, для совместимости со старыми установками.
Путь горячей замены через SIGINT существует ради обратной совместимости с инсталляциями, которые отправляют SIGINT из init-скриптов. Новые инсталляции должны явно использовать SIGUSR2 для горячей замены и SIGTERM для остановки.
Интеграция с systemd
pg_doorman поддерживает Type=notify. Поставляемый юнит pg_doorman.service запускает бинарник в основном процессе и уведомляет systemd через sd_notify:
[Service]
Type=notify
NotifyAccess=exec
ExecStart=/usr/bin/pg_doorman /etc/pg_doorman/pg_doorman.toml
ExecReload=/bin/kill -SIGUSR2 $MAINPID
ExecStop=/bin/kill -SIGTERM $MAINPID
SyslogIdentifier=pg_doorman
KillMode=mixed
TimeoutStopSec=60
Restart=on-failure
Nice=-15
User=postgres
Group=postgres
LimitNOFILE=65536
sd_notify READY=1 отправляется после привязки слушающего сокета и инициализации пулов. sd_notify MAINPID=<child> отправляется при горячей замене процесса, чтобы systemd корректно отслеживал новый процесс.
С таким юнитом systemctl reload pg_doorman означает горячую замену
процесса (SIGUSR2), а не перечитывание конфига (SIGHUP). Если нужно
только перечитать конфиг, используйте kill -HUP <pid>.
Если переходите с Type=forking + --daemon, уберите --daemon и переключитесь на Type=notify — меньше движущихся частей и корректное отслеживание готовности. Старые инсталляции с --daemon продолжают работать, но не получают преимуществ sd_notify.
Режим демона
pg_doorman --daemon ответвляется в фон и пишет PID в daemon_pid_file (по умолчанию /tmp/pg_doorman.pid). Под systemd предпочитайте Type=notify вместо --daemon.
general:
daemon_pid_file: "/var/run/pg_doorman.pid"
Куда дальше
- Горячая замена процесса с переносом сессий — полный протокол замены с миграцией TLS.
- Диагностика — что проверить, когда перезагрузка не подхватывает изменения.
- TLS — семантика перезагрузки серверных сертификатов по
SIGHUP.