Postgresql очистка буферного кэша

Обновлено: 05.07.2024

Иногда я запускаю запрос Postgres, это занимает 30 секунд. Затем я сразу же запускаю тот же запрос, и это занимает 2 секунды. Похоже, что Postgres имеет какое-то кэширование. Могу ли я каким-то образом увидеть, что этот кэш держит? Можно ли принудительно очистить все кэши для настройки?

Примечание: Я в основном ищу версию postgres следующей команды SQL Server:

Но я также хотел бы знать, как увидеть, что на самом деле содержится в этом буфере.

Спасибо за любую помощь.

Я не видел никаких команд для очистки кэшей в PostgreSQL. То, что вы видите, скорее всего, просто обычный индекс и кэш данных, которые читаются с диска и хранятся в памяти. как postgresql, так и кэши в ОС. Чтобы избавиться от всего этого, единственный способ, который я знаю:

То, что вы должны сделать, это:

Да, postgresql, безусловно, имеет кэширование. Размер управляется параметром shared_buffers . Кроме этого, есть, как упоминалось в предыдущем ответе, кэш файлов ОС, который также используется.

Если вы хотите посмотреть, что в кэше, есть модуль contrib с именем pg_buffercache (в contrib/ в исходном дереве, в contrib RPM или там, где это подходит для того, как вы установили его). Способ его использования приведен в стандартной документации PostgreSQL.

На некоторых системах также можно посмотреть кэш операционной системы, см. pg_osmem.py для одного несколько грубого примера.

Нет способа легко очистить тайники. В Linux вы можете остановить сервер баз данных и использовать средство drop_caches, чтобы очистить кэш ОС; обязательно обратите внимание на предупреждение, чтобы сначала запустить синхронизацию.

Я использую эту команду на моем linux box:

Он полностью избавляется от кэша.

У меня была эта ошибка.

psql:/cygdrive/e / test_insertion.sql: 9: ошибка: тип параметра 53
(t_stat_gardien) не соответствует этому при подготовке плана
(t_stat_avant)

I was looking for flushing the current plan and a found this:

У меня это было между вставками, и это решает мою проблему.

Ответ Грега Смита о drop_caches был очень полезен. Я нашел необходимым остановить и запустить службу postgresql, в дополнение к удалению кэшей. Вот сценарий оболочки, который делает трюк. (Моя среда Ubuntu 14.04 и PostgreSQL 9.3.)

Я тестировал с запросом, который занял 19 секунд в первый раз и менее 2 секунд в последующих попытках. После запуска этого скрипта запрос снова занял 19 секунд.

Как уже говорили многие, чтобы очистить общие буферы, вы можете просто перезапустить Postgres (нет необходимости перезапускать сервер). Но просто это не очистит кэш ОС.

Перезапустите Postgres, и вы увидите, что ваш следующий запрос будет очень медленным из-за отсутствия кэша.

иногда я запускаю запрос Postgres, это занимает 30 секунд. Затем я сразу же запускаю тот же запрос, и это занимает 2 секунды. Похоже, что Postgres имеет какое-то кэширование. Могу я как-нибудь увидеть, что в этом тайнике? Могу ли я принудительно очистить все кэши для целей настройки?

Примечание: я в основном ищу версию postgres следующей команды SQL Server:

но я также хотел бы знать, как можно увидеть, что на самом деле содержится в этом буфер.

Спасибо за любую помощь.

вы можете увидеть, что находится в буферном кэше PostgreSQL, используя модуль pg_buffercache. Я сделал презентацию под названием "внутри буферного кэша PostgreSQL

Я не видел никаких команд для очистки кэшей в PostgreSQL. То, что вы видите, скорее всего, просто обычный индекс и кэш данных, считываемые с диска и хранящиеся в памяти. как postgresql, так и кэши в ОС. Чтобы избавиться от всего этого, единственный способ я знаю:

Что вы должны сделать, это:

  1. завершение работы сервера баз данных (pg_ctl, sudo service postgresql stop, так далее.)
  2. echo 3 > /proc/sys/vm / drop_caches Это очистит файл/блок ОС Кэш - очень важно, хотя я не знаю, как это сделать на других ОС.
  3. запустите сервер баз данных

Я использую эту команду в своем окне linux:

Он полностью избавляется от кэша.

ответ Грега Смита о drop_caches был очень полезен. Я счел необходимым остановить и запустить службу postgresql, в дополнение к удалению кэшей. Вот скрипт, который делает трюк. (Моя среда-Ubuntu 14.04 и PostgreSQL 9.3.)

Я тестировал с запросом, который занял 19 секунд в первый раз и менее 2 секунд при последующих попытках. После запуска этого скрипта запрос снова занял 19 секунд.

да, postgresql, безусловно, имеет кэширование. Размер контролируется параметром shared_buffers. Кроме того, как упоминалось в предыдущем ответе, также используется кэш файлов ОС.

Если вы хотите посмотреть, что находится в кэше, есть модуль contrib под названием pg_buffercache доступно (в contrib/ в дереве источника, в contrib RPM или где угодно, где это подходит для того, как вы его установили). Как его использовать, указано в стандарте Документации PostgreSQL.

нет никаких способов очистить кэш буфера, кроме как перезапустить сервер. Вы можете удалить кэш ОС с помощью команды, упомянутой в другом ответе, при условии, что ваша ОС - Linux.

У меня была эта ошибка.

psql:/cygdrive/e / test_insertion.sql: 9: ошибка: тип параметра 53 (t_stat_gardien) не соответствует этому при подготовке плана (t_stat_avant)

Я искал промывку текущего плана и нашел это:

У меня было это между моими вставками, и это решает мою проблему.

здесь pg_buffercache модуль для просмотра shared_buffers кэш. И в какой-то момент мне нужно было удалить кэш, чтобы сделать некоторые тесты производительности на "холодный" кэш, поэтому я написал pg_dropcache расширение, которое делает именно это. Пожалуйста, проверьте это.

да, можно очистить оба общих буфера postgres cache и кэш ОС. Решение bellow для Windows. другие уже дали решение linux.

Как уже говорили многие, чтобы очистить общие буферы, вы можете просто перезапустить Postgres (нет необходимости перезагружать сервер). Но просто это не очистит кэш ОС.

чтобы очистить кэш ОС, используемый Postgres, после остановки службы используйте excelent RamMap (https://technet.microsoft.com/en-us/sysinternals/rammap), из превосходной сюиты Sysinternals. После выполнения RamMap просто нажмите "пустой" - > "пустой список ожидания" в главном меню.

перезапустите Postgres, и вы увидите, что ваш следующий запрос будет медленным из-за отсутствия кэша вообще.

вы также можете выполнить RamMap без закрытия Postgres и, вероятно, будете иметь результаты "без кэша", которые вы хотите, так как, как уже говорили люди, общие буферы обычно дают небольшое влияние по сравнению с кэшем ОС. Но для надежного теста я бы предпочел остановить postgres, как и все, прежде чем очищать кэш ОС, чтобы убедиться.

Примечание: AFAIK, я не рекомендую очищать другие вещи, кроме "списка ожидания" при использовании RamMap, потому что другие данные каким-то образом используются, и вы можете потенциально вызвать проблемы/потерять данные, если вы это сделаете. Помните, что вы очищаете память не только для файлов postgres, но и для любых других приложений и ОС также.

Предыдущий цикл был посвящен изоляции и многоверсионности PostgreSQL, а сегодня мы начинаем новый — о механизме журналирования (write-ahead logging). Напомню, что материал основан на учебных курсах по администрированию, которые делаем мы с Павлом pluzanov, но не повторяет их дословно и предназначен для вдумчивого чтения и самостоятельного экспериментирования.

Этот цикл будет состоять из четырех частей:

  • Буферный кеш (эта статья); — как устроен и как используется при восстановлении; и фоновая запись — зачем нужны и как настраиваются; — уровни и решаемые задачи, надежность и производительность.
    , как ее понимают стандарт и PostgreSQL; — что творится на физическом уровне; ; ; ; (vacuum); (autovacuum); .

В процессе работы часть данных, с которыми имеет дело СУБД, хранится в оперативной памяти и записывается на диск (или на другой энергонезависимый носитель) отложенным образом. Чем реже это происходит, тем меньше ввод-вывод и тем быстрее работает система.

Но что произойдет в случае сбоя, например, при выключении электропитания или при ошибке в коде СУБД или операционной системы? Все содержимое оперативной памяти будет потеряно, а останутся лишь данные, записанные на диск (при некоторых видах сбоев может пострадать и диск, но в этом случае поможет лишь резервная копия). В принципе можно организовать ввод-вывод таким образом, чтобы данные на диске всегда поддерживались в согласованном состоянии, но это сложно и не слишком эффективно (насколько я знаю, только Firebird пошел таким путем).

Обычно же — в том числе и в PostgreSQL — данные, записанные на диск, оказываются несогласованными и при восстановлении после сбоя требуются специальные действия, чтобы согласованность восстановить. Журналирование — тот самый механизм, который делает это возможным.

Разговор о журналировании мы, как ни странно, начнем с буферного кеша. Буферный кеш — не единственная структура, которая хранится в оперативной памяти, но одна из самых важных и сложных. Понимание принципа его работы важно само по себе, к тому же на этом примере мы познакомимся с тем, как происходит обмен данными между оперативной памятью и диском.

Кеширование используется в современных вычислительных системах повсеместно, у одного только процессора можно насчитать три-четыре уровня кеша. Вообще любой кеш нужен для того, чтобы сглаживать разницу в производительности двух типов памяти, одна из которых относительно быстрая, но ее на всех не хватает, а другая — относительно медленная, но имеющаяся в достатке. Вот и буферный кеш сглаживает разницу между временем доступа к оперативной памяти (наносекунды) и к дисковой (миллисекунды).

Заметим, что у операционной системы тоже есть дисковый кеш, который решает ту же самую задачу. Поэтому обычно СУБД стараются избегать двойного кеширования, обращаясь к диску напрямую, минуя кеш ОС. Но в случае PostgreSQL это не так: все данные читаются и записываются с помощью обычных файловых операций.

Кроме того, свой кеш бывает также у контроллеров дисковых массивов, и даже у самих дисков. Этот факт нам еще пригодится, когда мы доберемся до вопроса надежности.

Но вернемся к буферному кешу СУБД.

Называется он так потому, что представляет собой массив буферов. Каждый буфер — это место под одну страницу данных (блок), плюс заголовок. Заголовок, в числе прочего, содержит:

  • расположение на диске страницы, находящейся в буфере (файл и номер блока в нем);
  • признак того, что данные на странице изменились и рано или поздно должны быть записаны на диск (такой буфер называют грязным);
  • число обращений к буферу (usage count);
  • признак закрепления буфера (pin count).


Изначально кеш содержит пустые буферы, и все они связаны в список свободных буферов. Смысл указателя на «следующую жертву» станет ясен чуть позже. Чтобы быстро находить нужную страницу в кеше, используется хеш-таблица.

Когда процессу требуется прочитать страницу, он сначала пытается найти ее в буферном кеше с помощью хеш-таблицы. Ключом хеширования служит номер файла и номер страницы внутри файла. В соответствующей корзине хеш-таблицы процесс находит номер буфера и проверяет, действительно ли он содержат нужную страницу. Как и с любой хеш-таблицей, здесь возможны коллизии; в таком случае процессу придется проверять несколько страниц.

Использование хеш-таблицы давно вызывает нарекания. Такая структура позволяет быстро найти буфер по странице, но совершенно бесполезна, если, например, надо найти все буферы, занятые определенной таблицей. Но хорошую замену пока никто не предложил.

Если нужная страница найдена в кеше, процесс должен «закрепить» буфер, увеличив счетчик pin count (несколько процессов могут сделать это одновременно). Пока буфер закреплен (значение счетчика больше нуля), считается, что буфер используется и его содержимое не должно «радикально» измениться. Например, в странице может появиться новая версия строки — это никому не мешает благодаря многоверсионности и правилам видимости. Но в закрепленный буфер не может быть прочитана другая страница.

Может получиться так, что необходимая страница не будет найдена в кеше. В этом случае ее необходимо считать с диска в какой-либо буфер.

Если в кеше еще остались свободные буферы, то выбирается первый же свободный. Но рано или поздно они закончатся (обычно размер базы данных больше чем память, выделенная под кеш) и тогда придется выбирать один из занятых буферов, вытеснить находящуюся там страницу и на освободившееся место прочитать новую.

Механизм вытеснения основан на том, что при каждом обращении к буферу процессы увеличивают счетчик числа обращений (usage count) в заголовке буфера. Таким образом те буферы, которые используются реже остальных, имеют меньшее значение счетчика и являются хорошими кандидатами на вытеснение.

Алгоритм clock-sweep перебирает по кругу все буферы (используя указатель на «следующую жертву»), уменьшая на единицу их счетчики обращений. Для вытеснения выбирается первый же буфер, который:

  1. имеет нулевой счетчик обращений (usage count),
  2. и не закреплен (нулевой pin count).

После того, как буфер найден, с ним происходит следующее.

Буфер закрепляется, чтобы показать остальным процессам, что он используется. Помимо закрепления используются и другие средства блокировки, но подробнее об этом мы поговорим отдельно.

Если буфер оказался грязным, то есть содержит измененные данные, страницу нельзя просто выбросить — сначала ее требуется сохранить на диск. Это не очень хорошая ситуация, поскольку процессу, который собирается прочитать страницу, приходится ждать записи «чужих» данных, но этот эффект сглаживается процессами контрольной точки и фоновой записи, которые будут рассмотрены позже.

Далее в выбранный буфер читается с диска новая страница. Счетчик числа обращений устанавливается в единицу. Кроме того, ссылку на загруженную страницу необходимо прописать в хеш-таблицу, чтобы в дальнейшем ее можно было найти.

Теперь ссылка на «следующую жертву» указывает на следующий буфер, а у только что загруженного есть время нарастить счетчик обращений, пока указатель не обойдет по кругу весь буферный кеш и не вернется вновь.

Как это принято в PostgreSQL, существует расширение, которое позволяет заглянуть внутрь буферного кеша.


Создадим таблицу и вставим в нее одну строку.


Что окажется в буферном кеше? Как минимум, в нем должна появиться страница, на которую добавлена единственная строка. Проверим это следующим запросом, в котором мы выбираем только буферы, относящиеся к нашей таблице (по номеру файла relfilenode), и расшифровываем номер слоя (relforknumber):


Так и есть — в буфере одна страница. Она грязная (isdirty), счетчик обращений равен единице (usagecount), и она не закреплена ни одним процессом (pinning_backends).

Теперь добавим еще одну строку и повторим запрос. Для экономии букв мы вставляем строку в другом сеансе, а длинный запрос повторяем командой \g .

Новых буферов не прибавилось — вторая строка поместилась на ту же страницу. Обратите внимание, что счетчик использований увеличился.

И после обращения к странице на чтение счетчик тоже увеличивается.

А если выполнить очистку?

Очистка создала карту видимости (одна страница) и карту свободного пространства (три страницы — минимальный размер этой карты).

Размер кеша устанавливается параметром shared_buffers. Значение по умолчанию — смехотворные 128 Мб. Это один из параметров, которые имеет смысл увеличить сразу же после установки PostgreSQL.


Имейте в виду, что изменение параметра требует перезапуска сервера, поскольку вся необходимая под кеш память выделяется при старте сервера.

Из каких соображений выбирать подходящее значение?

Даже самая большая база имеет ограниченный набор «горячих» данных, с которыми ведется активная работа в каждый момент времени. В идеале именно этот набор и должен помещаться в буферный кеш (плюс некоторое место для «одноразовых» данных). Если размер кеша будет меньше, то активно используемые страницы будут постоянно вытеснять друг друга, создавая избыточный ввод-вывод. Но и бездумно увеличивать кеш тоже неправильно. При большом размере будут расти накладные расходы на его поддержание, и кроме того оперативная память требуется и для других нужд.

Таким образом, оптимальный размер буферного кеша будет разным в разных системах: он зависит от данных, от приложения, от нагрузки. К сожалению, нет такого волшебного значения, которое одинаково хорошо подойдет всем.

Стандартная рекомендация — взять в качестве первого приближения 1/4 оперативной памяти (для Windows до версии PostgreSQL 10 рекомендовалось выбирать размер меньше).

А дальше надо смотреть по ситуации. Лучше всего провести эксперимент: увеличить или уменьшить размер кеша и сравнить характеристики системы. Конечно, для этого надо иметь тестовый стенд и уметь воспроизводить типовую нагрузку — на производственной среде такие опыты выглядят сомнительным удовольствием.

Обязательно посмотрите доклад Николая Самохвалова на PgConf-2019: "Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных"

Но некоторую информацию о происходящем можно почерпнуть прямо на живой системе с помощью того же расширения 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 для обработки.

Устройство буферного кэша

Кэш нужен чтобы читать востребованные данные ни с диска а с более быстрой оперативной памяти. Предварительно данные приходится загружать с диска в буферных кэш оперативной памяти.

Есть 3 варианта размера страниц:

Буферный кэш занимает большую часть общей памяти.

Если процессу понадобятся какие-то данные он их вначале ищет в буферном кэше. Если данных в кэше не оказалось, то мы просим операционную систему прочитать эту страничку и поместить в буферный кэш. Операционная система имеет свой дисковые кэш, и ищет эту страничку там, если не находит, то читает с диска и помещает в дисковый кэш. Затем из дискового кэша страничка помещается в буферный кэш для PostgreSQL.

Так как буферный кэш находится в общей памяти, то чтобы разные процессы не мешали друг другу, к нему применяют различные блокировки.

Рисунок двойной буферизации Postgresql

Алгоритм вытеснения

Чтобы буферный кэш не переполнился нужно редко используемые страницы из него вытеснять. Другими словами удалить из буфера. Если мы страничку поменяли, то она считается грязной, и перед вытеснением из буфера её нужно записать на диск. Если мы страничку не меняли то и записывать на диск её ещё раз не имеет смыла.

В PostgreSQL реализован алгоритм вытеснения страниц из буфера при котором в кэше остаются самые часто используемые страницы.

Журнал предзаписи (WAL)

После сбоя наша база становится рассогласованной. Какие-то страницы менялись и были записаны, другие не успели записаться.

Когда мы хотим поменять какую-то страницу памяти, мы предварительно пишем, что хотим сделать в журнал предзаписи. И запись в этом журнале должна попасть на диск раньше, чем сама страница будет записана на диск.

В случае сбоя мы смотрим в журнал предзаписи и видим какие действия выполнялись, проделываем эти действия заново и восстанавливаем согласованность данных.

Почему запись в WAL эффективнее чем запись самой страницы? При записи страницы памяти на диск она пишется в произвольное место, это место еще нужно выбрать, подготовить для записи и начать запись. А запись в журнал ведется одним потоком и с этим потоком нормально справляются и обычные жёсткие диски и ssd.

WAL защищает всё что попадает в буферный кэш:

  • страницы таблиц, индексов;
  • статусы транзакций.

WAL не защищает:

  • временные таблицы;
  • нежурналируемые таблицы.

Производительность WAL

По умолчанию, каждый раз, когда транзакция фиксирует изменения, результат должен быть сброшен на диск. Для этого вначале страница сбрасывается из буферной памяти на дисковый кэш. А затем выполняется операция fsync для записи страницы на диск. То есть частые COMMIT приводят к частым fsync.

В асинхронном режиме postgresql работает быстрее, но вы можете потерять некоторые данные при сбое.

Режим работы настраивается с помощью конфигурационного файла и настройки не требуют перезагрузки сервера. Это позволяет приложению устанавливать параметры на лету. Некоторые транзакции сразу запишут изменения на диск, то есть поработают в синхронном режиме. Другие транзакции будут работать в асинхронном режиме. Условно можно поделить операции на критичные и не критичные.

Следующие параметры отвечают за режим работы WAL:

Контрольная точка

Сброс данных при контрольной точке не проходит моментально, это бы сильно нагрузило наш сервер. Чтобы не было пиковых нагрузок сброс идет примерно 50% времени от времени между контрольными точками. Например, контрольные точки делаются каждую минуту, тогда сброс осуществляют плавно в течении 30 секунд. Это регулируется и вы можете установить например 90% времени.

Контрольная точка также уменьшает размер необходимого дискового пространства. Так как весь журнал WAL не нужен, его можно периодически подрезать.

Отдельный серверный процесс контрольных точек автоматически выполняет контрольные точки с заданной частотой. Эту частоту можно настроить следующими параметрами:

Значения по умолчанию: 5 минут и 1 Гбайт, соответственно. Если после предыдущей контрольной точки новые записи WAL не добавились, следующие контрольные точки будут пропущены, даже если проходит время checkpoint_timeout. Также можно выполнить контрольную точку принудительно, воспользовавшись SQL-командой CHECKPOINT.

Уменьшение значений checkpoint_timeout и max_wal_size приводит к учащению контрольных точек. Но появляется дополнительная нагрузка на сервер.

Процессы, связанные с буферным кэшем и журналом

Уровни журналов

Практика

В журнале WAL каждая запись имеет номер LSN (Log Sequence Number). С помощью функции pg_current_wal_lsn() можно посмотреть номер текущей записи:

У нас вышло 138 KB! Так много получилось из за создания таблички, создание 1000 строк почти не нагрузит WAL.

Физически журнал хранится в файлах по 16 МБ в отдельном каталоге (PGDATA/pg_wal). На журнал можно взглянуть не только из файловой системы, но и с помощью функцию pg_ls_waldir():

Посмотреть на выполняемые процессы сервера postgres можно так:

К процессам, обслуживающим буферный кэш и журнал, можно отнести:

  • checkpointer;
  • background writer;
  • walwriter;

Теперь давайте остановим сервер корректно и посмотрим в лог файл:

Как видим сервер просто открыл соединения на сокете и tcp порту 5432 и начал работу.

Теперь завершим работу сервера некорректно, используя опцию immediate:

Как видим журнал изменился! Перед тем, как начать принимать соединения, СУБД выполнила восстановление (automatic recovery in progress).

Читайте также: