Разберёмся с вопросом, возникшем в рассылке MCM. Речь шла о быстром восстановлении (подробно я объяснял его в заметке «Логирование блокировок и быстрое восстановление»), а если кратко — это возможность редакции Enterprise предоставить доступ к базе данных после завершения фазы REDO (повторное применение зафиксированных транзакций) восстановления после сбоя и до завершения фазы UNDO (отмена незавершённых транзакций) восстановления после сбоя. Идея в том, что UNDO может занимать намного больше времени, чем REDO, поэтому ранний доступ к базе — благо; именно поэтому это возможность редакции Enterprise (начиная с SQL Server 2005).
Суть вопроса: когда используется быстрое восстановление?
Ответ таков: оно применяется всякий раз, когда база данных запускается и ей требуется выполнение восстановления. Это означает, что быстрое восстановление будет использовано:
- когда SQL Server запускается после сбоя или остановки, при которой база данных не была корректно завершена;
- после переключения кластера;
- после переключения зеркалирования базы данных;
- после переключения группы доступности;
- когда состояние базы переводят в ONLINE и необходимо выполнить восстановление после сбоя.
Обратите внимание, чего здесь нет:
- восстановление базы данных из резервных копий;
- вывод в онлайн вторичной базы при доставке журналов (это также восстановление из резервных копий).
Быстрое восстановление НЕ используется во время операции восстановления. В некоторых местах в сети вы прочтёте, что используется, но это неверно.
Почему же оно не применяется в последовательности восстановления?
Дело в базовом механизме, который и делает возможным быстрое восстановление. Операции, изменяющие базу, протоколируются, и запись журнала включает битовую карту удерживаемых в тот момент блокировок (примеры есть в упомянутой выше статье блога). Когда выполняется восстановление после сбоя, фаза REDO также захватывает все блокировки, необходимые для фазы UNDO, поскольку REDO знает, какие транзакции в восстанавливаемом журнале предстоит откатить. К концу фазы REDO можно дать доступ к базе данных, потому что механизм восстановления может гарантировать, что пользователь не заблокирует фазу UNDO: необходимые для UNDO блокировки уже удерживаются.
Почему этот механизм не работает при восстановлении из резервной копии? Потому что восстановление — это не одна фаза REDO и одна фаза UNDO, как при восстановлении после сбоя. Для каждого бэкапа, применяемого в последовательности восстановления, выполняется фаза REDO. Это позволяет избежать очень длинной фазы REDO в самом конце последовательности восстановления (которая могла бы охватить, скажем, неделю транзакций, распределённых по десяткам или сотням бэкапов) и необходимости иметь огромный журнал транзакций для хранения всех этих записей.
К моменту окончания последовательности восстановления весь необходимый REDO уже выполнен, но операции REDO НЕ захватывали блокировки для UNDO. Эти блокировки не берутся потому, что следующей фазой в последовательности восстановления с высокой вероятностью будет не UNDO, а очередная операция восстановления. В таком случае вероятно, что часть транзакций, бывших незавершёнными на конец предыдущего шага восстановления, закоммитятся на следующем шаге; и если бы блокировки UNDO были захвачены заранее, их пришлось бы снова освобождать. Это повлекло бы либо повторное сканирование соответствующих записей журнала, либо отслеживание того, какие «в процессе восстановления» транзакции захватили какие блокировки. И то и другое сложно и затратно по времени, поэтому выгода признана недостаточной для требуемых инженерных усилий.
Итак, при восстановлении из резервных копий быстрого восстановления нет.
«Постойте, — скажете вы, — зеркалирование базы данных это же непрерывный процесс REDO, отчего же быстрое восстановление там работает?» В SQL Server 2005, когда происходило переключение зеркалирования, базу данных на мгновение переводили в состояние offline, чтобы при возврате в online было выполнено полное восстановление после сбоя — тем самым обеспечивалась работа быстрого восстановления. Начиная с SQL Server 2008, этого больше не происходит, поэтому существует механизм, который при переключении зеркалирования определяет, какие блокировки UNDO необходимы, что и позволяет реализовать поведение быстрого восстановления. Теоретически тот же механизм можно было бы перенести в код восстановления из бэкапов, но, на мой взгляд, сделать это было бы непросто, а запросов на такую доработку недостаточно, чтобы оправдать инженерные усилия и возможную дестабилизацию кода восстановления.

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