更详细的事务日志文件的内容

Nev*_*ing 11 sql-server recovery transaction-log

我有一个关于事务日志(我们简称为 LDF)内容的问题。我假设一个具有完整恢复模型的数据库。

我已经读过 LDF 文件包含(记录)对数据库的每个操作(即处于完全恢复模式)。它与记录期间有什么不同BEGIN TRAN; COMMAND(s); COMMIT?我问是因为显然您可以回滚事务,但不能回滚标准命令(在完全恢复模式下)。

我猜在事务期间记录到 LDF 文件中的内容与常规完整恢复日志记录中的内容不同。那正确吗?有什么不同?是否只包含每个动作的“撤消”操作?

在相关说明中,我听说有一些商业工具可以使用完整的恢复 LDF 文件“回滚/撤消”标准查询。他们是怎么做到的呢?他们是否分析 LDF 内容并尝试提出逆/撤消操作?

iva*_*nmp 11

不同之处在于,您所说的“标准命令”具有隐式事务(如“非显式”而不是真正的隐式事务,这意味着不同的事物),因此每次发出INSERT没有显式事务的命令时,它都会打开一个事务,插入数据并自动提交。这称为自动提交事务。

这也是你不能回滚INSERT它的原因:它已经提交。所以规则与显式事务相同:一旦提交就不能回滚

您可以直接从 SQL Server 内部了解我的意思。

Microsoft 提供带有 DMF 的 SQL Server,该 DMFsys.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
Run Code Online (Sandbox Code Playgroud)

在这里,我进行了两次插入:一次有显式事务,另一次没有显式事务。

在日志文件中,您可以看到两者之间绝对没有区别:

自动提交与显式事务

红色是INSERT在自动提交事务中,蓝色是在INSERT显式事务中。

至于您提到的第 3 方工具,是的,它们会分析数据库日志并生成正常的 T-SQL 代码来“撤消”或“重做”操作。通常我的意思是除了生成一个脚本之外,它们不会做任何特殊的事情,该脚本的效果与日志文件中的内容完全相反。


小智 7

我将在 ApexSQL Log 示例中解释商业工具的工作原理

在相关说明中,我听说有一些商业工具可以使用完整的恢复 LDF 文件“回滚/撤消”标准查询。他们是怎么做到的呢?他们是否分析 LDF 内容并尝试提出逆/撤消操作?

是的,他们读取 LDF 文件(联机或分离的)和 trn 文件(事务日志备份),查找发生的事务,并创建执行相同或相反操作的脚本。

但是请注意,撤消和重做脚本不必与执行的完全相同,但效果将完全相同。

例如,如果执行的脚本是:

DELETE FROM [Person].[AddressType] WHERE Name  = 'New Loc22'
Run Code Online (Sandbox Code Playgroud)

事务日志会记录表中列值为9、'New Loc22'、'41BC2FF6-F0FC-475F-8EB9-CEC1805AA0F6'、'2002/06/01 00:00:00.000'的行被删除。从表结构中,该工具将读取主键是 AddressType 列,并将创建以下重做脚本:

DELETE FROM [Person].[AddressType] WHERE [AddressTypeID] = 9
Run Code Online (Sandbox Code Playgroud)

请注意,事务与主键列相关联,而不是与原始 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')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

免责声明:我作为支持工程师为 ApexSQL 工作