PostgreSQL: пять привычек, которые сэкономили мне ночи

25.06.2025 · 6 мин

Крупный план серверного оборудования

За годы работы с PostgreSQL у меня накопился короткий список привычек, которые кажутся мелочью, пока не спасут вас от инцидента в два часа ночи. Делюсь пятью, которые считаю обязательными для любого проекта, где база — не игрушка.

1. Индекс на внешний ключ — не автоматический

В отличие от некоторых других СУБД, PostgreSQL не создаёт индекс на колонку внешнего ключа автоматически. Если у вас таблица orders с user_id, ссылающимся на users, и вы не добавили индекс вручную — удаление пользователя с большим числом заказов может заблокировать таблицу на неприятно долгое время. Я завёл себе правило: индекс на FK добавляется в той же миграции, что и сам внешний ключ, без исключений.

2. EXPLAIN ANALYZE до продакшена, а не после

Проверять план выполнения тяжёлого запроса нужно на этапе разработки, с объёмом данных, близким к реальному. Запрос, который отрабатывает за десять миллисекунд на тестовой базе из тысячи строк, может превратиться в секвентное сканирование на десять секунд на боевой таблице из десяти миллионов строк. Разница между «работает у меня» и «работает в проде» чаще всего именно в объёме данных.

3. Транзакции — короткие и предсказуемые

Долгая транзакция держит блокировки и мешает автовакууму делать свою работу, из-за чего таблица со временем раздувается. Я стараюсь никогда не открывать транзакцию вокруг операции, которая включает сетевой вызов к внешнему сервису — если внешний сервис подвиснет, транзакция в базе подвиснет вместе с ним.

4. NOT NULL и ограничения — по умолчанию, а не когда вспомнили

Легче добавить ограничение на этапе создания таблицы, чем разгребать данные, которые уже успели накопить NULL-значения там, где логика приложения этого не ожидала. Каждый раз, когда я откладывал NOT NULL «на потом», это потом наступало в виде отдельной миграции по очистке данных, которая занимала в разы больше времени.

5. Резервные копии проверяются восстановлением, а не существованием файла

Самая дорогая ошибка — обнаружить в момент инцидента, что бэкап есть, но он битый или неполный. Раз в месяц я разворачиваю последний бэкап на отдельном стенде и проверяю, что из него действительно можно поднять рабочую базу. Это единственный способ быть уверенным, что план восстановления сработает, когда он реально понадобится.

Вывод

Ни одна из этих привычек не требует специальных знаний — только дисциплины делать их регулярно, а не «когда будет время». В базе данных именно дисциплина, а не изощрённость, чаще всего отделяет спокойную ночь от разбора инцидента.