MAATRIX / Блог / PostgreSQL на сервере: частые ошибки и решения

PostgreSQL на сервере: частые ошибки и решения

PostgreSQL на сервере: частые ошибки и решения

MAATRIX

Большинство ошибок PostgreSQL на сервере повторяются из раза в раз, и почти у каждой есть короткое проверенное решение. Ниже — разбор частых проблем: от «connection refused» и «too many connections» до переполнения диска и отказа в правах. Для каждой сначала даётся решение, а потом причина, чтобы вы могли починить быстро, а понять — спокойно.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Connection refused при подключении

Ошибка could not connect to server: Connection refused означает, что по указанному адресу и порту никто не слушает. Первым делом проверьте, запущен ли сервер и на каком адресе он слушает:

sudo systemctl status postgresql
sudo ss -ltnp | grep 5432

Если процесса на 5432 нет — служба не поднялась, смотрите журнал sudo journalctl -u postgresql -n 50. Если процесс слушает только 127.0.0.1, а вы подключаетесь по внешнему адресу, дело в параметре listen_addresses. Откройте postgresql.conf и добавьте нужный адрес, затем перезапустите сервер.

Причина почти всегда одна из трёх: сервер не запущен, слушает не тот интерфейс или порт закрыт фаерволом. Проверьте их по порядку — это экономит время. Частая ловушка: приложение в Docker обращается к localhost, имея в виду свой контейнер, а не хост с базой. В контейнерах указывайте реальный адрес хоста или имя сервиса, а не 127.0.0.1.

Ещё один сценарий этой же ошибки — сервер только что перезагрузился и PostgreSQL ещё не поднял кластер, особенно если восстановление после сбоя занимает время на большой базе. В журнале вы увидите строки о recovery. Здесь ничего чинить не нужно, дайте базе завершить восстановление. Если же процесс падает сразу после старта, ищите в журнале конкретную причину: чаще всего это повреждённый конфиг после ручной правки или занятый порт от второго кластера.

FATAL: password authentication failed

Пароль верный, а вход не проходит — типичная ситуация после переноса базы. Причина в файле pg_hba.conf, который определяет метод аутентификации. Проверьте, какая строка применяется к вашему подключению, и убедитесь, что метод — scram-sha-256, а не устаревший md5 или peer.

sudo nano /etc/postgresql/17/main/pg_hba.conf
host    appdb   appuser   127.0.0.1/32   scram-sha-256

Если базу перенесли со старого сервера, где пароли хранились в формате md5, а новый ждёт scram, аутентификация не пройдёт даже с правильным паролем. Решение — переустановить пароль роли уже на новом сервере командой ALTER ROLE appuser PASSWORD 'новый_пароль'; при password_encryption = scram-sha-256. После любой правки pg_hba.conf перезагрузите конфигурацию: sudo systemctl reload postgresql.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под PostgreSQL

FATAL: sorry, too many connections

База отказывает новым клиентам, потому что достигнут лимит max_connections (по умолчанию 100). Быстрая диагностика — посмотреть, кто занимает соединения:

sudo -u postgres psql -c "SELECT count(*), state FROM pg_stat_activity GROUP BY state;"

Часто виноваты «висящие» соединения в состоянии idle in transaction — приложение открыло транзакцию и не закрыло. Их можно завершить, но правильное лечение — исправить приложение и поставить пул-менеджер. Простое повышение max_connections съедает память: каждое соединение стоит несколько мегабайт, и на 500 подключений уйдёт гигабайты RAM.

Правильное решение при большом числе клиентов — pgBouncer в режиме transaction pooling. Он держит небольшой пул реальных соединений к PostgreSQL и мультиплексирует между ними сотни клиентских подключений. Приложение думает, что у него много коннектов, а база обслуживает десяток — и работает стабильно.

Отдельно проверьте, не съедает ли лимит сама система резервированием. Часть соединений PostgreSQL держит под суперпользователя (superuser_reserved_connections), поэтому реально доступных обычному приложению чуть меньше, чем стоит в max_connections. Если вы упёрлись в лимит и не можете подключиться даже под postgres, зайдите локально через сокет — резерв как раз для этого и существует, чтобы администратор всегда мог войти и разобраться.

Could not extend file: No space left on device

База встала, потому что закончилось место на диске. Это одна из самых опасных ситуаций: PostgreSQL останавливает запись, чтобы не повредить данные. Сначала посмотрите, что занимает диск:

df -h
sudo du -sh /var/lib/postgresql/17/main/*

Частые пожиратели места — незачищенные WAL-логи, старые дампы бэкапов в том же разделе и раздувшиеся таблицы. Освободите место: удалите старые бэкапы, проверьте, не накопились ли архивы WAL из-за неработающей репликации или archiving. Если replication slot «мёртвого» реплики держит WAL, его нужно удалить командой SELECT pg_drop_replication_slot('имя');, иначе WAL будет расти бесконечно.

После освобождения места PostgreSQL обычно продолжает работу сам. На будущее — вынесите бэкапы на отдельное хранилище и настройте мониторинг свободного места с оповещением заранее, а не по факту падения.

ERROR: role does not exist

Приложение или скрипт обращается к роли, которой нет. Проверьте список ролей:

sudo -u postgres psql -c "\du"

Обычно это результат восстановления дампа отдельной базы без ролей: pg_dump для одной базы не сохраняет глобальные объекты, включая роли. При переносе всего кластера используйте pg_dumpall или отдельно выгружайте роли через pg_dumpall --roles-only. Создать недостающую роль вручную:

sudo -u postgres psql -c "CREATE ROLE appuser WITH LOGIN PASSWORD 'пароль';"

Похожая ошибка — permission denied for schema public в PostgreSQL 15 и новее. Здесь роль есть, но не имеет прав создавать объекты в схеме. Выдайте права владельцем базы: GRANT ALL ON SCHEMA public TO appuser; или заведите приложению собственную схему.

Медленные запросы и высокая нагрузка

База отвечает, но всё тормозит. Первый шаг — найти тяжёлые запросы. Включите логирование медленных операций в postgresql.conf:

log_min_duration_statement = 1000

Теперь все запросы дольше секунды попадают в журнал. Для системного анализа установите расширение pg_stat_statements — оно показывает суммарную нагрузку по каждому шаблону запроса. Часто причина проста: отсутствует индекс, и база делает полный проход по таблице. Команда EXPLAIN ANALYZE перед запросом покажет план выполнения и место, где теряется время.

Второй частый корень тормозов — нехватка памяти под кэш. Если shared_buffers оставлен по умолчанию (128 МБ), сервер постоянно читает с диска. Подтяните параметры под реальный объём RAM: shared_buffers около четверти памяти, effective_cache_size около трёх четвертей. Если же нагрузка переросла железо — это честный сигнал, что пора взять VPS помощнее, а не выжимать последнее из слабого.

Как избежать большинства ошибок заранее

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

Если текущий сервер уже не тянет базу, в MAATRIX можно быстро арендовать VPS в России, США или Великобритании с нужным объёмом RAM под PostgreSQL и перенести данные без спешки. Оплата — картой российского банка, по СБП, криптовалютой или токеном MAAT, иностранная карта не требуется.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под PostgreSQL

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

PostgreSQL пишет connection refused, что делать?

Проверьте, запущена ли служба, слушает ли она нужный адрес (listen_addresses) и открыт ли порт фаерволом. В 90% случаев проблема в одном из этих трёх пунктов.

Как убрать ошибку too many connections без потери данных?

Найдите висящие соединения idle in transaction через pg_stat_activity, исправьте приложение и поставьте pgBouncer вместо простого повышения лимита.

База остановилась из-за No space left on device — данные целы?

Как правило да: PostgreSQL останавливает запись именно чтобы не повредить данные. Освободите место, проверьте зависшие replication slots и старые WAL, затем сервер продолжит работу.

Почему после переноса дампа не существует роль?

pg_dump одной базы не выгружает роли. Создайте роль вручную или используйте pg_dumpall --roles-only при переносе всего кластера.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.