Тормозит Postgres: 12 шагов диагностики
Эксперты собрали системный подход из 12 шагов, чтобы найти узкие места и пофиксить проблемы
298 открытий2К показов
Производительность PostgreSQL может проседать постепенно. Сначала запросы зависают и растёт нагрузка растёт, а затем CPU начинает работать на 100%, хотя данных больше не стало. База тормозит, что сказывается на работе всего проекта. Возможных причин много: от неоптимальных запросов до ошибок конфигурации. В таких ситуациях важно не паниковать, а действовать постепенно — от простого к сложному.
Вместе с экспертами собрали системный подход из 12 шагов, чтобы найти узкие места и пофиксить проблемы.
Шаг 1. Проверьте CPU, память и диск
Начинаем с базы — проверяем аппаратные и системные ресурсы. Иногда проблема кроется в том, что серверу объективно тяжело. CPU перегружен, память закончилась, диск устал, и PostgreSQL просто не из чего строить производительность. База работает как сениор-разработчик в последней стадии выгорания.
На что ориентироваться:
- Если CPU постоянно упирается в предел — анализируем активность запросов или рассматриваем масштабирование.
- Если
Swapактивен — не хватает памяти. - Если видите высокий
iowaitили высокий%utilдиска, то кандидаты: медленное хранилище, случайные чтения,VACUUM, большие запросы.
Шаг 2. Изучите активность в pg_stat_activity
Представляет информацию о текущей активности каждого процесса в реальном времени. Благодаря pg_stat_activity можно увидеть, какие запросы сейчас ждут запуска, какие в работе, а какие съедают больше всего ресурсов производительности. Если смотреть сюда регулярно, большинство проблем видно ещё до аварии.
На что обратить внимание
- долгие транзакции;
wait_event_type = 'Lock';idle in transaction— признак некорректной работы приложения с транзакциями.
Однажды в проде столкнулись с резким ростом задержек запросов, далее — массовые ошибки canceling statement due to lock timeout. Выяснилось: в ETL начали повсеместно использовать транзакции, в том числе там, где они не нужны. Долгие этапы блокировали частые операции. Перезапуск PostgreSQL помогал до следующего запуска ETL.
Решение: идентифицировать и завершить блокирующие процессы, переработать ETL на более короткие транзакции. В дальнейшем — маркировать подобные процессы и мониторить их отдельно.
Шаг 3. Найдите медленные запросы в pg_stat_statements
Этот модуль отслеживает статистику выполнения сервером всех операторов SQL. Сюда стоит заглянуть, если зависание и торможение повторяются. Сама база может работать нормально, а один или два плохо написанных запроса — нет.
Что искать:
- запросы, потребляющие больше всего времени;
- случаи, когда чтение идёт с диска, а не из буфера (
shared_blks_read >> shared_blks_hit).
Шаг 4. Выявите блокировки
Ищите ситуации, когда несколько запросов пытаются работать с одними и теми же данными одновременно. Если один процесс держит строку или таблицу, остальные ждут. Тогда база не падает, а просто стоит в очереди.
Ищем цепочки блокировок. Частые причины:
- долгие транзакции,
- миграции без окон обслуживания,
- запросы без нужных индексов.
Шаг 5. Проанализируйте план запроса с EXPLAIN ANALYZE
Эта команда сначала выполняет запрос, а затем выводит фактическое число строк и время выполнения, накопленное в каждом узле плана. Так можно найти место, которое съедает больше всего ресурсов. Неэффективный расход времени и памяти происходит, когда база выбирает неоптимальный план, чтобы выполнить запрос.
Шаг 6. Проверьте и оптимизируйте индексы
Индекс работает как указатель в книге, чтобы быстро искать нужную страницу. Но если поставить закладки везде, то книга станет толстой и неудобной. PostgreSQL ведёт себя так же: без индекса он перебирает строки вручную, а с перегруженной структурой дольше обновляет таблицу и тратит лишнюю память
Как оптимизировать:
- не создавать индекс на каждый столбец;
- использовать частичные индексы, если данные распределены неравномерно;
- регулярно проводить
REINDEXдля крупных объектов.
Шаг 7. Устраните раздувание таблиц — bloat
PostgreSQL не удаляет ненужные данные сразу, а копит «мёртвые» строки. Если их становится слишком много, таблицы разрастаются. Тогда база тратит ресурсы впустую.
Диагностика:
Очистка:
Шаг 8. Настройте и проверьте autovacuum
Этот фоновый процесс нужен в PostgreSQL, чтобы автоматически обслуживать базу. Пока он работает, система в порядке. Если его выключить или не настроить, то накопится мусор, вырастут таблицы, а база замедлится.
Проверьте эффективность процессов:
Настройки должны соответствовать нагрузке и объёму данных.
Если отключить автовакуум или не управлять им, может произойти быстрое раздувание таблиц и резкое падение производительности.
Если n_dead_tup растёт, а autovacuum_count нет — это сигнал будущих проблем с производительностью и ростом bloat. Также важно следить за WAL: резкий рост записи может указывать на массовые обновления, проблемы с репликацией или приближающееся заполнение диска.
Шаг 9. Обновите статистику и настройте планировщик
PostgreSQL формирует план выполнения запроса на основе статистики о распределении данных в таблицах. Если статистика устарела, оптимизатор может выбрать неэффективный план.
Регулярно выполняйте команду ANALYZE, чтобы освежить статистику и корректно оценивать операции.
Учитывайте важные параметры:
random_page_costдля SSD ≈ 1.1effective_cache_size≈ 50–75% RAM
Шаг 10. Контролируйте соединения
Каждое активное соединение потребляет ресурсы сервера, включая память и процессы планировщика. Избыточное количество соединений может привести к деградации производительности.
Текущее состояние соединений можно просмотреть с помощью:
Чтобы решить проблему, используйте пул соединений — например, через пулер PgBouncer или аналоги. Такие программы перераспределяют нагрузку между клиентами.
Шаг 11. Проанализируйте логи
PostgreSQL предоставляет гибкую систему протоколирования, чтобы фиксировать длительные операции, ожидания блокировок и создание временных файлов. Для диагностики посмотрите все логи, связанные с производительностью.
Рекомендуемые параметры в postgresql.conf:
Шаг 12. Оптимизируйте конфигурацию
Значения по умолчанию предназначены для минимальных нагрузок — для работы на ноутбуке. Они не дают достаточной мощности в производственной среде.
Измените ключевые параметры конфигурации:
shared_buffers~25% RAMeffective_cache_size~50–75% RAMwork_mem4–16 MB per operationcheckpoint_timeout15–30 minrandom_page_cost= 1.1 для SSD
Многие думают, что 16 мегабайт — это глобальный лимит на соединение. На самом деле это лимит на операцию. Один запрос может использовать work_mem много раз.
Качество и целостность данных: типовые проблемы и решения
Качество данных — основа устойчивой IT-системы. Проблемы с ними часто приводят к сбоям и некорректной работе приложений. В PostgreSQL есть встроенные механизмы, которые помогают поддерживать надёжность информации.
Какие ошибки встречаются чаще всего:
- дубли,
- неверные типы,
- конфликтующие или устаревшие значения,
- частичные и повреждённые записи.
Как поддерживать целостность данных:
- Проводить регулярный аудит и мониторинг качества данных.
- Внедрять автоматические проверки на дубликаты, пропуски и нарушения правил ещё на этапе загрузки данных.
- Использовать резервное копирование и инструменты восстановления после сбоев.
- Повышать осознанность пользователей и разработчиков — качество данных это часть инженерной культуры.
Контроль качества данных включает также стратегию восстановления. Даже идеально настроенная валидация не спасает от сбоя диска или человеческого фактора. Резервные копии и репликации должны стать частью общей стратегии.
На прикладном уровне используйте SAVEPOINT, чтобы аккуратно откатывать операции внутри транзакции. На уровне инфраструктуры работает та же логика:
- проверенные бэкапы возвращают к нормальному состоянию,
- репликация сохраняет доступность, если падает основной сервер.
SAVEPOINT помогает в рамках одной транзакции, бэкапы и репликация — в рамках всей системы.
Как проверять входные данные
Задавайте допустимые форматы и диапазоны. Указывайте, какие значения вы считаете корректными. Пример:
- дата рождения не может быть позже текущего дня;
- возраст — только числа ≥ 18;
- формат email должен содержать @ и домен.
Проверяйте данные на двух уровнях. Чтобы пользователь увидел ошибку сразу, смотрите на клиенте — например, в форме сбора контактов.
Чтобы защититься, если приложение пропустило проблему — на сервере.
Используйте ограничения в базе. SQL-ограничения — это тот самый встроенный механизм надёжности:
NOT NULL— поле не может быть пустым;UNIQUE— значение должно быть уникальным;CHECK— значение должно соответствовать условию;FOREIGN KEY— связь с другой таблицей;- триггеры — дополнительная логика проверки.
Давайте понятные сообщения об ошибках. Пользователь должен понимать, что он сделал не так. Например, вместо Error 400 — invalid data напишите: «Возраст должен быть от 18 лет. Введено: 15».
Актуализируйте правила проверки. Если вчера минимальная сумма заявки была 5 тысяч, а сегодня 10 — проверка должна обновиться.
Отдайте контроль машине. Используйте автоматизированные проверки:
- поиск дублей;
- контроль пустых полей;
- сверка с бизнес-правилами;
- регулярный скрипт на аномалии.
Документируйте и обучайте. Опишите, какие данные нужны, в каком виде и почему. Покажите команде и пользователям. Чем понятнее правила, тем меньше ошибок.
Идеальный сценарий: регулярные тестируемые бэкапы + репликация с мониторингом лагов.
Чек-лист диагностики за 15 минут
- pg_stat_activity — долгие транзакции, ожидания
- pg_locks — есть ли блокировки
- pg_stat_statements — тяжёлые запросы
- iostat, htop, free — ресурсы железа
- Проверка автовакуума
- Проверка WAL и места на диске
- Анализ логов
↓Зафиксировали замедление
├─ pg_stat_activity — кто работает?
├─ pg_locks — кто блокирует?
├─ idle in transaction — есть?
├─ I/O / CPU / swap — норм?
├─ Автовакуум — жив?
├─ Индексы — используются?
├─ План запроса — деградировал?
└─ max_connections / пул соединений — адекватны?
Ещё 4 неочевидные причины деградации производительности
Что делать, если диагностика по стандарту не помогла? Владимир Васильев рассказал нам, где ещё можно найти источник проблем:
- «Тихое» повреждение данных на диске. Дисковая подсистема не сообщала об ошибках: контроллер
RAIDс кэшем-бутербродом, где батарея отжила своё. Некоторые страницы данных на диске были битые. Postgres при чтении таких страниц не падал, а уходил в бесконечные ожиданияI/O, которые выглядели как резкий скачок нагрузки на диск. Вылечили включениемzero_damaged_pagesна свой страх и риск, с последующим дампом/рестором. Потом, конечно, заменили железо. - Конфликт расширений. Была история с
pg_stat_statementsиauto_explain, которые при определённой настройке (совместная загрузка и высокая частота сэмплирования) начинали сильно тормозить из-за конкуренции за локи в общей памяти. Симптом — высокийwait_eventтипаLWLockдля простых запросов. - Проблема на уровне файловой системы. Очень старый, но запоминающийся случай: файловая система была заполнена почти под завязку, больше 95%. Это привело к драматическому падению производительности, так как механизмам
VACUUMиCREATE INDEXне хватало места для создания временных файлов. Симптомы были самые странные, пока не посмотрели наdf -h. - Субтильный баг в версии PostgreSQL. Однажды апгрейд на минорную версию в рамках одного major привёл к деградации конкретного типа запросов с
JOIN. Оказалось, баг в планировщике — он неправильно оценивал стоимость при определённом условии. Помог откат или установкаenable_<type>scan = offв качестве временного костыля.
Выводы
Основные источники проблем:
- долгие транзакции и блокировки
- неэффективные планы выполнения
- недостаточная память и
I/O-узкие места - неверные настройки
work_mem,autovacuum,max_connections - игнорирование метрик и логов
Универсального решения проблем нет. Чтобы понять причину торможения и разобраться с ней, стоит последовательно уточнять контекст.
Краткий чек-лист диагностики:
- понять, что происходит сейчас,
- найти узкое место,
- проверить спрос со стороны запросов, а не только предложения со стороны конфигурации,
- убедиться, что данные и процессы здоровы.
Читайте также
- Основы PostgreSQL для начинающих: от установки до первых запросов
- PostgreSQL vs. ClickHouse vs. Duck DB: какую опенсорс базу выбрать для аналитики в 2025 году?
- Вредные советы по работе с базами данных, или как расстроить DBA
- SQL-оптимизация: 5 запросов, которые ломают базу
- PostgreSQL: что нужно знать о счётчике транзакций
298 открытий2К показов









