Гайды
Мониторинг PostgreSQL: Prometheus, Grafana и postgres_exporter
Роль postgres_exporter, scrape в Prometheus, дашборды Grafana, pg_stat_statements и базовые алерты.
~16 мин чтения
Мониторинг PostgreSQL: Prometheus, Grafana и postgres_exporter
Типичный стек: postgres_exporter (метрики с /metrics) → Prometheus (scrape + хранение + правила) → Grafana (дашборды и алерты). Ниже — установка экспортера, job в Prometheus, импорт дашборда и минимальный набор алертов.
Архитектура
- postgres_exporter подключается к БД и экспортирует метрики в формате Prometheus (в т.ч. из
pg_stat_*). - Prometheus периодически опрашивает
:9187/metrics, хранит временные ряды, может слать алерты в Alertmanager. - Grafana использует Prometheus как data source и строит панели.
Пользователь только для мониторинга
CREATE USER postgres_exporter WITH PASSWORD 'YOUR_PASSWORD_HERE';
ALTER USER postgres_exporter SET search_path TO postgres_exporter, public;
GRANT CONNECT ON DATABASE postgres TO postgres_exporter;
GRANT pg_monitor TO postgres_exporter;
Роль pg_monitor даёт чтение большинства нужных представлений. Для pg_stat_statements дополнительно включите расширение и выдайте SELECT (см. ниже).
Установка postgres_exporter (Linux amd64, пример v0.15.0)
wget https://github.com/prometheus-community/postgres_exporter/releases/download/v0.15.0/postgres_exporter-0.15.0.linux-amd64.tar.gz
tar -xvf postgres_exporter-0.15.0.linux-amd64.tar.gz
sudo mv postgres_exporter-0.15.0.linux-amd64/postgres_exporter /usr/local/bin/
sudo useradd --no-create-home --shell /bin/false postgres_exporter
sudo chown postgres_exporter:postgres_exporter /usr/local/bin/postgres_exporter
systemd unit
sudo tee /etc/systemd/system/postgres-exporter.service > /dev/null << 'EOF'
[Unit]
Description=PostgreSQL Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=postgres_exporter
Group=postgres_exporter
Type=simple
ExecStart=/usr/local/bin/postgres_exporter \
--web.listen-address=:9187 \
--web.telemetry-path=/metrics
Environment=DATA_SOURCE_NAME=postgresql://postgres_exporter:YOUR_PASSWORD_HERE@localhost:5432/postgres?sslmode=disable
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl start postgres-exporter
sudo systemctl enable postgres-exporter
Проверка: http://<host>:9187/metrics — метрики с префиксом pg_. Откройте порт в фаерволе при необходимости:
sudo ufw allow 9187/tcp
Prometheus: scrape_configs
scrape_configs:
- job_name: 'postgresql'
static_configs:
- targets: ['127.0.0.1:9187']
labels:
instance: 'prod-db-01'
environment: 'production'
После reload/restart Prometheus в Status → Targets job должен быть UP.
Grafana
- Configuration → Data sources → Add → Prometheus — URL вашего Prometheus (
http://prometheus:9090и т.д.), Save & test. - Dashboards → Import — можно импортировать популярные дашборды с grafana.com по ID (например, варианты под
postgres_exporterпериодически обновляются; проверяйте совместимость метрик и версию экспортера).
Примеры PromQL
- Коммиты:
rate(pg_stat_database_xact_commit{datname="mydb"}[1m]) - Подключения:
pg_stat_database_numbackends - Размер БД:
pg_database_size_bytes - Cache hit (оценочно): отношение
blks_hitк суммеblks_hit + blks_readчерезrate(...[5m]) - Репликационный лаг: метрики семейства
pg_replication_*/ специфичные к вашему дашборду
Алерты
В Grafana (упрощённо)
Например, доля использованных подключений к лимиту — панель + alert rule с порогом 80% на 5+ минут.
В Prometheus (rules.yml, пример)
groups:
- name: postgresql_alerts
rules:
- alert: PostgresHighConnections
expr: (sum(pg_stat_database_numbackends) / max(pg_settings_max_connections)) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High connection usage on {{ $labels.instance }}"
Минимальный набор смысловых алертов:
| Алерт | Идея |
|---|---|
| База недоступна для scrape | up{job="postgresql"} == 0 или отсутствие ключевых метрик |
| Высокая утилизация коннектов | Как выше |
| Ошибки экспортера | Метрики вида pg_exporter_last_scrape_error (если доступны в вашей версии) |
pg_stat_statements
В postgresql.conf:
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all
Перезапуск кластера, затем в целевой БД:
CREATE EXTENSION pg_stat_statements;
GRANT SELECT ON pg_stat_statements TO postgres_exporter;
На дашбордах появятся топы запросов по времени / I/O — без этого «слепые зоны» по SQL.
Kubernetes (набросок service discovery)
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
regex: postgres-exporter
action: keep
Типичные ошибки
| Симптом | Что проверить |
|---|---|
| Target DOWN | systemctl status postgres-exporter, фаервол, URL в Prometheus |
| Нет части метрик | Отдельный DSN на каждую БД, коллекторы / флаги версии экспортера |
| 500 в логах экспортера | scrape_interval, нагрузка на БД от частых запросов метрик |
Пустой pg_stat_statements | shared_preload_libraries, перезапуск, CREATE EXTENSION, права |
Альтернативы «в коробке»
- pgwatch2 — сбор + хранение + готовые Grafana-дашборды.
- Pigsty и др. — для крупных сред с множеством инстансов.
Итог
Начните с отдельного пользователя с минимальными правами, поднимите postgres_exporter как сервис, добавьте scrape в Prometheus, подключите Grafana и импортируйте проверенный дашборд. Затем включите pg_stat_statements и заведите алерты на доступность и saturation — иначе мониторинг декоративен.