Порядковые номера журналов CLFS
В общей файловой системе журналов (CLFS) каждая запись журнала в заданном потоке однозначно идентифицируется по номеру последовательности журнала (LSN). При записи записи в поток возвращается номер LSN, который идентифицирует эту запись для последующей ссылки.
Номера LSN, созданные для определенного потока, образуют строго увеличивающуюся последовательность. То есть номер LSN, назначенный записи журнала в заданном потоке, всегда больше номера LSN, назначенные записям журнала, ранее записанным в тот же поток. Для сравнения LSN записей журнала в заданном потоке доступны следующие функции.
Константы CLFS_LSN_NULL и CLFS_LSN_INVALID являются нижней и верхней границами для всех допустимых LSN. Любой допустимый номер LSN больше или равен CLFS_LSN_NULL. Кроме того, любой допустимый номер LSN строго меньше CLFS_LSN_INVALID. Обратите внимание, что CLFS_LSN_NULL является допустимым номером LSN, а CLFS_LSN_INVALID — недопустимым номером LSN. Несмотря на это, вы можете сравнить CLFS_LSN_INVALID с другими номерами LSN с помощью функций из предыдущего списка.
Для каждого потока CLFS отслеживает два специальных номера LSN: базовый номер LSN и последний номер LSN. Кроме того, каждая отдельная запись журнала имеет два специальных номера LSN (предыдущий номер LSN и undo-next LSN), которые можно использовать для создания цепочек связанных записей журнала. В следующих разделах эти специальные номера LSN подробно описаны.
Базовый номер LSN
Когда клиент записывает первую запись в поток, CLFS присваивает базовому номеру LSN номер LSN этой первой записи. Базовый номер LSN остается неизменным до тех пор, пока клиент не изменит его. Если клиентам потока больше не нужны записи до определенного момента в потоке, они могут обновить базовый номер LSN, вызвав ClfsAdvanceLogBase или ClfsWriteRestartArea. Например, если клиентам больше не нужны первые пять записей журнала, они могут задать базовый номер LSN шестой записи.
последний номер LSN
Когда клиенты записывают записи в поток, CLFS корректирует последний номер LSN таким образом, чтобы он всегда был номером LSN последней записанной записи. Если клиентам больше не нужны записи после определенного момента в потоке, они могут обновить последний номер LSN, вызвав ClfsSetEndOfLog. Например, если клиентам больше не нужны записи, записанные после десятой записи, они могут усечь поток, задав для последнего номера LSN номер LSN десятой записи.
Активная часть потока
Активная часть потока — это часть потока, которая начинается с записи, на которую указывает базовый номер LSN, и заканчивается записью, на которую указывает последний номер LSN. На следующей схеме показано, как базовый номер LSN и последний номер LSN обозначают активную часть потока.
Примечание Если поток имеет архивный хвост, активная часть потока начинается с записи, на которую указывает базовый номер LSN или хвост архива, в зависимости от того, какой из значений меньше. Дополнительные сведения о архивации см. в разделе Поддержка архивации CLFS.
Предыдущий номер LSN
Предположим, что две активные транзакции базы данных (транзакция A и транзакция B) записывают записи в один и тот же поток одновременно. Каждый раз, когда транзакция A записывает запись, она устанавливает предыдущий номер LSN записи в номер LSN предыдущей записи журнала, записанной транзакцией A. Это формирует цепочку записей журнала, принадлежащих транзакции A, которую можно просмотреть в обратном порядке. Цепочка заканчивается первой записью журнала, записанной транзакцией A, для которой для предыдущего номера LSN задано значение CLFS_LSN_INVALID. Аналогичным образом транзакция B создает собственную цепочку записей журнала, задавая предыдущий номер LSN каждой записи журнала, которую она записывает.
Стрелки на следующей схеме иллюстрируют, как предыдущий номер LSN записи журнала указывает на предыдущую запись в цепочке, принадлежавшей определенной транзакции.
Отменить следующий номер LSN
Предположим, что транзакция выполняет пять обновлений объекта данных в энергонезависимой памяти, откатывает четвертое и пятое обновления, а затем выполняет шестое обновление. По мере того как транзакция выполняет обновления, она записывает записи журнала 1, 2, 3, 4, 5, 5', 4' и 6. Записи журнала с 1 по 5 описывают изменения, внесенные обновлениями с 1 по 5. Запись 5' описывает изменения, внесенные во время отката обновления 5, а запись 4' — изменения, внесенные во время отката обновления 4. Наконец, запись 6 описывает изменения, внесенные обновлением 6. Обратите внимание, что номера 1, 2, 3, 4, 5, 5', 4 и 6 не являются номерами LSN записей журнала; это просто числа, используемые для имен записей журнала для целей этого обсуждения.
Записи журнала 5' и 4', которые описывают откаты, называются записями журнала компенсации (CLR). Транзакция задает номер LSN undo-next каждой среды CLR предшественника (среди записей, записанных транзакцией) записи журнала, обновление которой было только что откатировано (отменено). В этом примере номер LSN undo-next записи 5' является номером LSN записи 4, а номер LSN undo-next для записи 4' — номером LSN записи 3.
Для обычных записей журнала (тех, которые не являются CLR) для их отмены следующего номера LSN задана предыдущая запись журнала, записанная транзакцией. То есть для обычной записи номер LSN отмены и предыдущий номер LSN совпадают.
Теперь предположим, что произошел сбой системы, и во время восстановления перезапуска необходимо выполнить откат всей транзакции. Код восстановления считывает запись журнала 6. Данные в записи 6 указывают, что запись 6 является обычной записью (а не средой CLR), поэтому код восстановления откатывает обновление 6. Затем код восстановления проверяет следующий номер LSN отмены записи 6 и обнаруживает, что он указывает на запись 4'. Данные в записи 4' указывают на то, что это среда CLR, поэтому код восстановления не выполняет откат обновления 4'. Вместо этого он проверяет следующий номер LSN отмены записи 4', и находит, что указывает на запись 3. Запись 3 не является средой CLR, поэтому код восстановления выполняет откат обновления 3. Обновления 5 и 4 не откатываются во время восстановления, так как они уже были откатированы во время обычной обработки вперед. Наконец, код восстановления откатывает обновления 2 и 1.
Стрелки на следующей схеме иллюстрируют, как номер LSN undo-next предоставляет механизм, который код восстановления может использовать для пропуска записей, обновления которых уже были откатаны.