13.2.26

Очистка журнала обнуляет записи журнала?

Автор: Paul Randal, A SQL Server DBA myth a day: (14/30) clearing the log zeroes out log records

Очистка журнала обнуляет записи журнала.

ЛОЖЬ

Журнал транзакций всегда инициализируется нулями при первом создании, ручном расширении или автоматическом расширении. Не путайте это с процессом очистки (clearing) журнала во время обычных операций. Очистка просто означает, что один или несколько VLF (виртуальных файлов журнала) помечаются как неактивные и доступные для перезаписи. Когда происходит очистка журнала, ничего не стирается и не перезаписывается. «Очистка журнала» — это очень сбивающее с толку неправильное название. Оно означает ровно то же самое, что и «усечение журнала», что является ещё одним неудачным термином, потому что размер журнала при этом вообще не меняется.

Вы можете прочитать больше об инициализации журнала нулями в моём посте в блоге Search Engine Q&A #24: Why can’t the transaction log use instant initialization? и о том, как работает очистка журнала, в моей статье для TechNet Magazine за февраль 2009 года: Понимание журналирования и восстановления в SQL Server.

Примечание переводчика: Новое в SQL Server 2022: изменение стратегии прироста журналов транзакций

Вы можете доказать это себе, используя флаг трассировки 3004. Его включение позволит вам увидеть, когда SQL Server выполняет операции обнуления файлов (как я описал в Миф: Мгновенной инициализацией файлов можно управлять изнутри SQL Server). Включите его и наблюдайте за сообщениями в течение дня — вы не должны ничего увидеть, если только журнал не растёт.

Вот скрипт, демонстрирующий, что я имею в виду:

DBCC TRACEON (3004, 3605);
GO

-- Создание базы данных и перевод в простую модель восстановления,
-- чтобы журнал очищался при контрольной точке
CREATE DATABASE [LogClearTest] ON PRIMARY (
    NAME = N'LogClearTest_data', FILENAME = N'D:\SQLskills\LogClearTest_data.mdf')
LOG ON (
    NAME = N'LogClearTest_log', FILENAME = N'D:\SQLskills\LogClearTest_log.ldf',
SIZE = 20MB);
GO

-- Метка 1 в журнале ошибок
ALTER DATABASE [LogClearTest] SET RECOVERY SIMPLE;
GO

USE [LogClearTest];
GO

-- Создание таблицы и заполнение 10 МБ - значит, 10 МБ в журнале
CREATE TABLE [t1] ([c1] INT IDENTITY, [c2] CHAR (8000) DEFAULT 'a');
GO
INSERT INTO [t1] DEFAULT VALUES;
GO 1280

-- Очистка журнала
CHECKPOINT;
GO

-- Метка 2 в журнале ошибок
ALTER DATABASE [LogClearTest] SET RECOVERY SIMPLE;
GO

И в журнале ошибок я вижу:

2010-04-13 13:20:27.55 spid53     DBCC TRACEON 3004, server process ID (SPID) 53. This is an informational message only; no user action is required.
2010-04-13 13:20:27.55 spid53     DBCC TRACEON 3605, server process ID (SPID) 53. This is an informational message only; no user action is required.
2010-04-13 13:20:27.63 spid53     Zeroing D:\SQLskills\LogClearTest_log.ldf from page 0 to 2560 (0x0 to 0x1400000)
2010-04-13 13:20:28.01 spid53     Zeroing completed on D:\SQLskills\LogClearTest_log.ldf
2010-04-13 13:20:28.11 spid53     Starting up database 'LogClearTest'.
2010-04-13 13:20:28.12 spid53     FixupLogTail() zeroing D:\SQLskills\LogClearTest_log.ldf from 0x5000 to 0x6000.
2010-04-13 13:20:28.12 spid53     Zeroing D:\SQLskills\LogClearTest_log.ldf from page 3 to 63 (0x6000 to 0x7e000)
2010-04-13 13:20:28.14 spid53     Zeroing completed on D:\SQLskills\LogClearTest_log.ldf
2010-04-13 13:20:28.16 spid53     Setting database option RECOVERY to SIMPLE for database LogClearTest.
2010-04-13 13:20:29.49 spid53     Setting database option RECOVERY to SIMPLE for database LogClearTest.

Две команды ALTER DATABASE служат маркерами в журнале ошибок. Между ними явно нет никакого обнуления, вызванного CHECKPOINT. Чтобы ещё больше убедить себя, вы можете добавить вызовы DBCC SQLPERF (LOGSPACE) до и после CHECKPOINT, чтобы показать, что журнал очищается при выполнении контрольной точки (следите за уменьшением значения в столбце Log Space Used (%).


Комментариев нет:

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