← Все заметки
Мониторинг и безопасность

Мониторинг PostgreSQL / Postgres Pro через Prometheus и postgres_exporter

Production-подход к мониторингу PostgreSQL и Postgres Pro через postgres_exporter, Prometheus и Grafana с отделением метрик БД от обычного Linux-мониторинга.

Статус: актуальноОпубликовано: 2026-09-16Обновлено: 2026-09-16

Проверено на: AlmaLinux 9.8 · Postgres Pro 1C 17.10 · postgres_exporter systemd deployment · Prometheus · Grafana

Контекст

Обычный мониторинг Linux показывает CPU, память, файловые системы и сеть, но этого недостаточно для диагностики большинства проблем на уровне СУБД.

В production-стеке 1С сервер БД работает на AlmaLinux 9.8 с Postgres Pro 1C 17.10 и отдаёт метрики через отдельный postgres_exporter.service в Prometheus и Grafana.

Поэтому мониторинг разделён на два уровня:

метрики Linux -> CPU / RAM / filesystem / network
метрики PostgreSQL -> sessions / transactions / locks / checkpoints / DB state

Рабочий Linux-хост ещё не означает здоровую БД.

Подтверждённый production baseline

OS: AlmaLinux 9.8
Database: Postgres Pro 1C 17.10
Database listener for exporter: loopback
Exporter service: postgres_exporter.service
Exporter port: 9187
Metrics backend: Prometheus
Visualization: Grafana

Точную версию бинарника postgres_exporter не утверждаю: на работающем сервере вызов postgres_exporter --version не вернул строку версии.

Реальная схема systemd

Exporter работает от отдельной непривилегированной учётной записи:

[Service]
Type=simple
User=postgres_exporter
Group=postgres_exporter

Подключение к БД локальное:

Environment="DATA_SOURCE_URI=127.0.0.1:5432/postgres?sslmode=disable"
Environment="DATA_SOURCE_USER=postgres_exporter"
Environment="DATA_SOURCE_PASS_FILE=/etc/postgres_exporter/password"

Это даёт несколько полезных свойств:

Содержимое /etc/postgres_exporter/password в Git и документацию не публикуется. Права на файл должны оставаться минимально необходимыми.

Фактический запуск exporter

Production unit запускает:

/usr/local/bin/postgres_exporter \
  --config.file= \
  --web.listen-address=<db-host-ip>:9187 \
  --collector.database_wraparound \
  --collector.long_running_transactions \
  --collector.postmaster \
  --collector.stat_checkpointer \
  --no-collector.stat_replication

Внутренний IP в публичной статье намеренно заменён placeholder’ом.

Unit явно задаёт пустой --config.file= и использует environment variables для параметров подключения к БД.

Включены collectors:

database_wraparound
long_running_transactions
postmaster
stat_checkpointer

Сбор replication metrics отключён:

--no-collector.stat_replication

Collector имеет смысл включать тогда, когда за ним стоит конкретный эксплуатационный вопрос или alert, а не просто потому, что он существует.

Сетевой listener

Exporter не слушает 0.0.0.0.

Он привязан к одному внутреннему адресу:

<db-host-ip>:9187

Проверка:

ss -lntp | grep -E ':9187\b|postgres_exporter'

Это лучше, чем публикация endpoint на всех интерфейсах. При этом firewall всё равно должен разрешать TCP/9187 только со стороны Prometheus.

Порядок запуска сервисов

Unit содержит:

After=network-online.target postgrespro-1c-17.service
Wants=network-online.target

То есть exporter запускается после поднятия сети и сервиса Postgres Pro 1C 17.

Это правильный порядок, но он не заменяет runtime-проверку: после рестарта БД нужно убедиться, что exporter снова успешно собирает metrics.

Hardening systemd

Production unit уже достаточно жёстко ограничен:

NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=strict
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
LockPersonality=true
RestrictSUIDSGID=true
RestrictRealtime=true
CapabilityBoundingSet=
AmbientCapabilities=

Для exporter это подходящая модель: ему не нужны elevated capabilities, доступ к kernel modules или возможность писать по всей файловой системе.

Если будущий collector потребует дополнительных прав, их лучше добавлять точечно, а не ослаблять unit заранее.

Проверка работающего exporter

Состояние сервиса:

systemctl status postgres_exporter --no-pager
systemctl is-enabled postgres_exporter

Эффективный unit:

systemctl cat postgres_exporter

Listener:

ss -lntp | grep -E ':9187\b|postgres_exporter'

Так как exporter привязан к внутреннему адресу, а не к loopback, endpoint нужно проверять по этому адресу из разрешённого monitoring path:

curl -fsS http://<db-host-ip>:9187/metrics | head

После этого смотрим журнал:

journalctl -u postgres_exporter -n 100 --no-pager

Доступный /metrics подтверждает только работу HTTP endpoint. Повторяющиеся ошибки database collection всё равно означают неисправный monitoring path.

Учётная запись БД

Exporter использует отдельную DB account:

postgres_exporter

Ей нужны только права, необходимые включённым collectors.

Не нужно переиспользовать:

учётку приложения
postgres superuser
учётку сервиса 1С

По возможности используйте штатные monitoring roles PostgreSQL/Postgres Pro и добавляйте только те grants, которые реально нужны custom queries.

Prometheus scrape model

Обезличенный пример:

scrape_configs:
  - job_name: postgresql
    static_configs:
      - targets:
          - db01.example.net:9187
        labels:
          service: postgresql
          role: database

Перед применением изменений:

promtool check config /etc/prometheus/prometheus.yml

После reload/restart проверьте UP target и то, что DB metrics действительно меняются во времени.

Что мониторить

Connections и long-running transactions

Следите за числом сессий относительно реального max_connections и за аномальным ростом.

Collector long_running_transactions важен, потому что долгие транзакции могут удерживать locks, мешать cleanup и увеличивать bloat.

Transaction activity и locks

Сопоставляйте transaction rate и contention с CPU/I/O сервера и ошибками приложения.

Медленная 1С может упираться в БД, но также в storage, сеть или application tier.

Checkpoints

Collector stat_checkpointer даёт видимость checkpoint activity.

Эти метрики полезно коррелировать со storage latency и write pressure, а не оценивать отдельно.

Postmaster state

Collector postmaster позволяет контролировать состояние основного процесса PostgreSQL на уровне БД, а не только факт открытого TCP-порта.

Transaction ID wraparound

database_wraparound нужен для контроля риска exhaustion/wraparound transaction IDs — это типичный пример состояния, которое невозможно качественно увидеть через обычный Linux monitoring.

Replication

В текущем unit replication collector отключён.

Если позже появится репликация, сначала нужно определить нормальные значения lag/slot/replay state, а затем включать соответствующий collector и alerts.

Структура Grafana dashboard

Полезная структура:

Overview
  -> exporter / DB availability
  -> connections
  -> long-running transactions
  -> transaction activity
  -> locks / contention
  -> checkpoint activity
  -> wraparound risk
  -> host CPU / RAM / storage

Host panels лучше держать рядом с DB panels, чтобы сразу было видно, проблема находится в PostgreSQL или ниже, на уровне ресурсов сервера.

Alerting

Полезнее alert’ить на actionable conditions:

exporter недоступен
PostgreSQL недоступен
connections приближаются к лимиту
long-running transactions превышают допустимое время
длительное lock/contention состояние
checkpoint/write pressure выходит за baseline
растёт риск transaction ID wraparound
filesystem/storage приближается к заполнению

Пороги должны основываться на реальной нагрузке 1С и maintenance model.

Граница с мониторингом 1С

PostgreSQL monitoring не доказывает здоровье application tier 1С.

Он не отвечает напрямую на вопросы:

запущен ли нужный instance 1С
доступна ли информационная база пользователям
выполняются ли операции приложения
здоров ли кластер 1С

На production-хосте уже есть отдельный сервис/таймер метрик 1С, поэтому application-level monitoring нужно описывать отдельно.

Безопасность

Текущая модель уже правильно разделяет доступ:

Monitoring не должен становиться вторым административным каналом в БД.

Backup и rollback

Перед изменением exporter сохраняйте:

/etc/systemd/system/postgres_exporter.service
metadata/permissions /etc/postgres_exporter/password
Prometheus scrape config
Grafana dashboards/provisioning
alert rules

Сам пароль копировать в Git или документацию не нужно.

Rollback должен возвращать предыдущую monitoring configuration и не затрагивать application database.

Проверка после изменений

[ ] postgres_exporter.service active
[ ] exporter работает от postgres_exporter user/group
[ ] подключение к PostgreSQL остаётся на loopback
[ ] password file-backed и не находится в ExecStart
[ ] exporter слушает только нужный внутренний адрес:9187
[ ] firewall ограничивает 9187 monitoring path
[ ] в journal нет повторяющихся collection errors
[ ] Prometheus target = UP
[ ] DB metrics меняются
[ ] Grafana показывает свежие данные

Ссылки