在日志备份期间,数据是备份到操作开始还是结束?

Geo*_*ios 14 sql-server backup sql-server-2012 transaction-log

假设我正在运行日志备份,并且该日志备份需要 10 分钟才能完成。在这 10 分钟的窗口中,将运行进一步的事务。鉴于以下示例,日志备份实际上包含哪些事务?

  1. 事务 A 提交
  2. 事务 B 打开
  3. 日志备份开始
  4. 交易 C 开启
  5. 事务 B 提交
  6. 日志备份完成
  7. 事务 C 提交

Ron*_*ldo 15

日志备份文件应包含直到备份完成运行的所有事务(包括尚未提交的事务),您可以按如下方式验证它:

CREATE DATABASE MyDB;
ALTER DATABASE MyDB SET RECOVERY FULL;

USE MyDB;
CREATE TABLE LogTest (numbers int);
Run Code Online (Sandbox Code Playgroud)

一旦创建了将用于测试的数据库和表,请进行第一次完整备份,以便稍后进行日志备份。

BACKUP DATABASE MyDB 
TO DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL14.SQL2017\MSSQL\Backup\MyDB_FULL.bak';
Run Code Online (Sandbox Code Playgroud)

现在进行了完整备份,让我们在表中插入一些数据:

USE MyDB;

INSERT INTO LogTest(numbers) VALUES (1);

BEGIN TRAN
INSERT INTO LogTest(numbers) VALUES (2);
Run Code Online (Sandbox Code Playgroud)

观察到第二个插入位于BEGIN TRAN尚未提交的a 下。接下来,我们将使用函数 [fn_dblog 在进行日志备份之前检查日志文件的内容。

SELECT [Current LSN], [Operation], [SPID], [Transaction Name], [Begin Time], [End Time] FROM fn_dblog(NULL, NULL);
Run Code Online (Sandbox Code Playgroud)

在图片上我们可以看到与第一个和第二个 INSERT 相关的 LSN

第一次查询结果

BACKUP LOG MyDB 
TO DISK = 'C:\Program Files\Microsoft SQL Server\MSSQL14.SQL2017\MSSQL\Backup\MyDB_LOG.trn';
Run Code Online (Sandbox Code Playgroud)

进行了日志备份,我们可以使用函数fn_dump_dblog使用以下查询读取其内容:

SELECT [Current LSN], [Transaction ID], [Transaction Name], [Operation], [Begin Time] 
FROM fn_dump_dblog (NULL, NULL, N'DISK', 1, N'C:\Program Files\Microsoft SQL Server\MSSQL14.SQL2017\MSSQL\Backup\MyDB_LOG.trn',
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT,
DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT);
Run Code Online (Sandbox Code Playgroud)

第二次查询结果

正如我们可以看到这些相关的未完成交易的LSN实际上即使其未提交的事务日志备份。问题在于,正如微软所说

事务日志是数据库的关键组件。如果出现系统故障,您将需要该日志来使您的数据库恢复到一致状态。

因此,在执行该日志备份的恢复之后,与那些未完成事务相关的数据将被回滚以保持数据库处于一致状态。您可以考虑安全(可以恢复)所有已提交的事务。可以通过删除数据库 MyDB 并恢复使用上述步骤生成的备份来验证。


Jon*_*ite 6

事务日志包含在事务日志完成时完全提交的所有事务。

使用上面的示例,事务日志包含 A 和 B。这类似于完整备份,它包含备份完成时提交的所有事务的尾日志备份。

这个网站是很好的进一步阅读。 https://sqlbak.com/academy/transaction-log-backup

  • 请注意,日志备份可能包含_所有_事务 C 的日志记录,而不是提交记录。因此,使用 WITH RECOVERY 还原该日志备份将首先重做,然后撤消事务 C。 (4认同)