После расширения сервера администратор PostgreSQL увеличивает shared_buffers. Логика понятна: больше оперативной памяти должно означать больше данных рядом с базой и меньше чтения с накопителя. RAM быстро оказывается почти полностью занятой. Часть запросов действительно работает стабильнее, но другие почти не ускоряются. Во время контрольной точки нагрузка на накопитель становится заметнее, а фоновые процессы оставляют серверу меньше запаса. Одна крупная настройка изменилась, но весь путь данных не свёлся к ней. PostgreSQL использует память совместно с операционной системой. У базы есть собственный буфер, у Linux — файловый кэш, а рядом работают процессы запросов, обслуживание и системные службы. Поэтому вопрос «сколько дать shared_buffers» нельзя отделить от вопроса «как работает весь сервер».
shared_buffers — управляемая память самой базы
shared_buffers — внутренний буфер PostgreSQL для блоков таблиц и индексов. Когда запрос читает данные, нужный блок может попасть в этот буфер. Повторное обращение способно обслуживаться без нового чтения основного файла. PostgreSQL знает, какие блоки находятся в shared_buffers. Буферный менеджер учитывает их использование, закрепление текущими операциями и состояние записи. Это позволяет базе координировать одновременный доступ и изменение данных. Изменённый блок называют dirty buffer — «грязным» буфером: его версия в памяти уже отличается от версии в основном файле. Такой блок нельзя просто забыть. Перед повторным использованием места изменения должны попасть в устойчивое хранилище по правилам СУБД.
Большой shared_buffers способен удерживать больше блоков под непосредственным управлением PostgreSQL. Но он не превращает всю RAM сервера в память базы и не гарантирует, что каждый дополнительный блок будет повторно использован. Если запрос последовательно читает данные один раз, увеличение буфера может лишь вытеснить прежнее содержимое новым потоком. Если рабочий набор хорошо повторяется, дополнительное место полезнее. Результат задаёт поведение запросов, а не сама величина параметра.
Linux использует RAM для кэширования файлов
PostgreSQL читает и записывает обычные файлы через операционную систему. При buffered I/O — буферизованном вводе-выводе — Linux может сохранить недавно прочитанные части файлов в page cache, или файловом кэше. Этот кэш не является лишней памятью, отнятой у базы. Он способен обслужить повторное чтение без обращения к физическому накопителю. При необходимости Linux освобождает часть кэша для процессов, но полезные данные потом придётся прочитать снова. Поэтому свободная RAM на выделенном сервере обычно не простаивает: операционная система превращает её в ускорение файлового пути. Если почти весь объём передать shared_buffers, файловому кэшу и другим потребителям останется меньше места.
Один блок данных может временно иметь представление и во внутреннем буфере PostgreSQL, и на файловом уровне ОС. Но отсюда нельзя делать вывод, что вся база всегда хранится в двух полных копиях. Наполнение обоих уровней меняется вместе с запросами и освобождением памяти. Уровни знают о данных разное. PostgreSQL видит блоки таблиц и индексов, их состояние и участие в операциях. Linux видит страницы памяти и части файлов, но не понимает план SQL или ценность конкретного индекса.
Остальная память тоже выполняет работу
За пределами shared_buffers остаются процессы PostgreSQL. Каждое соединение выполняет запросы, строит планы и хранит служебное состояние. Сортировки, соединения таблиц и другие операции могут временно потреблять дополнительную память. Есть и обслуживание: очистка старых версий строк, построение индексов, статистика и резервное копирование. Эти процессы не исчезают после увеличения shared_buffers и способны совпасть с пиком пользовательских запросов. Операционной системе нужен собственный запас для ядра, сетевого стека, файловых структур и фоновой записи. На том же сервере могут работать мониторинг, агент резервного копирования и другие сервисы.
Поэтому «RAM сервера минус shared_buffers» нельзя считать бесполезным остатком. Этот объём защищает работу запросов и ОС. Слишком тесный запас способен привести к подкачке на диск, долгому освобождению памяти или аварийному завершению процесса. Бюджет по одной настройке особенно опасен при росте конкуренции. Один отчёт помещается, несколько одновременных операций создают другой пик. Размер shared_buffers при этом не меняется, а общий расход сервера — меняется.
Большой буфер меняет путь записи
PostgreSQL использует WAL — журнал предварительной записи. Сначала информация об изменении надёжно попадает в журнал, а изменённые блоки основных файлов могут быть записаны позже. Это позволяет восстановить согласованное состояние после сбоя. Checkpoint, или контрольная точка, фиксирует этап, после которого более ранние изменения уже отражены в основных файлах в требуемой степени. Во время такой работы dirty buffers записываются на накопитель, и профиль I/O меняется. Больший shared_buffers способен удерживать больше изменённых блоков. Это не означает, что каждая контрольная точка обязательно станет хуже, но увеличивает объём состояния, которым нужно управлять. Поведение зависит от частоты изменений и настроек WAL.
Официальная документация PostgreSQL предупреждает, что при больших значениях shared_buffers обычно требуется соответствующее внимание к max_wal_size — границе объёма WAL между контрольными точками. Это не готовая пара чисел, а указание на связь буфера и пути записи. Слишком частые контрольные точки создают интенсивный поток записи. Слишком редкие увеличивают объём восстановления и требования к месту для WAL. Увеличение одного параметра без понимания этой связи способно перенести проблему с чтения на запись.
effective_cache_size ничего не резервирует
Название effective_cache_size часто создаёт ещё одну путаницу. Кажется, что параметр выделяет PostgreSQL дополнительный кэш или задаёт реальную границу памяти. На самом деле это оценка для планировщика запросов. Планировщик сравнивает возможные способы выполнить SQL. Оценка доступного кэша помогает решить, насколько вероятно повторное чтение данных из памяти и выгоден ли определённый план, например использование индекса. Изменение effective_cache_size не резервирует RAM, не заполняет кэш и не меняет физический лимит процесса. Оно меняет предположение, на основании которого PostgreSQL оценивает стоимость планов.
Параметр учитывает возможный эффект и shared_buffers, и кэша операционной системы, но остаётся приблизительным. Реальное содержимое меняется постоянно, а разные запросы конкурируют за один сервер. Поэтому одна панель настроек не является картой физической памяти. Управленческое решение должно связывать конфигурацию с выполненными запросами, задержкой, чтением и записью, а не с желанием заполнить доступный объём.
PostgreSQL платит за весь сервер
В классе решений gigaRAM прозрачный страничный уровень видит страницы памяти ОС, а не логику буферного менеджера PostgreSQL. Подходящая менее активная часть может обслуживаться через NVMe, но это не заменяет настройку shared_buffers и не является кэшем СУБД. Если внутренний буфер выбран неверно, дополнительный уровень не исправит план запросов или всплеск dirty buffers. Если файловый кэш лишён места, база чаще обращается к накопителю. Если операция требует большой временной памяти, размер кэша решает другую задачу.
Иногда лучший результат даёт индекс или изменение SQL, потому что база перестаёт читать лишние блоки. Иногда помогает расписание обслуживания или более быстрый накопитель. В нагрузке с большим повторно используемым набором обоснована дополнительная DRAM. Руководитель оплачивает не параметр, а способность PostgreSQL выполнять нужную работу. В стоимость входят внутренний буфер, кэш ОС, память процессов, путь WAL, контрольные точки и запас для обслуживания. Главный вывод: shared_buffers — важная часть архитектуры PostgreSQL, но не вся RAM и не универсальная кнопка ускорения. Бюджетируют сервер целиком и качество запросов; затем выбирают, где полезнее конфигурация, запрос, накопитель или дополнительная память.
Источники. PostgreSQL 17 — Resource Consumption описывает shared_buffers, кэш ОС и связь с max_wal_size.
WAL Configuration объясняет dirty buffers, checkpoints и I/O.
Query Planning определяет effective_cache_size как оценку.
pg_buffercache показывает внутреннее состояние shared buffers.
Meta Engineering — TMO используется для различия типов памяти и работы с файловым кэшем.
Страница продукта — только для механики и позиционирования.
