Настройка мониторинга производительности базы данных (pg_stat_statements/slow query log)

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Настройка мониторинга производительности базы данных (pg_stat_statements/slow query log)
Средняя
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Настройка мониторинга производительности базы данных (pg_stat_statements/slow query log)

Мониторинг базы данных — это не дашборд ради дашборда. Это система, которая за 30 секунд даёт ответ на вопрос: «Что именно замедлилось и почему». Без правильно настроенного мониторинга при деградации начинается угадывание — смотрят не туда, теряют часы.

PostgreSQL: pg_stat_statements

Расширение pg_stat_statements накапливает статистику по каждому уникальному запросу:

# postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.max          = 10000   # сколько уникальных запросов хранить
pg_stat_statements.track        = all     # top — только верхнеуровневые, all — вложенные тоже
pg_stat_statements.track_utility = off    # не трекать COPY, VACUUM и т.п.

После перезапуска PostgreSQL:

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

Полезные запросы для анализа:

-- Запросы, съедающие больше всего суммарного времени
SELECT
    left(query, 120)                                         AS query,
    calls,
    round(total_exec_time::numeric / 1000, 1)               AS total_sec,
    round(mean_exec_time::numeric, 1)                        AS avg_ms,
    round(stddev_exec_time::numeric, 1)                      AS stddev_ms,
    round(rows::numeric / nullif(calls, 0), 0)               AS rows_per_call
FROM pg_stat_statements
WHERE dbid = (SELECT oid FROM pg_database WHERE datname = current_database())
  AND calls > 10
ORDER BY total_exec_time DESC
LIMIT 20;

-- Запросы с большим разбросом — нестабильные (иногда быстро, иногда медленно)
SELECT left(query, 120) AS query, calls,
       round(mean_exec_time::numeric, 1) AS avg_ms,
       round(stddev_exec_time::numeric, 1) AS stddev_ms,
       round(stddev_exec_time / nullif(mean_exec_time, 0) * 100, 1) AS cv_pct
FROM pg_stat_statements
WHERE calls > 100
ORDER BY cv_pct DESC
LIMIT 10;

PostgreSQL: auto_explain

pg_stat_statements показывает что медленно, auto_explainпочему: логирует план выполнения для медленных запросов автоматически.

# postgresql.conf
shared_preload_libraries = 'pg_stat_statements,auto_explain'
auto_explain.log_min_duration = 500   # мс: логировать запросы > 500ms
auto_explain.log_analyze      = true  # реальное время выполнения, не только оценка
auto_explain.log_buffers      = true  # сколько страниц hit/read
auto_explain.log_format       = json  # для структурированного парсинга
auto_explain.log_nested_statements = true

Вывод попадает в основной лог PostgreSQL (/var/log/postgresql/). Удобно анализировать через pgBadger.

MySQL/MariaDB: slow query log

# /etc/mysql/conf.d/slow-log.cnf
[mysqld]
slow_query_log           = ON
slow_query_log_file      = /var/log/mysql/slow.log
long_query_time          = 1       # секунды
log_queries_not_using_indexes = ON
min_examined_row_limit   = 1000   # игнорировать запросы, просматривающие < 1000 строк
log_slow_rate_limit      = 100    # MariaDB: логировать каждый 100-й такой запрос

Включить без перезапуска:

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL log_queries_not_using_indexes = 'ON';

Анализ через Percona pt-query-digest:

# Топ запросов за последний час slow.log
pt-query-digest \
  --since="1h ago" \
  --limit 20 \
  --output report \
  /var/log/mysql/slow.log

# Вывод: для каждого уникального запроса — count, avg/max time, rows examined

Prometheus + Grafana: метрический мониторинг

Для PostgreSQL — postgres_exporter:

# docker-compose.yml
services:
  postgres_exporter:
    image: quay.io/prometheuscommunity/postgres-exporter:latest
    environment:
      DATA_SOURCE_NAME: "postgresql://monitoring:password@postgres:5432/mydb?sslmode=disable"
    ports:
      - "9187:9187"
# prometheus.yml — scrape config
- job_name: postgresql
  static_configs:
    - targets: ['postgres_exporter:9187']
  scrape_interval: 15s

Ключевые метрики и алерты:

# alerting rules
groups:
  - name: postgresql
    rules:
      - alert: PostgreSQLSlowQueries
        expr: rate(pg_stat_statements_total_exec_time_seconds_total[5m]) > 10
        for: 2m
        annotations:
          summary: "Высокое суммарное время запросов"

      - alert: PostgreSQLHighConnections
        expr: pg_stat_activity_count > pg_settings_max_connections * 0.8
        for: 1m
        annotations:
          summary: "Использовано > 80% соединений"

      - alert: PostgreSQLReplicationLag
        expr: pg_replication_lag > 30
        for: 1m
        annotations:
          summary: "Реплика отстаёт на {{ $value }} секунд"

Для MySQL — mysqld_exporter:

mysqld_exporter \
  --config.my-cnf=/etc/mysql/monitoring.cnf \
  --collect.global_status \
  --collect.info_schema.innodb_metrics \
  --collect.perf_schema.eventsstatements \
  --collect.perf_schema.eventsstatementssum

pgBadger: анализ логов PostgreSQL

# Установка
apt-get install pgbadger

# Анализ за сутки
pgbadger \
  --format=stderr \
  --outfile=/var/www/reports/pgbadger_$(date +%Y%m%d).html \
  /var/log/postgresql/postgresql-2025-01-15_*.log

# Генерировать ежедневно через cron
0 6 * * * /usr/bin/pgbadger --incremental --outdir /var/www/reports/pgbadger /var/log/postgresql/postgresql.log

pgBadger строит HTML-отчёт: топ медленных запросов, число запросов по времени суток, lock events, checkpoint activity.

Grafana дашборды

Готовые дашборды из Grafana Dashboard Repository:

  • PostgreSQL: ID 9628 (postgres_exporter dashboard) — connections, transactions/sec, cache hit rate, replication lag
  • MySQL: ID 7362 (MySQL Overview) — InnoDB buffer pool, queries/sec, slow queries
  • pgBouncer: ID 13474

Импорт через Grafana UI: Dashboards → Import → ввести ID.

Что мониторить обязательно

Метрика Порог алерта
Cache hit rate (PG) < 99%
Активные соединения > 80% от max_connections
Лаг репликации > 30 секунд
Размер таблиц + bloat > 30% bloat
Checkpoint duration > 30 секунд
Dead tuples > 10% от live
Slow queries count/min растущий тренд
Disk usage > 80%

Настройка полного стека (postgres_exporter + Prometheus + Grafana + алерты в Telegram) занимает 1–2 дня.