Профилирование и мониторинг PostgreSQL
Раздел 8.11, шаг 11 из 12. Дальше — Ansible и Terraform.
Что мониторить
| Категория | Примеры метрик |
|---|---|
| Доступность | pg_up, replication lag seconds |
| Производительность | TPS, latency p95, cache hit ratio |
| Ресурсы | connections, locks, temp files, bloat |
| WAL / checkpoint | checkpoint frequency, wal generation rate |
| Autovacuum | dead tuples, last autovacuum age |
Золотые сигналы для приложения с БД — latency запросов, error rate, saturation (connections), replication lag.
pg_stat_activity — «кто сейчас»
SELECT pid, usename, datname, state, wait_event_type, wait_event,
now() - query_start AS duration, left(query, 80) AS query
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY duration DESC;
wait_event — где backend ждёт (IO, Lock, Client, …). Долгие idle in transaction — кандидаты на kill и fix в коде.
SELECT pg_cancel_backend(12345); -- мягко
SELECT pg_terminate_backend(12345); -- жёстко
pg_stat_statements — топ запросов
Расширение (часто через shared_preload_libraries):
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all
CREATE EXTENSION pg_stat_statements;
SELECT calls,
round(total_exec_time::numeric, 2) AS total_ms,
round(mean_exec_time::numeric, 2) AS mean_ms,
rows,
left(query, 100)
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;
Сброс статистики после деплоя — pg_stat_statements_reset().
pg_stat_user_tables / indexes
SELECT relname,
seq_scan, idx_scan,
n_live_tup, n_dead_tup,
round(100.0 * n_dead_tup / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;
seq_scan >> idx_scan на большой таблице — сигнал к индексам или statistics.
auto_explain
Логирует план медленных запросов автоматически:
shared_preload_libraries = 'pg_stat_statements, auto_explain'
auto_explain.log_min_duration = '500ms'
auto_explain.log_analyze = on
auto_explain.log_buffers = on
auto_explain.log_nested_statements = on
Альтернатива — sampling в приложении (OpenTelemetry) + EXPLAIN в staging.
pgBadger — отчёт из логов
pgBadger парсит postgresql-*.log, строит HTML с топ запросами, checkpoint, locks.
pgbadger /var/log/postgresql/postgresql-16-main.log -o report.html
Требует log_line_prefix с %t, %p, %u, %d и log_min_duration_statement или log_statement.
Prometheus + Grafana
postgres_exporter exposes metrics:
# scrape config фрагмент
- job_name: postgres
static_configs:
- targets: ['postgres-exporter:9187']
Дашборды — ID 9628 (PostgreSQL Database), алерты:
pg_replication_lag > 30spg_stat_activity_count{state="active"} > 80% max_connectionsrate(pg_stat_bgwriter_buffers_backend[5m])spike — checkpoint pressure
Стек observability DevOps — 8.04/19, Prometheus, Практикум Prometheus и Grafana, Практикум Zabbix.
Профилирование нагрузки
| Инструмент | Назначение |
|---|---|
| pgbench | Synthetic TPS benchmark |
| EXPLAIN (ANALYZE, BUFFERS) | Один запрос |
| perf / eBPF | CPU на уровне OS (редко для DBA) |
| strace | Debug IO syscall (осторожно в prod) |
pgbench -i -s 100 testdb
pgbench -c 20 -j 4 -T 60 testdb
Checklist алертов production
- Replication lag > порог (30s–5min по SLA).
- Disk > 85% на WAL/data.
max_connectionsблизко к лимиту.- Dead tuples ratio > 20% на hot table без autovacuum.
age(datfrozenxid)> 200M.- Failed backup job (Wal-G / operator).
Практика
- Включите
pg_stat_statements, найдите top-3 поtotal_exec_time, оптимизируйте один запрос. - Сгенерируйте нагрузку pgbench, постройте Grafana dashboard cache hit + TPS.
- Запустите pgBadger на log с
auto_explain.
Связанные материалы
См. также
Другие статьи этого же раздела в боковом меню (как на странице "О разделе"). MVCC, XID, снимки данных, системные поля xmin/xmax, VACUUM и autovacuum, bloat, wraparound, процессы postmaster, Shared Buffers и WAL. pg_dump, pg_basebackup, PITR, pg_probackup, Wal-G, стратегия 3-2-1, восстановление в Kubernetes и после failover. Ansible role для установки Postgres, шаблоны postgresql.conf, Terraform для RDS и managed PostgreSQL, GitOps паттерны для инфраструктуры БД. EXPLAIN и EXPLAIN ANALYZE, B-tree, GiST, SP-GiST, GIN, BRIN, частичные и составные индексы, типовые ошибки планировщика. Тонкая настройка памяти (shared_buffers, work_mem, maintenance_work_mem), I/O (effective_cache_size, random_page_cost), WAL, checkpoint и autovacuum. Документная модель в Postgres, операторы и индексы JSONB, declarative partitioning по range/list/hash, связь с оконными функциями и CTE. Хранимые функции и процедуры PL/pgSQL, row-level и statement triggers, event triggers, асинхронные события через NOTIFY и LISTEN без polling. Streaming replication, logical replication, read replicas и Hot Standby, failover, connection pooling через PgBouncer — transaction и session pooling. Официальный образ postgres, volumes для PGDATA, переменные окружения, docker-compose с healthcheck, типовые ошибки контейнеризации СУБД. Managed PostgreSQL (RDS, Cloud SQL, Yandex Managed), StatefulSet, PersistentVolume, секреты, операторы Crunchy/Zalando, anti-patterns stateful в K8s. Patroni и DCS, сравнение с Greenplum и CockroachDB, когда нужен sharding, Citus, выбор архитектуры под OLTP и аналитику. Краткое резюме раздела 8.11 — архитектура, оптимизация, эксплуатация в контейнерах и Kubernetes, HA, бэкапы и автоматизация.Архитектура PostgreSQL и внутреннее устройство
Бэкапы PostgreSQL и восстановление
Автоматизация PostgreSQL — Ansible и Terraform
Продвинутая оптимизация PostgreSQL и индексы
Конфигурация PostgreSQL — postgresql.conf
JSONB, партиционирование и расширения SQL в PostgreSQL
PL/pgSQL, триггеры и NOTIFY/LISTEN в PostgreSQL
Репликация PostgreSQL, Hot Standby и PgBouncer
PostgreSQL в Docker
PostgreSQL в облаке и Kubernetes
HA-кластеры PostgreSQL и распределённые СУБД
Практикум PostgreSQL — итоги