And*_*eas 11 sql-server backup transaction-log
我们正在使用具有完全恢复模式的 SQL Server。给定完整备份和一系列日志备份,我们希望能够检查从上次完整备份到当前尾日志的日志链是否完整。(没有实际恢复这些备份;这里的目的是测试备份的一致性。)
我已经知道如何对现有备份执行此操作:使用 RESTORE HEADERONLY 我获得每个文件的 FirstLSN 和 LastLSN,可以对连续文件进行比较,以确定它们是否兼容。
但是,我不知道如何检查尾部日志是否遵循上次日志备份。
如果我有尾日志的 FirstLSN,我可以将它与上次日志备份的 LastLSN 进行比较。但是如何获取尾日志的 FirstLSN 呢?
我需要一个适用于 SQL Server 2005 以上的解决方案(最好使用 t-sql)。到目前为止,我已经搜索过谷歌无济于事。顺便提一句。我首先在 stackoverflow 上发布了这篇文章;但是将它迁移到这里,因为它在那里被标记为离题。
编辑
我在一个小例子(SQL Server 2005,9.0.5057)上尝试了两个提供的解决方案:
BACKUP DATABASE TestDb TO DISK = 'C:\temp\backup test\Full.bak'
-- fire some update queries
BACKUP LOG TestDb TO DISK = 'C:\temp\backup test\Log1.bak'
-- fire both queries from the provided answers:
-- Martin Smith's answer yields: 838886656088920652852608
-- Shawn Melton's answer yields: 46000000267600001
RESTORE HEADERONLY FROM DISK = 'C:\temp\backup test\Log1.bak'
-- yields: 46000000267600001
Run Code Online (Sandbox Code Playgroud)
因此,第一个似乎偏离了几个数量级。
然后我对 SQL 2008 SP1 (10.00.2531) 进行了相同的测试,其中两个查询都产生了正确的答案。
小智 12
我转向我的SQL Server 2008 Internals副本,并指出DMV sys.database_recovery_status用于查找下一个日志备份的第一个 LSN。该列通过 BOLlast_log_backup_lsn为您提供:
最近一次日志备份的日志序列号。这是上一个日志备份的结束 LSN 和下一个日志备份的起始 LSN。
NULL= 不存在日志备份。数据库离线或数据库无法启动。
顺便提一下,如果数据库处于简单恢复模式(自动截断模式)或不存在日志备份,Kalen 还提出了一个问题,即您将获得 NULL 值。
但是如何获取尾日志的 FirstLSN 呢?
如果不实际备份数据库的尾日志(没有测试实例来尝试此操作),您可以从逻辑上得出结论,提到的列中返回的值将是下一个日志备份的第一个 LSN,在您的情况下尾巴。
因此,执行以下操作将返回我相信您正在寻找的值:
SELECT
last_log_backup_lsn
FROM
sys.database_recovery_status
WHERE
databse_id = DB_ID('MyDb')
Run Code Online (Sandbox Code Playgroud)
此 DMV 从 SQL 2005 开始可用。
编辑
除非您阅读 BOL 链接,请注意此 DMV 只会将值返回到在线数据库,或在 BOL 引用它时打开。如果发生需要您对数据库进行尾日志备份的故障,您将无法通过上述代码验证该值,除非该数据库可访问;如果失败,它可能不会。
像下面这样的事情应该做。
WITH LSN_CTE
AS
(
SELECT TOP 1
LEFT( LogRecords.[Current LSN], 8 ) AS Part1,
SUBSTRING( LogRecords.[Current LSN], 10, 8 ) AS Part2,
RIGHT( LogRecords.[Current LSN], 4 ) AS Part3
FROM sys.fn_dblog(NULL,NULL) AS LogRecords
ORDER BY [Current LSN]
)
SELECT CAST( CAST( CONVERT( varbinary, Part1, 2 ) AS int ) AS varchar ) +
RIGHT( '0000000000' + CAST( CAST( CONVERT( varbinary, Part2, 2 ) AS int ) AS varchar ), 10 ) +
RIGHT( '00000' + CAST( CAST( CONVERT( varbinary, Part3, 2 ) AS int ) AS varchar ), 5 ) AS [Converted LSN]
FROM LSN_CTE
Run Code Online (Sandbox Code Playgroud)
使用转换代码从十进制这篇文章。
这很ORDER BY [Current LSN]可能是完全不必要的开销。我不知道。此函数的结果似乎总是按 LSN 顺序排列,我猜它只是按顺序读取日志,但以防万一......
| 归档时间: |
|
| 查看次数: |
3107 次 |
| 最近记录: |