Postgres в Docker и «could not resize shared memory segment»
Тяжёлый аналитический запрос, который локально отрабатывал за секунды, в контейнере начал падать с ошибкой could not resize shared memory segment … No space left on device. Диск при этом был почти пустой.
Откуда ошибка
Речь не о диске, а о /dev/shm — разделе в оперативной памяти. Postgres использует его для динамической разделяемой памяти: через неё общаются параллельные воркеры, туда же попадают большие хеш-таблицы при параллельных join-ах. Docker по умолчанию выделяет контейнеру всего 64 МБ /dev/shm, и параллельному запросу этого мало.
Проверить легко:
docker exec -it db df -h /dev/shm
Как исправить
Увеличить раздел в compose-файле:
services:
db:
image: postgres:16
shm_size: 1g
Это верхняя граница, а не резерв: память тратится только по мере надобности. Ориентируюсь примерно на размер shared_buffers.
Второй вариант — уменьшить max_parallel_workers_per_gather или выключить параллелизм для конкретной сессии, но это лечит симптом, а не причину.
Заодно
Пока разбирался, понял, что в том же контейнере стоял shared_buffers по умолчанию — 128 МБ на сервере с 16 ГБ памяти. Стартовая точка — около четверти оперативной памяти, а дальше смотреть на долю попаданий в кеш в pg_stat_database.