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 КБ)