在 SQL Server 中仅在必要时进行日志备份

Jos*_*h W 6 sql-server backup transaction-log

我们每隔几分钟就会从许多数据库中备份事务日志。有没有办法确定自上次备份以来是否有任何提交的事务,然后才进行日志备份?

例如,某些数据库在夜间没有任何更改。但是每次运行日志备份脚本时,我们仍然会为这些数据库获得许多微小的日志备份。

我已经尝试根据记录在 msdb 中的先前备份的 last_lsn 编写脚本,并使用 fn_dblog 来查看是否有新提交的事务。到目前为止我还没有成功。


一点背景:

这些日志备份每隔几分钟进行一次并保存到 Azure Blob 存储。它们不会恢复到另一个数据库(又名日志传送)。在一天之内,我们将获得每个数据库数百个日志备份。如果我们不得不从 Azure 恢复某些内容,我想避免有 100 甚至 1000 个日志文件,其中没有任何用户事务,从而延长了恢复过程。

Mik*_*Fal 6

此处的一种替代方法是使用 来计算事务日志中活动事务的大小DBCC LOGINFO。你的逻辑看起来像这样:

CREATE TABLE #vlfs(
   RecoveryUnitID int
  ,  FileID      int
  , FileSize    bigint
  , StartOffset bigint
  , FSeqNo      bigint
  , [Status]    bigint
  , Parity      bigint
  , CreateLSN   numeric(38)
);

DECLARE @MBthreshhold int

SELECT @MBthreshhold = 5 --Enter your threshhold in MB here

INSERT INTO #vlfs
EXEC ('DBCC LOGINFO')

IF (select sum(filesize/1024/1024) 
    from #vlfs
    where [Status] = 2) > @MBthreshhold
BEGIN
    BACKUP LOG [foo] to <<backup location>>
END
Run Code Online (Sandbox Code Playgroud)

请注意,这里有很多注意事项。您的事务日志永远不会完全为空,并且总有一些东西可以备份。您可以使用它来确定实际运行备份的大小点,但这可能会给您的恢复点目标 (RPO)带来巨大风险。您的日志备份会在不同的时间进行,这意味着您永远无法保证在灾难中会发生最大的数据丢失量。应极其谨慎地采取这种策略。


Aar*_*and 5

我认为,如果你有数据库,你知道有在某些时期少(或无尤)的活动,你应该在这些时期只是备份日志较少。总会有一些日志流失,确定它是由用户还是系统活动引起的将是一场噩梦(并且几乎总是会有一些微小级别的系统活动,即使是在空闲系统上)。如果您想在不创建大量日志备份的情况下增强保护,您可以考虑更频繁地进行 FULL(和/或 DIFF)备份。

在任何情况下,您都不应该围绕您认为减少 http 请求的数量会加快速度这一事实来设计恢复策略。您的恢复时间应主要取决于您要恢复的总体数据量,而不是文件数或 http 请求数。由于恢复是非常罕见的事件,您可能会想象优化您一直在做的事情比优化您希望永远不必做的事情更重要。

话虽如此,Paul Randal 确实编写了一个存储过程,可以告诉您下一次备份中将有多少数据 - 我认为在每次日志备份之前运行它似乎代价高昂,只是为了看看是否值得进行备份,但是嘿 - 我可以用枪指着你,你知道你的脚在哪里。剩下的就看你了。我不会窃取他的代码,而是将其指向您:


efe*_*sar 0

这样的事情会有帮助吗?它会告诉您最后一笔交易发生的时间,这就是开始。

如何读取SQL Server数据库事务日志

您是否计划手动恢复这些备份,或者您是否有一个读取文件列表并按顺序恢复它们的脚本?如果第二个选项是您的情况,我建议获取文件大小,如果为 0,则跳过该文件。