Логирование медленных запросов PostgreSQL: log_min_duration_statement
- Жалобы пользователей на периодические зависания интерфейса без информации в системных логах.
- Отсутствие контекста (имя пользователя, IP-клиента, имя базы данных) в лог-файлах СУБД.
- Переполнение диска логами из-за избыточного логирования всех операций без фильтрации по времени.
1. Конфигурация логирования в postgresql.conf
# Включение логирования в файлы с ротацией
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 1GB
log_truncate_on_rotation = on
# Порог фиксации медленных запросов (например, все запросы дольше 250 мс)
log_min_duration_statement = 250
# Фиксация контрольных точек, блокировок и временных файлов
log_checkpoints = on
log_lock_waits = on
log_temp_files = 0
log_autovacuum_min_duration = 10002. Настройка информативного префикса log_line_prefix
Формат, полностью совместимый с анализатором pgBadger:
log_line_prefix = '%m [%p] %q%u@%d host=%h app=%a tx=%x: '%m: Таймстемп с миллисекундами;%p: PID процесса;%u: Имя пользователя БД;%d: Имя базы данных;%h: IP-адрес клиента;%a: Имя клиентского приложения (например, 1CV8C);%x: ID виртуальной транзакции.
3. Применение параметров без рестарта СУБД
SELECT pg_reload_conf();4. Анализ логов с помощью pgBadger
# Генерация визуального HTML-отчета
pgbadger /var/lib/postgresql/16/main/log/postgresql-*.log -o /var/www/html/report.html Частые вопросы (FAQ)
В чем разница между log_duration и log_min_duration_statement?
log_duration логирует только длительность выполнения запроса отдельной строкой. log_min_duration_statement логирует текст SQL-запроса вместе с его длительностью в одной строке, если превышен заданный порог в миллисекундах.
Что означает log_min_duration_statement = 0?
Значение 0 заставляет СУБД записывать в лог абсолютно каждый выполненный SQL-запрос. Это используется исключительно для кратковременной отладки, так как создает огромную нагрузку на дисковую подсистему.
Зачем включать параметр log_temp_files = 0?
Он записывает в журнал информацию о каждом временном файле, созданном запросом при нехватке work_mem, позволяя локализовать неоптимальные операции сортировок.
Как временно включить логирование запросов только для одной проблемной сессии?
Выполните в сессии: SET log_min_duration_statement = 0;. Это изменит порог только для вашего текущего соединения без влияния на весь сервер.