Shared Memory (разделяемая память) — это один большой кусок оперативной памяти, который PostgreSQL выделяет при старте кластера и использует всеми своими процессами совместно.

Без shared memory PostgreSQL не смог бы работать многопользовательски. Она решает три ключевые задачи:

ЗадачаКак решается через shared memory
Кэширование данныхХранит часто читаемые страницы таблиц и индексов в shared_buffers → меньше чтения с диска
Согласованность при записиВсе процессы видят одни и те же данные, потому что работают с одной копией страницы
Координация между процессамиХранит информацию о блокировках, состоянии транзакций, WAL и т.д.

Вы влияете на shared memory через параметры в postgresql.conf. Вот главные:

1. shared_buffers — кэш данных

  • Что: сколько RAM выделить под кэш страниц БД.
  • Значение по умолчанию: 128 МБ (слишком мало для production!).
  • Рекомендация:
    • Для сервера с 8+ ГБ RAM → 25% от общей памяти,
    • Но не более 8–16 ГБ (дальнейший рост даёт мало пользы).
  • Проверить:
SHOW shared_buffers;

Требует перезапуска.

Не путайте с work_mem — это разные вещи!
shared_buffers — общий кэш для всех,
work_mem — память на операцию для одного запроса.

2. max_connections — число подключений

  • Почему это важно для shared memory?
    Потому что каждое подключение резервирует место в shared memory:
    • Для блокировок (max_locks_per_transaction),
    • Для состояния транзакции (в ProcArray),
    • Для WAL-буферов и др.
  • Слишком много подключений → не хватит shared memory → ошибка:
ERROR: out of shared memory
HINT: You might need to increase max_locks_per_transaction.

Решение

  • Используйте пул подключений (pgBouncer),
  • Не ставьте max_connections = 1000 без необходимости.

3.max_locks_per_transaction

  • Сколько блокировок может удерживать одна транзакция.
  • По умолчанию: 64.
  • Если у вас большие DDL-операции или сложные транзакции — может не хватить.
  • Ошибка: out of shared memory. Как увеличить:
max_locks_per_transaction = 128

Требует перезапуска.

4. wal_buffers — буфер WAL

  • Хотя WAL пишется на диск, сначала записи попадают сюда.
  • По умолчанию: -1 → 1/32 от shared_buffers (но не менее 64 КБ, не более 64 МБ).
  • Обычно не нужно менять вручную.

Как проверить, что shared memory работает?

1. Посмотреть размер сегмента ОС

ipcs -m
 
# Найдите сегмент с владельцем postgres и большим размером
# Размер ≈ shared_buffers + служебные структуры

2. Проверить использование буферов

-- Требует расширения
CREATE EXTENSION pg_buffercache;
 
-- Сколько буферов используется
SELECT count(*) FROM pg_buffercache WHERE reldatabase = (SELECT oid FROM pg_database WHERE datname = 'mydb');

3. Мониторить ошибки

Следите за логами на предмет:

out of shared memory
# — это сигнал, что нужно увеличить `max_locks_per_transaction` или уменьшить `max_connections`.

Как настраивать shared memory

ДействиеКоманда / Файл
Установить shared_buffersВ /etc/postgresql/18/main/postgresql.conf
Увеличить лимиты блокировокmax_locks_per_transaction = 128
Проверить, сколько памяти использует кластерipcs -m
Убедиться, что ОС позволяет выделить такую памятьsysctl kernel.shmmax (для System V)
Перезапустить кластер после измененийsudo systemctl restart postgresql@18-main

Убедитесь, что ядро разрешает выделять большие сегменты shared memory:

# В /etc/sysctl.conf
kernel.shmmax = 17179869184  # 16 ГБ
kernel.shmall = 4194304      # в страницах (обычно 4 КБ)