PostgreSQL
Мониторинг PostgreSQL
Ночь. Production PostgreSQL медленнее чем обычно. Без мониторинга: DBA подключается, бегает по pg_stat_* запросам, 40 минут диагностики. С Grafana: открыть дашборд, 30 секунд - visible spike в lock_wait_time, zoom in, найти PID держащий lock 2 часа, pg_terminate_backend, всё. Мониторинг - это разница между паникой и уверенностью.
- **Heroku** - postgres_exporter + Datadog для всех managed PostgreSQL инстансов: 50+ метрик, автоматические алерты на wraparound, replication lag, high connections
- **Gitlab** - открытый дашборд Grafana для PostgreSQL: https://dashboards.gitlab.com - мониторинг production БД Gitlab.com в реальном времени публично доступен
- **Supabase** - встроенный мониторинг для каждого проекта: cache hit ratio, active queries, slow query log, autovacuum activity в UI без настройки
pg_stat_activity: что делает БД прямо сейчас
**pg_stat_activity** - главный диагностический view. Показывает каждое активное соединение: что выполняется, сколько ждёт, в каком состоянии. Первая остановка при диагностике performance проблем, блокировок, idle in transaction.
**wait_event и wait_event_type** - ключ к диагностике медленных запросов. Lock = ждёт блокировки. LWLock = ждёт internal latch. IO = ждёт диска. Client = ждёт данных от приложения. Много Lock wait = проблемы с конкуренцией за строки.
pg_stat_activity показывает 50 соединений в state='idle in transaction' более 10 минут. Что это означает?
pg_stat_user_tables: здоровье таблиц
**pg_stat_user_tables** содержит статистику по каждой таблице: seq scans, index scans, строки INSERT/UPDATE/DELETE, dead tuples, время последнего autovacuum. Используется для диагностики bloat, отсутствующих индексов, эффективности autovacuum.
**HOT updates (Heap-Only Tuple)** - оптимизация: если обновляется строка и ни один индекс не включает изменённый столбец - PostgreSQL не создаёт новую запись в индексе. hot_update_pct = 0% при низком числе индексов, означает излишние обновления всех индексов.
pg_stat_user_tables показывает seq_scan = 1M, idx_scan = 100 для таблицы 5M строк. Что это означает?
pg_locks: диагностика блокировок
**pg_locks** показывает все текущие блокировки: кто держит, кто ждёт. Сам по себе сложен для чтения - обычно объединяют с pg_stat_activity. Lock wait chain - цепочка ожиданий: A ждёт B, B ждёт C. Найти root cause = найти начало цепочки.
**ALTER TABLE - источник блокировок #1 в production.** ALTER TABLE берёт ACCESS EXCLUSIVE lock, блокируя все запросы к таблице. Неожиданный idle in transaction в pg_stat_activity держит lock и блокирует ALTER TABLE который блокирует всё остальное. Всегда проверять pg_locks перед DDL.
pg_blocking_pids(1234) возвращает [5678]. PID 5678 state = 'idle in transaction', query_start = 2 часа назад. Что нужно сделать?
Grafana + Prometheus: production мониторинг
**postgres_exporter** (Prometheus) экспортирует pg_stat_* метрики в Prometheus. Grafana дашборд визуализирует тренды во времени. Это критично: разовый SELECT показывает текущее состояние, Grafana - динамику за дни и недели. Spike в 3 ночи без Grafana - потерянная информация.
**Готовые дашборды** для Grafana: ID 9628 (PostgreSQL Database) и ID 455 (PostgreSQL Overview) - импортируются одним кликом. Содержат 50+ метрик включая TPS, latency percentiles, cache hit ratio, replication lag, autovacuum stats.
Grafana показывает spike cache_hit_ratio с 99% до 60% каждые 5 минут и возврат. Что это, скорее всего?
Alerting: что должно будить в 3 ночи
**Правильный алертинг** - это баланс: слишком мало алертов = пропущенные инциденты, слишком много = alert fatigue, команда игнорирует. Для PostgreSQL: критические алерты будят немедленно, warning - рабочий день.
**Топ алертов для production PostgreSQL:** Down, TxidWraparound > 1.5B, диск < 20% свободно, cache hit ratio < 90% за 15 мин, replication lag > 10 МБ, долгие транзакции > 5 мин, много idle in transaction. Это минимальный set который спасёт от большинства инцидентов.
Мониторинг PostgreSQL достаточен если смотреть pg_stat_* запросами по необходимости
Reactive мониторинг (смотреть когда сломалось) недостаточен. Проактивный мониторинг (Grafana + алерты) обнаруживает проблемы за часы/дни до инцидента: растущий bloat, деградация hit ratio, медленно растущий replication lag
Txid wraparound, деградация autovacuum, утечки соединений - все эти проблемы развиваются медленно. Через pg_stat_* запрос раз в неделю их не поймать. Grafana с трендами за 2 недели показывает аномалии, которые невидны в моментальном снимке
alert_fatigue: команда перестала реагировать на алерты потому что их 200/день, большинство ложные. Какой первый шаг?
Итоги
- **pg_stat_activity** - real-time диагностика: активные запросы, idle in transaction, wait events. Первая остановка при проблемах
- **pg_stat_user_tables** - здоровье таблиц: bloat (n_dead_tup), отсутствие индексов (seq_scan vs idx_scan), autovacuum activity
- **pg_blocking_pids(pid)** - находит блокирующие процессы. Корень lock chain = idle in transaction запущенный давно
- **postgres_exporter + Grafana** - тренды, не снимки. Spike в 3 ночи виден утром. Wraparound риск растёт недели
- Алертинг: critical = немедленно (Down, Wraparound > 1.5B, диск < 10 ГБ). Warning = рабочий день (hit ratio, replication lag)
Связанные темы
Мониторинг охватывает все аспекты PostgreSQL:
- Настройка autovacuum — pg_stat_user_tables - основной инструмент мониторинга autovacuum: n_dead_tup, last_autovacuum, bloat_pct
- Streaming Replication — pg_stat_replication - мониторинг репликации: lag в байтах, state, sync_state для каждого standby
- Troubleshooting — Большинство troubleshooting сценариев начинается с pg_stat_activity, pg_locks и pg_stat_user_tables
Вопросы для размышления
- Grafana показывает hit_ratio деградирует с 98% до 85% за последние 2 недели. Запросы не менялись. Что могло вызвать деградацию? Как определить причину?
- pg_stat_activity показывает 5 соединений в state='active' с duration > 10 минут и wait_event_type = 'Lock'. Как найти корень lock chain и минимальным воздействием разблокировать ситуацию?
- Компания ввела SLA: P99 latency < 100 мс. Как настроить мониторинг PostgreSQL чтобы отслеживать это? Какой алерт нужен и с каким threshold?