Содержимое файла журнала транзакций более подробно

11

У меня есть вопрос, касающийся журнала транзакций (давайте просто назовем его LDF). Я предполагаю, что база данных с полной моделью восстановления.

Я прочитал, что файл LDF содержит (журналы) каждую операцию с базой данных (то есть в режиме полного восстановления). Как это отличается от регистрации во время BEGIN TRAN; COMMAND(s); COMMIT? Я спрашиваю, потому что, очевидно, вы можете откатить транзакции, но вы не можете откатить стандартные команды (в режиме полного восстановления).

Я предполагаю, что во время транзакции содержимое, которое регистрируется в файле LDF, отличается от обычного полного журнала восстановления. Это правильно? Чем это отличается? Это только включение операций отмены для каждого действия?

Относительно примечания я слышал, что существуют коммерческие инструменты для «отката / отмены» стандартных запросов с использованием файла полного восстановления LDF. Как они это делают? Анализируют ли они содержимое LDF и пытаются ли выполнить обратные / отмененные операции?

Никогда не переставай учиться
источник
Связанный: Как просмотреть журналы транзакций в SQL Server 2008 на переполнении стека.
Вадим

Ответы:

11

Разница в том, что то, что вы называете «стандартными командами», имеет неявные транзакции (как в « неявных » и не реальных неявных транзакциях, которые означают что-то другое ), поэтому каждый раз, когда вы вводите INSERTкоманду без явной транзакции, она открывает транзакцию, вставить данные и автоматически зафиксировать. Это называется транзакцией автоматического принятия.

Это также, почему вы не можете откатить это INSERT: это уже зафиксировано. Таким образом, правило аналогично явным транзакциям: вы не можете откатиться после того, как они были зафиксированы .

Вы можете видеть, что я имею в виду прямо из SQL Server.

Microsoft поставляет SQL Server с DMF, sys.fn_dblogкоторый можно использовать для просмотра журнала транзакций данной базы данных.

Для этого простого эксперимента я собираюсь использовать базу данных AdventureWorks:

USE AdventureWorks2008;
GO

SELECT TOP 10 *
FROM dbo.Person;
GO

INSERT INTO dbo.Person (FirstName, MiddleName, LastName, Gender, Date)
VALUES ('Never', 'Stop', 'Learning', 'M', GETDATE());
COMMIT;

BEGIN TRAN;
INSERT INTO dbo.Person (FirstName, MiddleName, LastName, Gender, Date)
VALUES ('Never', 'Stop', 'Learning', 'M', GETDATE());
COMMIT;
GO

SELECT *
FROM sys.fn_dblog(NULL, NULL);
GO

Здесь я делаю две вставки: одну с и без явной транзакции.

В файле журнала вы можете видеть, что между ними нет абсолютно никакой разницы:

Автокоммит против явных транзакций

Красный - INSERTвнутри транзакции с автоматическим подтверждением, а синий - INSERTс явной транзакцией.

Что касается сторонних инструментов, о которых вы упомянули, то они анализируют журнал базы данных и генерируют обычный код T-SQL для «отмены» или «повторения» операций. Под обычным я подразумеваю, что они не делают ничего особенного, кроме генерации скрипта, который будет иметь эффект, противоположный тому, что находится в файле журнала.

ivanmp
источник
7

Я объясню, как работают коммерческие инструменты, на примере ApexSQL Log

И из соответствующей заметки я слышал, что есть коммерческие инструменты для «отката / отмены» стандартных запросов с использованием файла полного восстановления LDF. Как они это делают? Анализируют ли они содержимое LDF и пытаются ли выполнить обратные / отмененные операции?

Да, они читают файл LDF (онлайн или отдельно) и файлы trn (резервные копии журнала транзакций), находят, какая транзакция произошла, и создают сценарий, который будет делать то же самое или наоборот.

Однако обратите внимание, что сценарии отмены и повторения не обязательно должны быть точно такими же, как выполняемые, но эффект будет точно таким же.

Например, если выполненный скрипт был:

DELETE FROM [Person].[AddressType] WHERE Name  = 'New Loc22'

В журнале транзакций будет записано, что строка в таблице со значениями столбца 9, «Новый Loc22», «41BC2FF6-F0FC-475F-8EB9-CEC1805AA0F6» и «2002/06/01 00: 00: 00.000» удалена. Из структуры таблицы инструмент прочитает, что первичный ключ является столбцом AddressType, и создаст следующий скрипт повторного выполнения:

DELETE FROM [Person].[AddressType] WHERE [AddressTypeID] = 9

Обратите внимание, что транзакция связана со столбцом первичного ключа, а не со столбцом, использованным в предложении where. Точно так же скрипт отмены будет:

INSERT INTO [Person].[AddressType] ([AddressTypeID], [Name], [rowguid], [ModifiedDate]) VALUES (9, N'New loc22' COLLATE SQL_Latin1_General_CP1_CI_AS, '41bc2ff6-f0fc-475f-8eb9-cec1805aa0f6', '20020601 00:00:00.000')

введите описание изображения здесь

Отказ от ответственности: я работаю для ApexSQL в качестве инженера службы поддержки

Милена Петрович
источник