Ещё в 2009 году я писал о том, как работают контрольные точки (см. How do checkpoints work and what gets logged), и недавно получил по почте вопрос, который, как мне показалось, стоит оформить в короткую статью.
Вопрос (пересказ): Что произойдёт, если контрольная точка начнётся, но не успеет завершиться до сбоя? Будет ли она использована при восстановлении после сбоя?
Ответ: нет, не будет. Если оставить всё на этом, запись и правда вышла бы короткой, поэтому поясню мысль.
Назначение контрольной точки — привести страницы в файлах данных в соответствие с содержимым журнала транзакций. Когда контрольная точка завершается, даётся гарантия, что по состоянию на LSN (Log Sequence Number) записи журнала LOP_BEGIN_CKPT все изменения из записей журнала до этой точки уже сохранены в файлах данных на диске. Никаких гарантий насчёт записей журнала после этой точки нет — только до неё. Иными словами, все записи журнала до LSN записи LOP_BEGIN_CKPT больше не требуются для восстановления после сбоя, если только нет долгоживущей транзакции, начавшейся раньше этого LSN.
По завершении контрольной точки страница загрузки (boot page) базы данных (страница 9 в файле 1 — см. здесь для подробностей) обновляется начальным LSN контрольной точки (после чего, если используется режим SIMPLE, может произойти очистка/усечение журнала).
Следовательно, если контрольная точка началась, но не завершилась до сбоя, её LSN не окажется на странице загрузки, и восстановление после сбоя начнётся с предыдущей контрольной точки. Это правильно, потому что незавершённая контрольная точка не даёт гарантии, какие именно зафиксированные в журнале изменения уже записаны в файлы данных, а значит, восстановление не сможет корректно стартовать только с начала такой незавершённой контрольной точки.
Сопутствующий вопрос: Как SQL Server гарантирует, что в активной части журнала всегда есть хотя бы одна завершённая контрольная точка на случай сбоя?
Ответ: очистка/усечение журнала в VLF (виртуальном файле журнала), содержащем запись LOP_BEGIN_CKPT, невозможны до тех пор, пока не произойдёт ещё одна завершённая контрольная точка. Иными словами, после последней операции очистки/усечения должна произойти завершённая контрольная точка, прежде чем будет разрешена следующая очистка/усечение. Если контрольная точка не происходила, поле log_reuse_wait_desc для базы данных в sys.databases вернёт значение CHECKPOINT. Такое увидеть непривычно, но возможно, если контрольная точка длится очень долго (например, крупное обновление на системе с медленной подсистемой ввода-вывода, из-за чего сброс страниц файлов данных занимает много времени) и при этом очень часто выполняются резервные копии журнала, так что за время одной контрольной точки успевают пройти две копии журнала. Это также может случиться, если вы изменили параметр sp_configure recovery interval и задали его выше значения по умолчанию.

Комментариев нет:
Отправить комментарий