Журналирование
Контрольная точка
13
Авторские права
© Postgres Professional, 2016–2022.
Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Процесс контрольной точки
Процесс фоновой записи
Мониторинг
3
Контрольная точка
Необходимость контрольной точки
Процесс выполнения контрольной точки
Алгоритм восстановления после сбоя
Настройка
4
Необходимость
Размер хранимых журнальных записей
с какого сегмента начинать применять журнальные записи
при восстановлении?
активно использующаяся страница может не вытесняться из кеша
Время восстановления
сколько времени займет восстановление после сбоя?
Если не принять специальных мер, то активно использующаяся
страница, попав в буферный кеш, может никогда не вытесняться.
Это означает, что при восстановлении после сбоя нам пришлось бы
просматривать все журнальные записи, созданные с момента запуска
сервера.
На практике это, конечно, недопустимо. Во-первых, файлы занимают
много места — их все придется хранить на сервере. Во-вторых, время
восстановления будет запредельно большим — придется просмотреть
множество журнальных записей.
Поэтому и существует специальный фоновый процесс контрольной
точки (checkpointer), который периодически сбрасывает все грязные
страницы на диск (но не вытесняет их из кеша). После того как
контрольная точка завершена, журнальные записи, предшествующие
ее началу, больше не нужны для восстановления.
5
Процесс контрольной точки
записываются грязные буферы CLOG
CLOG
Рассмотрим подробнее, что происходит при выполнении контрольной
точки.
Во-первых, помимо буферного кеша, в оперативной памяти
располагаются и другие структуры, содержимое которых нужно
сохранять на диске.
Вmчастности, контрольная точка сбрасывает на диск буферы статуса
транзакций (CLOG). Поскольку количество таких буферов невелико
(ихm128 штук), они записываются сразу же.
6
Процесс контрольной точки
31 12
1 0
помечаются измененные страницы в буферном кеше
Во-вторых, основная работа контрольной точки — сбросить на диск все
страницы из буферного кеша, которые были грязными на момент
начала контрольной точки.
Поскольку размер буферного кеша может быть очень велик,
сбрасывать сразу все страницы плохо — это приостановит нормальную
работу сервера и создаст большую нагрузку на дисковую подсистему.
Поэтому контрольная точка растягивается во времени и фактически
превращается в отрезок.
Сначала все измененные на текущий момент страницы помечаются
в заголовке буфера специальным флагом...
7
Процесс контрольной точки
31 12
1 0
помеченные страницы постепенно записываются,
пометка убирается из заголовка буфера
checkpoint_completion_target = 0.5
стал
грязным
после начала
контрольной
точки
...а затем процесс контрольной точки постепенно проходит по всем
буферам и сбрасывает помеченные на диск. Отметим, что страницы
неmвытесняются из кеша, а только записываются. Поэтому контрольная
точка не обращает внимания на число обращений к буферу и признак
закрепленности.
Помеченные буферы могут также быть записаны и обслуживающими
процессами — смотря кто доберется до буфера первым. В любом
случае при записи снимается установленный ранее флаг, так что буфер
будет записан только один раз.
В процессе работы контрольной точки страницы продолжают
изменяться в буферном кеше. Но новые грязные буферы уже не
рассматриваются процессом контрольной точки, так как на момент
начала работы они не были грязными.
Активность записи грязных буферов определяется значением
параметра checkpoint_completion_target. Он показывает, какую часть
времени между двумя соседними контрольными точками следует
использовать для записи страниц. Значение по умолчанию равно 0.5,
тоmесть запись занимает примерно половину времени между
контрольными точками. Обычно значение увеличивают, например до
0.9, чтобы нагрузка была более равномерной. Значения выше 0.9
использовать не рекомендуется, поскольку фактически процесс может
занять несколько больше времени, чем указано в параметре.
8
Процесс контрольной точки
в журнале создается запись о завершении контрольной точки
с указанием момента ее начала
в файл pg_control записывается LSN контрольной точки
WAL
Latest checkpoint location: 3/B35D50E8
PGDATA/global/pg_control
в этот
момент началась
контрольная
точка
запись
о завершении
контрольной
точки
В конце работы процесс создает журнальную запись об окончании
контрольной точки. В этой записи содержится LSN момента начала
работы контрольной точки. Поскольку контрольная точка ничего не
записывает в журнал в начале своей работы, по этому LSN может
находиться любая журнальная запись.
Кроме того, в специальный файл PGDATA/global/pg_control
записывается указание на созданную журнальную запись. Таким
образом можно быстро выяснить последнюю пройденную контрольную
точку.
10
Восстановление
При старте сервера после сбоя
1. найти LSN
0
начала последней завершенной контрольной точки
2. применить каждую запись журнала, начиная с LSN
0
,
если LSN записи больше, чем LSN страницы
3. перезаписать нежурналируемые таблицы init-файлами
4. выполнить контрольную точку
xid
контрольная точка
контрольная точка сбой
необходимые файлы журнала
начало
восстановления
Если в работе сервера произошел сбой, при последующем запуске
процесс startup обнаруживает это (в файле pg_control статус отличен
от «shut down») и выполняет автоматическое восстановление.
Сначала процесс читает из того же файла LSN записи оmпоследней
контрольной точке. Из этой записи процесс узнает позицию LSN начала
контрольной точки.
(Для полноты картины заметим: если присутствует файл backup_label,
запись о контрольной точке читается из него — это нужно для
восстановления из резервных копий. Подробнее см. курс DBA3.)
Далее процесс startup читает журнал от найденной позиции,
последовательно применяя записи к страницам, если в этом есть
необходимость (что можно проверить, сравнив LSN страницы на диске
с LSN журнальной записи). Изменение страниц происходит в буферном
кеше, как при обычной работе.
Записи, относящиеся к страницам CLOG, восстанавливают статус
транзакций. Транзакции, не зафиксированные к концу восстановления,
считаются оборванными; их изменения не видны в снимках данных.
Аналогично записи применяются и к файлам: например, если запись
говорит, что файл должен быть создан, а его нет — файл создается.
В конце процесса все нежурналируемые таблицы перезаписываются
сmпомощью образов в init-файлах. На этом процесс startup завершает
работу, после чего процесс checkpointer выполняет контрольную точку,
чтобы зафиксировать восстановленное состояние.
12
Настройки
checkpoint_timeout = 5min
max_wal_size = 1GB
Частота контрольных точек
время
объем WAL
checkpoint_timeout
max_wal_size
о
б
ъ
е
м
з
а
о
д
н
у
к
о
н
т
р
о
л
ь
н
у
ю
т
о
ч
к
у
объем,
необходимый
для восста-
новления
Обычно контрольная точка настраивается из следующих соображений.
Сначала надо определиться, какая частота срабатываний нас
устраивает (исходя из допустимого времени восстановления и объема
журнальных файлов за это время при стандартной нагрузке). Чем реже
можно позволить себе контрольные точки, тем лучше — это сокращает
накладные расходы.
Устраивающая частота записывается в параметр checkpoint_timeout
(значение поmумолчанию — 5 минут — слишком мало, обычно время
увеличивают доmполучаса).
Однако возможна ситуация, когда нагрузка станет выше расчетной
иmза указанное время будет сгенерирован слишком большой объем
журнальных записей. Для этого в параметре max_wal_size указывают
общий допустимый объем журнальных записей.
Для восстановления после сбоя сервер должен хранить файлы
сmмомента последней контрольной точки, плюс файлы, накопившиеся
во время работы текущей контрольной точки. Поэтому общий объем
можно оценить как
(1 + checkpoint_completion_target) * объем-между-контр-точками.
Таким образом большая часть контрольных точек происходит
по расписанию, раз в checkpoint_timeout единиц времени. Но при
повышенной нагрузке контрольная точка вызывается чаще, чтобы
постараться уложиться в объем max_wal_size.
13
Объем файлов журнала
Сервер хранит журнальные файлы
необходимые для восстановления (обычно < max_wal_size)
еще не прочитанные через слоты репликации
еще не записанные в архив, если настроена непрерывная архивация
не превышающие по объему wal_keep_size
не превышающие по объему min_wal_size (при переиспользовании)
Настройки
max_wal_size = 1GB
wal_keep_size = 0
wal_recycle = on
min_wal_size = 80MB
Надо понимать, что объем, указанный в параметре max_wal_size,
может быть превышен. Это не жесткое ограничение, а ориентир для
процесса checkpointer, влияющий на активность записи грязных
буферов.
Кроме того, сервер не имеет права стереть журнальные файлы, еще
неmпереданные через слоты репликации, и файлы, еще не записанные
в архив при непрерывном архивировании. Это может привести
к перерасходу места, так что если этот функционал используется,
необходим постоянный мониторинг.
Можно на случай отставания реплики параметром wal_keep_size
установить минимальный объем файлов журнала, остающихся после
контрольной точки. Это не гарантирует, что журнальная запись
сохранится до момента, когда она понадобится реплике, но позволяет
работать без слота репликации.
По умолчанию журнальные файлы могут не удаляться, а просто
переименовываются и используются заново. Параметр min_wal_size
задает минимальный неудаляемый объем. Это позволяет сэкономить
на постоянном создании и удалении файлов. Однако для файловых
систем с copy-on-write быстрее создать новый файл, поэтому для них
рекомендуется отключить переиспользование, установив
wal_recycle=off.
15
Фоновая запись
Процесс фоновой записи
Настройка
16
Процесс фоновой записи
31 1
следующая
жертва
3
может быть
вытеснен, надо
записать
1 0
следующий
на запись
Когда обслуживающий процесс собирается вытеснить страницу
изmбуфера, он может обнаружить, что буфер грязный, и ему придется
записать страницу на диск. Чтобы этого не происходило, в дополнение
к процессу контрольной точки (checkpointer) существует также процесс
фоновой записи (background writer, bgwriter или просто writer).
Процесс фоновой записи использует тот же самый алгоритм поиска
буферов для вытеснения, что и обслуживающие процессы, только
использует свой указатель. Он может опережать указатель на «жертву»,
но никогда не отстает от него.
Записываются буферы, которые одновременно:
- содержат измененные данные (грязные),
- не закреплены (pin count = 0),
- имеют нулевое число обращений (usage count = 0).
Таким образом фоновый процесс записи находит те буферы, которые
сmбольшой вероятностью вскоре потребуется вытеснить. За счет этого
обслуживающий процесс скорее всего обнаружит, что выбранный им
буфер не является грязным.
17
Процесс фоновой записи
Алгоритм
уснуть на bgwriter_delay
если в среднем за цикл запрашивается N буферов, то записать
N * bgwriter_lru_multiplier bgwriter_lru_maxpages
грязных буферов
Настройки
bgwriter_delay = 200ms
bgwriter_lru_maxpages = 100
bgwriter_lru_multiplier = 2.0
Процесс фоновой записи работает циклами максимум
поmbgwriter_lru_maxpages страниц, засыпая между циклами
наmbgwriter_delay.
аким образом, если установить параметр bgwriter_lru_maxpages
в ноль, процесс фактически не будет работать.)
Точное число буферов для записи определяется по среднему
количеству буферов, которые запрашивались обслуживающими
процессами с прошлого цикла (используется скользящее среднее,
чтобы сгладить неравномерность между циклами, но при этом не
зависеть от давней истории). Вычисленное количество буферов
умножается на коэффициент bgwriter_lru_multiplier.
Если процесс совсем не обнаружил грязных буферов (то есть в системе
ничего не происходит), он «впадает в спячку», из которой его выводит
обращение серверного процесса за буфером. После этого процесс
просыпается и опять работает обычным образом.
Процесс фоновой записи имеет смысл настраивать после того, как
настроена контрольная точка. Совместно с контрольной точкой эти
процессы должны успевать записывать грязные буферы до того, как
они потребуются обслуживающим процессам.
18
Мониторинг
Контрольные точки
checkpoint_warning = 30s
log_checkpoints = off
Запись грязных буферов всеми процессами
представление pg_stat_bgwriter
Параметр checkpoint_warning позволяет выводить в журнал
предупреждения о слишком частом выполнении контрольных точек.
Если это происходит регулярно, следует подумать об увеличении
max_wal_size или уменьшении интервала между контрольными точками
checkpoint_timeout.
Включение параметра log_checkpoints выводит в журнал подробную
информацию о каждой выполненной контрольной точке.
Статистику работы процессов, записывающих грязные буферы
(контрольной точки, фоновой записи и обслуживающих процессов),
показывает представление pg_stat_bgwriter.
20
Итоги
Процесс контрольной точки ограничивает размер хранимых
журнальных файлов и сокращает время восстановления
Контрольная точка и фоновая запись сбрасывают на диск
грязные буферы
Обслуживающие процессы могут сбрасывать грязные
буферы, но не должны этим заниматься
21
Практика
1. Настройте выполнение контрольной точки раз в 30 секунд.
Установите параметры min_wal_size и max_wal_size в 16 МБ.
2. Несколько минут c помощью утилиты pgbench подавайте
нагрузку 100 транзакций/сек.
3. Измерьте, какой объем журнальных файлов был
сгенерирован за это время. Оцените, какой объем приходится
в среднем на одну контрольную точку.
4. Проверьте данные статистики: все ли контрольные точки
выполнялись по расписанию? Как можно объяснить
полученный результат?
5. Сбросьте настройки к значениям по умолчанию.