Какой параметр не является параметром буферного пула субд
Гибридный буферный пул
Гибридный буферный пул позволяет объектам буферного пула ссылаться на страницы данных в файлах базы данных, находящихся на устройствах энергонезависимой памяти (PMEM), а не в копиях страниц данных, кэшированных в непостоянной DRAM. Эта функция появилась в SQL Server 2019 (15.x).
Устройства энергонезависимой памяти (PMEM) поддерживают байтовую адресацию. Если используется файловая система с режимом прямого доступа (DAX), поддерживающая энергонезависимую память (например, XFS, EXT4 или NTFS), доступ к файлам в файловой системе осуществляется с помощью обычных API файловой системы в ОС. Кроме того, он позволяет выполнять так называемые операции загрузки и сохранения в размещенных в памяти файлах на устройстве. Это позволяет приложениям с поддержкой PMEM, таким как SQL Server, получать доступ к файлам на устройстве в обход традиционного стека хранилища.
Гибридный буферный пул использует эту возможность для операций загрузки и сохранения с размещенными в памяти файлами, чтобы использовать устройство PMEM как кэш для буферного пула, а также для хранения файлов базы данных. Это создает уникальную ситуацию, когда логическая операция чтения и физическое чтение фактически являются одной операцией. Устройства энергонезависимой памяти доступны через шину памяти так же, как и обычная непостоянная память DRAM.
Только чистые страницы данных кэшируются на устройстве для гибридного буферного пула. Когда страница помечается как «грязная», она копируется в буферный пул DRAM, а затем записывается обратно на устройство PMEM и снова помечается как «чистая». Это происходит во время обычных операций с контрольной точкой аналогично тому, что делается для блочного устройства.
Функция гибридного буферного пула доступна в Windows и Linux. PMEM-устройства должны быть отформатированы с использованием файловой системы, поддерживающей DAX (DirectAccess). DAX поддерживают файловые системы XFS, EXT4 и NTFS. SQL Server автоматически определит, что файлы данных находятся на соответствующим образом отформатированном PMEM-устройстве, и выполнит сопоставление памяти в файлах базы данных во время запуска при подключении, восстановлении либо создании базы данных.
Дополнительные сведения см. в разделе:
Включение гибридного буферного пула
SQL Server 2019 (15.x) представляет язык DDL для управления гибридным буферным пулом.
В следующем примере гибридный буферный пул включается для экземпляра SQL Server:
По умолчанию гибридный буферный пул отключен на уровне экземпляра. Обратите внимание на то, чтобы изменения параметра вступили в силу, необходимо перезапустить экземпляр SQL Server. Перезапуск необходим для упрощения выделения достаточного числа хэш-страниц, чтобы учесть общую емкость PMEM на сервере.
В следующем примере гибридный буферный пул включается для конкретной базы данных.
По умолчанию гибридный буферный пул включен на уровне базы данных.
Отключение гибридного буферного пула
Следующий пример отключает гибридный буферный пул на уровне экземпляра:
По умолчанию гибридный буферный пул отключен на уровне экземпляра. Чтобы изменения параметра вступили в силу, необходимо перезапустить экземпляр SQL Server. Это гарантирует, что для буферного пула будет выделено достаточное количество страниц хэша, так как теперь необходимо учитывать емкость PMEM на сервере.
В следующем примере гибридный буферный пул отключается для конкретной базы данных.
По умолчанию гибридный буферный пул включен на уровне базы данных.
Просмотр конфигурации гибридного буферного пула
Следующий пример возвращает текущее состояние конфигурации гибридного буферного пула для экземпляра.
В примере ниже перечислены базы данных и параметр уровня базы данных для гибридного буферного пула ( is_memory_optimized_enabled ).
Рекомендации по использованию гибридного буферного пула
При форматировании PMEM-устройства в Windows используйте максимальный размер единицы размещения, доступный для файловой системы NTFS (2 МБ в Windows Server 2019), и отформатируйте устройство для DAX (Direct Access).
Размеры файлов должны быть кратны 2 МБ (деление по модулю на 2 МБ должно давать ноль).
Если параметр области сервера для гибридного буферного пула отключен, эта функция не будет использоваться какой-либо пользовательской базой данных.
Если параметр гибридного буферного пула на уровне сервера включен, можно использовать параметр области базы данных, чтобы отключить эту функцию для отдельных пользовательских баз данных.
Расширение буферного пула
Преимущества расширения буферного пула
Главное назначение базы данных SQL Server — хранение и поиск данных, поэтому интенсивное использование операций дискового ввода-вывода — это основное свойство компонента Database Engine. Так как дисковые операции ввода-вывода могут потреблять много ресурсов и требовать относительно длительного времени для выполнения, в SQL Server особое внимание уделено рациональному использованию операций ввода-вывода. Буферный пул служит основным источником размещения памяти SQL Server. Управление буфером — это ключевой компонент в достижении этой рациональности. Компонент управления буферами состоит из двух механизмов: диспетчера буферов для доступа к страницам баз данных и их обновления и буферного пула для сокращения операций файлового ввода-вывода базы данных.
Страницы данных и индексов считываются с диска в буферный пул, а измененные страницы (так называемые «грязные страницы») записываются обратно на диск. Нехватка памяти в контрольных точках сервера и базы данных приводит к тому, что активные «грязные» страницы удаляются из буферного кэша, записываются на механические диски и считываются обратно в кэш. Эти операции ввода-вывода обычно представляют небольшие произвольные операции чтения и записи с объемом данных от 4 до 16 КБ. Работа в режиме небольших произвольных операций ввода-вывода предполагает частые операции поиска, конкурирующие за перемещение головки диска, что увеличивает задержку ввода-вывода и сокращает общую пропускную способность ввода-вывода системы.
Типичный подход к устранению этих «узких мест» заключается в добавлении дополнительных модулей DRAM или высокопроизводительных шпинделей SAS. Хотя эти варианты работают, у них есть существенные недостатки: модули DRAM дороже, чем диски хранения данных, а установка шпинделей увеличивает капитальные расходы при покупке оборудовании и эксплуатационные расходы из-за повышения энергопотребления и вероятности сбоя компонента.
Компонент расширения буферного пула расширяет кэш буферного пула с помощью памяти энергонезависимого хранилища (обычно на основе SSD-дисков). В результате этого расширения в буферном пуле становится возможным разместить рабочее множество данных большего объема, что обеспечивает подкачку операций ввода-вывода между ОЗУ и SSD-дисками. Это эффективно перераспределяет нагрузку небольших случайных операций ввода-вывода с механических дисков на SSD-диски. Благодаря более низкой задержке и улучшенной производительности случайных операций ввода-вывода SSD-дисков расширение буферного пула значительно повышает пропускную способность ввода-вывода.
В следующем списке приведены преимущества расширения буферного пула.
Повышенная пропускная способность произвольных операций ввода-вывода
Уменьшенная задержки ввода-вывода
Повышенная пропускная способность транзакций
Улучшенная производительность операций чтения с использованием крупного гибридного буферного пула
Архитектура кэширования, которая может использовать современные и будущие недорогие диски
Основные понятия
Следующие термины относятся к компоненту расширения буферного пула.
Твердотельный накопитель (SSD)
Твердотельные накопители постоянно хранят данные в оперативной памяти (ОЗУ). Дополнительные сведения см. в этом определении.
Буфер
В SQL Serverбуфер — это 8-килобайтовая страница в памяти такого же размера, что и страница данных или индекса. Буферный кэш делится на 8-килобайтовые страницы. Страница остается в буферном кэше, пока диспетчеру буферов требуется область буфера для чтения дополнительных данных. Данные записываются обратно на диск, только если они были изменены. Эти измененные страницы в памяти называют «грязными». Страница чиста, когда она эквивалентна ее образу в базе данных на диске. Данные в буферном кэше могут измениться несколько раз, прежде чем будут сохранены обратно на диске.
Буферный пул
Также называют буферным кэшем. Буферный пул — это глобальный ресурс, который совместно используется всеми базами данных для кэшированных страниц данных. Минимальный и максимальный размер кэша буферного пула задается во время запуска или динамической настройки SQL Server с процедуры sp_configure. Этот размер определяет максимальное число страниц, которые могут кэшироваться в буферном пуле в любое время в запущенном экземпляре.
Максимальный объем памяти, который может зафиксировать расширение буферного пула, может ограничиваться другими запущенными на компьютере приложениями, если они вызывают значительную нехватку памяти.
Контрольная точка
Контрольная точка создает известную надежную точку, с которой Компонент Database Engine может начать применение изменений, содержащихся в журнале, во время восстановления после непредвиденного отключения или аварии. Новая контрольная точка записывает «грязные» страницы вместе со сведениями журнала транзакций из памяти на диск, а также сведения о журнале транзакций. Дополнительные сведения см. в разделе Контрольные точки базы данных (SQL Server).
Сведения
SSD-хранилище используется как расширение подсистемы памяти вместо дисковой подсистемы хранилища. Это означает, что файл расширения буферного пула позволяет диспетчеру буферного пула использовать DRAM и NAND-Flash для реализации буферного пула намного большего размера из изменяемых страниц в энергонезависимой ОЗУ на основе SSD. Это создает многоуровневую иерархию кэширования, где на 1-м уровне (L1) DRAM, а на 2-м уровне (L2) файл расширения буферного пула на SSD-дисках. В кэш L2 записываются только чистые страницы, что позволяет обеспечить безопасность данных. Диспетчер буферов обеспечивает перемещение чистых страниц между кэшами L1 и L2.
Если расширение буферного пула включено, оно определяет размер и путь к файлу кэширования буферного пула на SSD-диске. Этот файл представляет собой смежный экстент хранилища на SSD-дисках, которое настраивается статически во время запуска экземпляра SQL Server. Параметры файла конфигурации можно изменить, только если расширение буферного пула отключено. Если расширение буферного пула отключено, все связанные параметры конфигурации удаляются из реестра. Файл расширения буферного пула удаляется после завершения работы экземпляра SQL Server.
Ограничения емкости
Выпуск SQL Server Enterprise допускает максимальный размер расширения буферного пула, который в 32 раза превышает значение max_server_memory.
Выпуск SQL Server Standard допускает максимальный размер расширения буферного пула, который в 4 раза превышает значение max_server_memory.
Рекомендации
Рекомендуется следовать приведенным ниже правилам.
Включив расширение буферного пула первый раз, перезапустите экземпляр SQL Server, чтобы обеспечить максимальную производительность.
Настройте расширение буферного пула так, чтобы соотношение между объемом физической памяти (max_server_memory) и объемом расширения буферного пула не превышало 1:16. Более низкое значение в диапазоне от 1:4 до 1:8 может быть оптимальными. Сведения о настройке параметра max_server_memory см. в разделе Параметры конфигурации сервера «Server Memory».
Тщательно протестируйте расширение буферного пула перед реализацией в рабочей среде. После внедрения в рабочую среду не следует изменять конфигурацию в файле или отключать функцию. Эти действия могут отрицательно повлиять на производительность сервера, поскольку размер буферного пула значительно снижается, когда эта функция отключена. При отключении память, используемая для поддержки функции, не возвращается в кучу, пока не произойдет перезагрузка экземпляра SQL Server. Однако, если функцию снова включить, память будет использоваться повторно без перезапуска экземпляра.
Возврат сведений о расширении буферного пула
Можно использовать следующие динамические административные представления для отображения конфигурации расширения буферного пула и получения сведений о страницах данных в расширении.
Счетчики производительности доступны в объекте диспетчера буферов SQL Server для трассировки страниц данных в файле расширения буферного пула. Дополнительные сведения см. в разделе Счетчики производительности расширения буферного пула.
SQL Server 2019: Гибридный пул буферов (Hybrid Buffer Pool)
Гибридный пул буферов в Microsoft SQL Server 2019 позволяет объектам пула буферов ссылаться на страницы данных в файлах базы данных, находящихся на устройствах постоянной памяти (PMEM), вместо копий страниц данных, кэшированных в энергозависимой DRAM. Эта функция представлена в SQL Server 2019 начиная с версии 15.x.
Устройства с постоянной памятью (PMEM) имеют побайтовую адресацию, и если используется файловая система с поддержкой постоянной памяти (DAX) (например, XFS, EXT4 или NTFS), файлы в файловой системе могут быть доступны с помощью API обычной файловой системы в ОС. В качестве альтернативы он может выполнять так называемые операции загрузки и сохранения с картами памяти файлов на устройстве. Это позволяет приложениям, поддерживающим PMEM, таким как SQL Server, получать доступ к файлам на устройстве без обхода традиционного стека хранилища.
Гибридный буферный пул использует эту способность для выполнения операций загрузки и сохранения файлов с отображением памяти, чтобы использовать устройство PMEM в качестве кэша для буферного пула, а также для хранения файлов базы данных. Это создает уникальную ситуацию, когда и логическое, и физическое чтение, по сути, являются одной и той же операцией. Устройства постоянной памяти доступны через шину памяти, как и обычная энергозависимая DRAM.
На устройстве кэшируются только чистые страницы данных для гибридного буферного пула. Когда страница помечается как грязная, она копируется в буферный пул DRAM, прежде чем в конечном итоге будет записана обратно на устройство PMEM и снова помечена как чистая. Это будет происходить во время обычных операций контрольной точки аналогично тому, как это выполняется для стандартного блочного устройства.
Функция гибридного буферного пула доступна как для Windows, так и для Linux. Устройство PMEM должно быть отформатировано с файловой системой, поддерживающей DAX (DirectAccess). Все файловые системы XFS, EXT4 и NTFS поддерживают DAX. SQL Server автоматически определяет, находятся ли файлы данных на правильно отформатированном устройстве PMEM, и выполняет отображение файлов базы данных в памяти при запуске, когда новая база данных присоединяется, восстанавливается или создается.
Как включить гибридный буферный пул
SQL Server 2019 (15.x) представляет динамический язык данных (DDL) для управления пулом гибридных буферов.
В следующем примере включается гибридный буферный пул для экземпляра SQL Server:
По умолчанию гибридный буферный пул отключен в области экземпляра. Обратите внимание: чтобы изменение параметра вступило в силу, необходимо перезапустить экземпляр SQL Server. Необходим перезапуск, чтобы облегчить выделение достаточного количества хэш-страниц, чтобы учесть общую емкость PMEM на сервере.
В следующем примере включается гибридный буферный пул для конкретной базы данных.
По умолчанию гибридный буферный пул включен на уровне базы данных (database scope).
Как отключить гибридный буферный пул
В следующем примере гибридный пул буферов отключается на уровне экземпляра:
По умолчанию гибридный буферный пул отключен на уровне экземпляра. Чтобы это изменение вступило в силу, необходимо перезапустить экземпляр. Это гарантирует, что для пула буферов будет выделено достаточно хэш-страниц, поскольку теперь необходимо учитывать емкость PMEM на сервере.
В следующем примере отключается гибридный буферный пул для конкретной базы данных.
По умолчанию гибридный буферный пул включен в области базы данных (database scope).
Просмотр конфигурации гибридного буферного пула
В следующем примере возвращается текущее состояние конфигурации гибридного буферного пула экземпляра.
В следующем примере перечислены базы данных и параметр уровня базы данных для гибридного буферного пула ( is_memory_optimized_enabled ).
Советы и рекомендации по настройке для гибридного буферного пула
Надеюсь приведенные рекомендации по настройке Гибридного пул буферов (Hybrid Buffer Pool) в MS SQL Server 2019 будут Вам полезны!
WAL в PostgreSQL: 1. Буферный кеш
Предыдущий цикл был посвящен изоляции и многоверсионности PostgreSQL, а сегодня мы начинаем новый — о механизме журналирования (write-ahead logging). Напомню, что материал основан на учебных курсах по администрированию, которые делаем мы с Павлом pluzanov, но не повторяет их дословно и предназначен для вдумчивого чтения и самостоятельного экспериментирования.
Этот цикл будет состоять из четырех частей:
Зачем нужно журналирование?
В процессе работы часть данных, с которыми имеет дело СУБД, хранится в оперативной памяти и записывается на диск (или на другой энергонезависимый носитель) отложенным образом. Чем реже это происходит, тем меньше ввод-вывод и тем быстрее работает система.
Но что произойдет в случае сбоя, например, при выключении электропитания или при ошибке в коде СУБД или операционной системы? Все содержимое оперативной памяти будет потеряно, а останутся лишь данные, записанные на диск (при некоторых видах сбоев может пострадать и диск, но в этом случае поможет лишь резервная копия). В принципе можно организовать ввод-вывод таким образом, чтобы данные на диске всегда поддерживались в согласованном состоянии, но это сложно и не слишком эффективно (насколько я знаю, только Firebird пошел таким путем).
Обычно же — в том числе и в PostgreSQL — данные, записанные на диск, оказываются несогласованными и при восстановлении после сбоя требуются специальные действия, чтобы согласованность восстановить. Журналирование — тот самый механизм, который делает это возможным.
Буферный кеш
Разговор о журналировании мы, как ни странно, начнем с буферного кеша. Буферный кеш — не единственная структура, которая хранится в оперативной памяти, но одна из самых важных и сложных. Понимание принципа его работы важно само по себе, к тому же на этом примере мы познакомимся с тем, как происходит обмен данными между оперативной памятью и диском.
Кеширование используется в современных вычислительных системах повсеместно, у одного только процессора можно насчитать три-четыре уровня кеша. Вообще любой кеш нужен для того, чтобы сглаживать разницу в производительности двух типов памяти, одна из которых относительно быстрая, но ее на всех не хватает, а другая — относительно медленная, но имеющаяся в достатке. Вот и буферный кеш сглаживает разницу между временем доступа к оперативной памяти (наносекунды) и к дисковой (миллисекунды).
Заметим, что у операционной системы тоже есть дисковый кеш, который решает ту же самую задачу. Поэтому обычно СУБД стараются избегать двойного кеширования, обращаясь к диску напрямую, минуя кеш ОС. Но в случае PostgreSQL это не так: все данные читаются и записываются с помощью обычных файловых операций.
Кроме того, свой кеш бывает также у контроллеров дисковых массивов, и даже у самих дисков. Этот факт нам еще пригодится, когда мы доберемся до вопроса надежности.
Но вернемся к буферному кешу СУБД.
Называется он так потому, что представляет собой массив буферов. Каждый буфер — это место под одну страницу данных (блок), плюс заголовок. Заголовок, в числе прочего, содержит:
Изначально кеш содержит пустые буферы, и все они связаны в список свободных буферов. Смысл указателя на «следующую жертву» станет ясен чуть позже. Чтобы быстро находить нужную страницу в кеше, используется хеш-таблица.
Поиск страницы в кеше
Когда процессу требуется прочитать страницу, он сначала пытается найти ее в буферном кеше с помощью хеш-таблицы. Ключом хеширования служит номер файла и номер страницы внутри файла. В соответствующей корзине хеш-таблицы процесс находит номер буфера и проверяет, действительно ли он содержат нужную страницу. Как и с любой хеш-таблицей, здесь возможны коллизии; в таком случае процессу придется проверять несколько страниц.
Использование хеш-таблицы давно вызывает нарекания. Такая структура позволяет быстро найти буфер по странице, но совершенно бесполезна, если, например, надо найти все буферы, занятые определенной таблицей. Но хорошую замену пока никто не предложил.
Если нужная страница найдена в кеше, процесс должен «закрепить» буфер, увеличив счетчик pin count (несколько процессов могут сделать это одновременно). Пока буфер закреплен (значение счетчика больше нуля), считается, что буфер используется и его содержимое не должно «радикально» измениться. Например, в странице может появиться новая версия строки — это никому не мешает благодаря многоверсионности и правилам видимости. Но в закрепленный буфер не может быть прочитана другая страница.
Вытеснение
Может получиться так, что необходимая страница не будет найдена в кеше. В этом случае ее необходимо считать с диска в какой-либо буфер.
Если в кеше еще остались свободные буферы, то выбирается первый же свободный. Но рано или поздно они закончатся (обычно размер базы данных больше чем память, выделенная под кеш) и тогда придется выбирать один из занятых буферов, вытеснить находящуюся там страницу и на освободившееся место прочитать новую.
Механизм вытеснения основан на том, что при каждом обращении к буферу процессы увеличивают счетчик числа обращений (usage count) в заголовке буфера. Таким образом те буферы, которые используются реже остальных, имеют меньшее значение счетчика и являются хорошими кандидатами на вытеснение.
Алгоритм clock-sweep перебирает по кругу все буферы (используя указатель на «следующую жертву»), уменьшая на единицу их счетчики обращений. Для вытеснения выбирается первый же буфер, который:
После того, как буфер найден, с ним происходит следующее.
Буфер закрепляется, чтобы показать остальным процессам, что он используется. Помимо закрепления используются и другие средства блокировки, но подробнее об этом мы поговорим отдельно.
Если буфер оказался грязным, то есть содержит измененные данные, страницу нельзя просто выбросить — сначала ее требуется сохранить на диск. Это не очень хорошая ситуация, поскольку процессу, который собирается прочитать страницу, приходится ждать записи «чужих» данных, но этот эффект сглаживается процессами контрольной точки и фоновой записи, которые будут рассмотрены позже.
Далее в выбранный буфер читается с диска новая страница. Счетчик числа обращений устанавливается в единицу. Кроме того, ссылку на загруженную страницу необходимо прописать в хеш-таблицу, чтобы в дальнейшем ее можно было найти.
Теперь ссылка на «следующую жертву» указывает на следующий буфер, а у только что загруженного есть время нарастить счетчик обращений, пока указатель не обойдет по кругу весь буферный кеш и не вернется вновь.
Своими глазами
Как это принято в PostgreSQL, существует расширение, которое позволяет заглянуть внутрь буферного кеша.
Создадим таблицу и вставим в нее одну строку.
Что окажется в буферном кеше? Как минимум, в нем должна появиться страница, на которую добавлена единственная строка. Проверим это следующим запросом, в котором мы выбираем только буферы, относящиеся к нашей таблице (по номеру файла relfilenode), и расшифровываем номер слоя (relforknumber):
Так и есть — в буфере одна страница. Она грязная (isdirty), счетчик обращений равен единице (usagecount), и она не закреплена ни одним процессом (pinning_backends).
Новых буферов не прибавилось — вторая строка поместилась на ту же страницу. Обратите внимание, что счетчик использований увеличился.
И после обращения к странице на чтение счетчик тоже увеличивается.
А если выполнить очистку?
Очистка создала карту видимости (одна страница) и карту свободного пространства (три страницы — минимальный размер этой карты).
Настройка размера
Размер кеша устанавливается параметром shared_buffers. Значение по умолчанию — смехотворные 128 Мб. Это один из параметров, которые имеет смысл увеличить сразу же после установки PostgreSQL.
Имейте в виду, что изменение параметра требует перезапуска сервера, поскольку вся необходимая под кеш память выделяется при старте сервера.
Из каких соображений выбирать подходящее значение?
Даже самая большая база имеет ограниченный набор «горячих» данных, с которыми ведется активная работа в каждый момент времени. В идеале именно этот набор и должен помещаться в буферный кеш (плюс некоторое место для «одноразовых» данных). Если размер кеша будет меньше, то активно используемые страницы будут постоянно вытеснять друг друга, создавая избыточный ввод-вывод. Но и бездумно увеличивать кеш тоже неправильно. При большом размере будут расти накладные расходы на его поддержание, и кроме того оперативная память требуется и для других нужд.
Таким образом, оптимальный размер буферного кеша будет разным в разных системах: он зависит от данных, от приложения, от нагрузки. К сожалению, нет такого волшебного значения, которое одинаково хорошо подойдет всем.
Стандартная рекомендация — взять в качестве первого приближения 1/4 оперативной памяти (для Windows до версии PostgreSQL 10 рекомендовалось выбирать размер меньше).
А дальше надо смотреть по ситуации. Лучше всего провести эксперимент: увеличить или уменьшить размер кеша и сравнить характеристики системы. Конечно, для этого надо иметь тестовый стенд и уметь воспроизводить типовую нагрузку — на производственной среде такие опыты выглядят сомнительным удовольствием.
Но некоторую информацию о происходящем можно почерпнуть прямо на живой системе с помощью того же расширения pg_buffercache — главное, смотреть под нужным углом.
Например, можно изучить распределение буферов по степени их использования:
В данном случае много пустых значений счетчика — это свободные буферы. Неудивительно для системы, в которой ничего не происходит.
Можно посмотреть, какая доля каких таблиц в нашей базе закеширована и насколько активно используются эти данные (под активным использованием в этом запросе понимаются буферы со счетчиком использования больше 3):
Тут, например, видно, что больше всего место занимает таблица vac (мы использовали ее в одной из прошлых тем), но к ней уже давно никто не обращался и она до сих пор не вытеснена только потому, что еще не закончились свободные буферы.
Можно придумать и другие разрезы, которые дадут полезную информацию для размышлений. Надо только учитывать, что такие запросы:
Массовое вытеснение
При операциях, выполняющих массовое чтение или запись данных, есть опасность быстрого вытеснения полезных страниц из буферного кеша «одноразовыми» данными.
Чтобы этого не происходило, для таких операций используются так называемые буферные кольца (buffer ring) — для каждой операции выделяется небольшая часть буферного кеша. Вытеснение действует только в пределах кольца, поэтому остальные данные буферного кеша не страдают.
Для последовательного чтения (sequential scan) больших таблиц (размер которых превышает четверть буферного кеша) выделяется 32 страницы. Если в процессе чтения таблицы другому процессу тоже потребуются эти данные, он не начинает читать таблицу сначала, а подключается к уже имеющемуся буферному кольцу. После окончания сканирования он дочитывает «пропущенное» начало таблицы.
Давайте проверим. Для этого создадим таблицу так, чтобы одна строка занимала целую страницу — так удобнее считать. Размер буферного кеша по умолчанию составляет 128 Мб = 16384 страницы по 8 Кб. Значит, в таблицу надо вставить больше 4096 страниц-строк.
Теперь нам придется перезапустить сервер, чтобы очистить кеш от данных таблицы, которые прочитал анализ.
После перезагрузки прочитаем всю таблицу:
И убедимся, что табличными страницами в буферном кеше занято только 32 буфера:
Если же запретить последовательное сканирование, то таблица будет прочитана по индексу:
В этом случае буферное кольцо не используется и в буферном кеше окажется вся таблица полностью (и почти весь индекс тоже):
Похожим образом буферные кольца используются для процесса очистки (тоже 32 страницы) и для массовых операций записи COPY IN и CREATE TABLE AS SELECT (обычно 2048 страниц, но не больше 1/8 всего буферного кеша).
Временные таблицы
Исключение из общего правила представляют временные таблицы. Поскольку временные данные видны только одному процессу, им нечего делать в общем буферном кеше. Более того, временные данные существуют только в рамках одного сеанса, так что их не нужно защищать от сбоя.
Для временных данных используется кеш в локальной памяти того процесса, который владеет таблицей. Поскольку такие данные доступны только одному процессу, их не требуется защищать блокировками. В локальном кеше используется обычный алгоритм вытеснения.
В отличие от общего буферного кеша, память под локальный кеш выделяется по мере необходимости, ведь временные таблицы используются далеко не во всех сеансах. Максимальный объем памяти для временных таблиц одного сеанса ограничен параметром temp_buffers.
Прогрев кеша
После перезапуска сервера должно пройти некоторое время, чтобы кеш «прогрелся» — набрал актуальные активно использующиеся данные. Иногда может оказаться полезным сразу прочитать в кеш данные определенных таблиц, и для этого предназначено специальное расширение:
Раньше расширение могло только читать определенные таблицы в буферный кеш (или только в кеш ОС). Но в версии PostgreSQL 11 оно получило возможность сохранять актуальное состояние кеша на диск и восстанавливать его же после перезагрузки сервера. Чтобы этим воспользоваться, надо добавить библиотеку в shared_preload_libraries и перезагрузить сервер.
Поле рестарта, если не менялось значение параметра pg_prewarm.autoprewarm, будет автоматически запущен фоновый процесс autoprewarm master, который раз в pg_prewarm.autoprewarm_interval будет сбрасывать на диск список страниц, находящихся в кеше (не забудьте учесть новый процесс при установке max_parallel_processes).
Сейчас в кеше нет таблицы big:
Если мы предполагаем, что все ее содержимое очень важно, мы можем прочитать ее в буферный кеш с помощью вызова следующей функции:
Список страниц сбрасывается в файл autoprewarm.blocks. Чтобы его увидеть, можно просто подождать, пока процесс autoprewarm master отработает в первый раз, но мы инициируем это вручную:
Число сброшенных страниц больше 4097 — сюда входят и уже прочитанные сервером страницы объектов системного каталога. А вот и файл:
Теперь снова перезапустим сервер.
И сразу после запуска наша таблица снова оказывается в кеше.
Это обеспечивает тот же самый процесс autoprewarm master: он читает файл, разделяет страницы по базам данных, сортирует их (чтобы чтение с диска было по возможности последовательным) и передает отдельному рабочему процессу autoprewarm worker для обработки.



