Wal postgresql что это

Sysadminium

База знаний системного администратора

Буферный кэш и журнал WAL в PostgreSQL

Рассмотрим технологии которые обеспечивают высокую производительность и безопасность работы сервера PostgreSQL, а именно “Буферный кэш” и “Журнал предзаписи WAL“. В документации об этом можете почитать тут.

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

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

В общей памяти отводится определённый кусок памяти под массив буферов. В каждом буфере хранится одна страница памяти. Страница памяти это 8 КБ. Когда мы собираем PostgreSQL из исходных кодов мы можем изменить размер этой страницы. А после сборки это изменить уже не получится.

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

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

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

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

Wal postgresql что это. image 1. Wal postgresql что это фото. Wal postgresql что это-image 1. картинка Wal postgresql что это. картинка image 1

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

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

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

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

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

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

Журнал предварительной записи (WAL) – механизм, которым позволит нам восстановить согласованность данных после сбоя.

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

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

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

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

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

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

В PostgreSQL есть другой режим работы – асинхронный. При этом каждый COMMIT не приводит к fsync. Вместо этого страницы сбрасываются на диск по расписанию специальным процессом – WALWRITER. Этот процесс периодически просыпается и записывает на диск всё что изменилось за время пока он спал и опять засыпает.

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

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

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

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

При выполнении контрольной точки (CHECKPOINT) – принудительно сбрасываются на диск все грязные страницы, которые есть в буферном кэше. Это гарантирует что на момент контрольной точки все данные сбросились на диск и при восстановлении данных нужно читать не весь журнал 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() можно посмотреть номер текущей записи:

Запомним номер текущей записи WAL в переменной “pos1”, затем создадим табличку с 1000 строк и опять сохраним текущий LSN в переменной “pos2”. Затем посмотрим разницу между этими числами, но в формате LSN, и получим число байт записанных в WAL при создании таблички с 1000 строками:

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

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

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

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

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

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

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

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

Источник

Wal postgresql что это

Параметр wal_level определяет, как много информации записывается в WAL. Со значением replica (по умолчанию) в журнал записываются данные, необходимые для поддержки архивирования WAL и репликации, включая запросы только на чтение на ведомом сервере. Вариант minimal оставляет только информацию, необходимую для восстановления после сбоя или аварийного отключения. Наконец, logical добавляет информацию, требующуюся для поддержки логического декодирования. Каждый последующий уровень включает информацию, записываемую на всех уровнях ниже. Задать этот параметр можно только при запуске сервера.

Однако минимальный журнал не будет содержать достаточно информации для восстановления данных из базовой копии и журналов, поэтому для реализации стратегии архивации WAL (см. archive_mode) и потоковой репликации необходим уровень replica или более высокий.

Если этот параметр установлен, сервер PostgreSQL старается добиться, чтобы изменения были записаны на диск физически, выполняя системные вызовы fsync() или другими подобными методами (см. wal_sync_method). Это даёт гарантию, что кластер баз данных сможет вернуться в согласованное состояние после сбоя оборудования или операционной системы.

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

Параметр fsync можно задать только в файле postgresql.conf или в командной строке при запуске сервера. Если вы отключаете этот параметр, возможно, имеет смысл отключить также и full_page_writes. synchronous_commit ( enum )

Определяет, после завершения какого уровня обработки WAL сервер будет сообщать об успешном выполнении операции. Допустимые значения: remote_apply (применено удалённо), on (вкл., по умолчанию), remote_write (записано удалённо), local (локально) и off (выкл.).

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

Характеристики различных значений synchronous_commit сведены в Таблице 19.1.

Таблица 19.1. Режимы synchronous_commit

значение synchronous_commitгарантированная локальная фиксациягарантированная фиксация на ведомом после сбоя PGгарантированная фиксация на ведомом после сбоя ОСсогласованность запросов на ведомом
remote_apply
on
remote_write
local
off

Метод, применяемый для принудительного сохранения изменений WAL на диске. Если режим fsync отключён, данный параметр не действует, так как принудительное сохранение изменений WAL не производится вовсе. Возможные значения этого параметра:

open_datasync (для сохранения файлов WAL открывать их функцией open() с параметром O_DSYNC )

fdatasync (вызывать fdatasync() при каждом фиксировании)

fsync (вызывать fsync() при каждом фиксировании)

fsync_writethrough (вызывать fsync() при каждом фиксировании, форсируя сквозную запись кеша)

open_sync (для сохранения файлов WAL открывать их функцией open() с параметром O_SYNC )

Когда этот параметр включён, сервер PostgreSQL записывает в WAL всё содержимое каждой страницы при первом изменении этой страницы после контрольной точки. Это необходимо, потому что запись страницы, прерванная при сбое операционной системы, может выполниться частично, и на диске окажется страница, содержащая смесь старых данных с новыми. При этом информации об изменениях на уровне строк, которая обычно сохраняется в WAL, будет недостаточно для получения согласованного содержимого такой страницы при восстановлении после сбоя. Сохранение образа всей страницы гарантирует, что страницу можно восстановить корректно, ценой увеличения объёма данных, которые будут записываться в WAL. (Так как воспроизведение WAL всегда начинается от контрольной точки, достаточно сделать это при первом изменении каждой страницы после контрольной точки. Таким образом, уменьшить затраты на запись полных страниц можно, увеличив интервалы контрольных точек.)

Отключение этого параметра не влияет на возможность применения архивов WAL для восстановления состояния на момент времени (см. Раздел 25.3).

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

Этот параметр позволяет без дополнительных рисков повреждения данных уменьшить объём WAL, ценой дополнительной нагрузки на процессор, связанной со сжатием данных при записи в WAL и разворачиванием их при воспроизведении WAL. wal_init_zero ( boolean )

Если этот параметр включён ( on ), создаваемые файлы WAL заполняются нулями. В ряде файловых систем благодаря этому заранее выделяется пространство, которое потребуется для записи WAL. Однако с файловыми системами, работающими по принципу COW ( Copy-On-Write, Копирование при записи), это может быть бессмысленно, поэтому данный параметр позволяет отключить в данном случае неэффективное поведение. Со значением off в создаваемый файл записывается только последний байт, чтобы файл WAL сразу обрёл желаемый размер. wal_recycle ( boolean )

Если этот параметр имеет значение on (по умолчанию), файлы WAL используются повторно (для этого они переименовываются), что избавляет от необходимости создавать новые файлы. В файловых системах COW может быть быстрее создать новые файлы, поэтому данный параметр позволяет отключить это поведение. wal_buffers ( integer )

Содержимое буферов WAL записывается на диск при фиксировании каждой транзакции, так что очень большие значения вряд ли принесут значительную пользу. Однако значение как минимум в несколько мегабайт может увеличить быстродействие при записи на нагруженном сервере, когда сразу множество клиентов фиксируют транзакции. Автонастройка, действующая при значении по умолчанию (-1), в большинстве случаев выбирает разумные значения. wal_writer_delay ( integer )

Когда выбран wal_level minimal и фиксируется транзакция, которая создавала или перезаписывала постоянное отношение, этот параметр определяет, как будут сохраняться новые данные. Если объём данных меньше заданного значения, они будут записываться в журнал WAL; в противном случае затронутые файлы просто синхронизируются с ФС. Изменение этого параметра в зависимости от характеристик вашего хранилища может быть полезным, если при фиксировании такой транзакции наблюдается замедление других транзакций. Если это значение задаётся без единиц измерения, оно считается заданным в килобайтах. Значение по умолчанию — два мегабайта ( 2MB ). commit_delay ( integer )

В PostgreSQL до версии 9.3, параметр commit_delay работал по-другому и не так эффективно: он задерживал только фиксирование транзакций, а не все операции сохранения WAL, и заданная пауза выдерживалась полностью, даже если WAL удавалось сохранить быстрее. Начиная с версии 9.3, заданное время ожидает только первый процесс, готовый произвести сохранение, тогда как все последующие процессы ждут только, когда он закончит эту операцию. commit_siblings ( integer )

19.5.2. Контрольные точки

Максимальное время между автоматическими контрольными точками в WAL. Если это значение задаётся без единиц измерения, оно считается заданным в секундах. Допускаются значения от 30 секунд до одного дня. Значение по умолчанию — пять минут ( 5min ). Увеличение этого параметра может привести к увеличению времени, которое потребуется для восстановления после сбоя. Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера. checkpoint_completion_target ( floating point )

Задаёт целевое время для завершения процедуры контрольной точки, как коэффициент для общего времени между контрольными точками. По умолчанию это значение равно 0.5. Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера. checkpoint_flush_after ( integer )

Когда в процессе контрольной точки записывается больше заданного объёма данных, сервер даёт указание ОС произвести запись этих данных в нижележащее хранилище. Это ограничивает объём «грязных» данных в страничном кеше ядра и уменьшает вероятность затормаживания при выполнении fsync в конце контрольной точки или когда ОС сбрасывает данные на диск большими порциями в фоне. Часто это значительно уменьшает задержки транзакций, но бывают ситуации (особенно когда объём рабочей нагрузки больше shared_buffers, но меньше страничного кеша ОС), когда производительность может упасть. Этот параметр действует не на всех платформах. Если значение параметра задаётся без единиц измерения, оно считается заданным в блоках (размер которых равен BLCKSZ байт, обычно это 8 КБ). Он может принимать значение от 0 (при этом управление отложенной записью отключается) до 2 мегабайт ( 2MB ). Значение по умолчанию — 256kB в Linux и 0 в других ОС. (Если BLCKSZ отличен от 8 КБ, значение по умолчанию и максимум корректируются пропорционально.) Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера. checkpoint_warning ( integer )

Пока WAL занимает на диске меньше этого объёма, старые файлы WAL в контрольных точках всегда перерабатываются, а не удаляются. Это позволяет зарезервировать достаточно места для WAL, чтобы справиться с резкими скачками использования WAL, например, при выполнении больших пакетных заданий. Если это значение задаётся без единиц измерения, оно считается заданным в мегабайтах. Значение по умолчанию — 80 МБ. Этот параметр можно установить только в postgresql.conf или в командной строке сервера.

19.5.3. Архивация

Когда параметр archive_mode включён, полные сегменты WAL передаются в хранилище архива командой archive_command. Помимо значения off (выключающего архивацию) есть ещё два: on (вкл.) и always (всегда). В обычном состоянии эти два режима не различаются, но в режиме always архивация WAL активна и во время восстановления архива, и при использовании ведомого сервера. В этом режиме все файлы, восстановленные из архива или полученные при потоковой репликации, будут архивироваться (снова). За подробностями обратитесь к Подразделу 26.2.9.

Параметры archive_mode и archive_command разделены, чтобы команду архивации ( archive_command ) можно было изменять, не отключая режим архивации. Этот параметр можно задать только при запуске сервера. Режим архивации нельзя включить, когда установлен минимальный уровень WAL ( wal_level имеет значение minimal ). archive_command ( string )

Этот параметр можно задать только в postgresql.conf или в командной строке при запуске сервера. Если режим архивации ( archive_mode ) не был включён при запуске, этот параметр игнорируется. Если значение archive_command — пустая строка (по умолчанию), но archive_mode включён, архивация WAL временно отключается, но сервер продолжает накапливать файлы сегментов WAL в ожидании, что команда будет вскоре определена. Если в качестве archive_command задать команду, которая ничего не делает, но сообщает об успешном завершении, например /bin/true (или REM в Windows), архивация по сути отключается, но при этом нарушается цепочка файлов WAL, необходимых для восстановления архива, поэтому такой вариант следует использовать только в особых случаях. archive_timeout ( integer )

19.5.4. Восстановление из архива

В этом разделе описываются параметры, действующие только в процессе восстановления. Они должны сбрасываться для любой последующей операции восстановления.

Под « восстановлением » здесь понимается и использование сервера в качестве ведомого, и выполнение целевого восстановления данных. Обычно ведомые серверы используется для обеспечения высокой степени доступности и/или масштабируемости чтения, тогда как целевое восстановление производится в случае потери данных.

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

Этот параметр можно задать только при запуске сервера. archive_cleanup_command ( string )

Этот необязательный параметр указывает команду оболочки ОС, которая будет вызываться при каждой точке перезапуска. Назначение команды archive_cleanup_command — предоставить механизм очистки от старых архивных файлов WAL, которые более не нужны на ведомом сервере. Любое вхождение %r заменяется на имя файла, содержащего последнюю действительную точку перезапуска. Это самый ранний файл, который необходимо хранить для возможности восстановления, а более старые файлы вполне можно удалить. Эта информация может быть использована для усечения архива с целью его минимизации при сохранении возможности последующего восстановления из заданной точки. Модуль pg_archivecleanup часто используется в качестве archive_cleanup_command в конфигурациях с одним ведомым сервером, например:

Стоит обратить внимание, что в конфигурациях с множеством ведомых серверов, использующих общий архивный каталог для восстановления, необходимо контролировать удаление файлов WAL, так как они могут ещё быть нужны некоторым серверам. Поэтому archive_cleanup_command обычно используется при организации тёплого резерва (см. Раздел 26.2). Чтобы указать символ % в команде, продублируйте его ( %% ).

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

Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера. recovery_end_command ( string )

Этот параметр задаёт команду оболочки, которая будет выполнена единожды в конце процесса восстановления. Назначение параметра recovery_end_command — предоставить механизм для очистки после репликации или восстановления. Любое вхождение %r заменяется именем файла, содержащим последнюю действительную точку восстановления, например, как в archive_cleanup_command.

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

Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера.

19.5.5. Цель восстановления

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

Технически это строковый параметр, но значение ‘immediate’ — единственно допустимое в данный момент. recovery_target_name ( string )

Этот параметр указывает именованную точку восстановления (созданную с помощью pg_create_restore_point() ), до которой будет производиться восстановление. recovery_target_time ( timestamp )

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

Параметр указывает идентификатор транзакции, вплоть до которой необходимо произвести процедуру восстановления. Имейте в виду, что числовое значение идентификатора отражает последовательность именно старта транзакций, а фиксироваться они могут в ином порядке. Восстановлению будут подлежать все транзакции, что были зафиксированы до указанной (и, возможно, включая её). Точность точки останова также зависит от recovery_target_inclusive. recovery_target_lsn ( pg_lsn )

Следующие параметры уточняют целевую точку восстановления и определяют, что будет происходить при её достижении:

Задавать этот параметр обычно требуется только в сложных ситуациях с повторами восстановления, когда необходимо вернуться к состоянию, которое само было достигнуто после восстановления на момент времени. Это обсуждается в Подразделе 25.3.5. recovery_target_action ( enum )

Вариант pause позволяет выполнить запросы к базе данных и убедиться в том, что достигнутая цель оказалась желаемой точкой восстановления. Для снятия с паузы нужно вызвать pg_wal_replay_resume() (см. Таблицу 9.87), что в итоге приведёт к завершению восстановления. Если же окажется, что мы ещё не достигли желаемой точки восстановления, нужно остановить сервер, установить более позднюю цель и перезапустить сервер для продолжения восстановления.

Вариант shutdown полезен для получения готового экземпляра сервера в желаемой точке. При этом данный экземпляр сможет воспроизводить дополнительные записи WAL (а при перезапуске ему придётся воспроизводить записи WAL после последней контрольной точки).

В любом случае, если задана цель восстановления, но восстановление архива завершается до её завершения, сервер завершит работу с критической ошибкой.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *