在镜像生产数据库上缩小事务日志文件的最简单方法是什么?
我必须这样做,因为我的磁盘空间快用完了。
在执行此操作之前,我将进行完整的数据库备份,因此我不需要保留事务日志中的任何内容(对吗?我每天都有完整的数据库备份,可能永远不需要时间点还原,但我会保留如果可以,请打开选项 - 这就是 .ldf 的全部用途,对吗?)。
已解决:
好的,在通过 SSMS(不是 TSQL)仅对日志进行了 2 次备份,创建了一个全新的备份集之后,SSMS 中的 Shrink-Files-Log 对话框终于真正起作用了,释放了一些磁盘空间。
不确定为什么需要 2 次备份,或者为什么 TSQL 不起作用,并且收缩对话框中报告的“可回收空间”没有差异(第一次备份后所有收缩尝试都达到 99%也是,但仍然没有释放任何空间),但问题暂时解决了。谢谢大家。
这是一个较老的问题,但有些事情没有得到很好的解释,希望这会有所启发。主要回答了如何收缩,但这将解释您实际在做什么的“为什么”部分。
备份,特别是日志备份,可以做几件事。数据作为备份集写入磁盘,以便以后根据需要使用或丢弃。每个后续备份都添加到该集合,在一个完全记录的数据库中。截断日志或开始新的备份集会破坏链条并抑制,或者在许多情况下,使您无法恢复到链条被破坏之前的某个时间点。
日志中的数据实际上并没有被删除,备份期间日志文件也没有缩小。活动的 VLF 被标记为非活动的,除了那些不能完全提交的 - 它们保持活动状态。不活动的 VLF 可以被重写,使您的日志循环,实际上就像一条蛇在吃自己的尾巴。作为备份的一部分,会发出一个检查点,一旦当前 VLF 填满,它就会告诉 DB 开始写入日志的开头。如果此时执行收缩,您将获得日志末尾的所有空间,直至活动 VLF 点。
第二次备份似乎“成功”的原因是因为活跃的 VLF 通常在这段时间内填满并且日志从头开始写入。当你进行第二次备份时,活动的 VLF 被写入磁盘作为备份集的一部分(或不是),并且 VLF 被标记为非活动的。由于之前的收缩,这是日志的尾端,执行收缩现在释放所有空间到日志的开头,直到当前活动的 VLF。
所有这一切都假设了一些事情,1.) 你没有大量的 VLF 需要数小时或数天才能填满 2.) 你的数据库相当不活跃并且没有一堆事务被写入日志. 如果这些条件中的任何一个对您来说是一个问题,那么缩小日志也将是一个问题。
所有这些对于非镜像和镜像数据库都是正确的。区别在于您只需要在镜像场景中对主服务器执行维护,假设您的镜像是相同构建的。
使用您觉得最舒服的任何方法进行事务日志备份。
这将导致已提交到数据库的事务日志从磁盘中删除。理想情况下,您实际上应该创建一个数据库维护任务来定期为您执行此操作,正是出于这个原因——消除旧的事务日志,这样您就不会填满磁盘。
根据你的问题的其他部分......不,不是真的。是的,他们执行该功能,但不仅仅是该功能。
数据库不像其他文件那样以传统方式备份(或写入),因为数据库文件本身一直在使用和不断变化。因此,单个“时间点”备份要么需要使数据库脱机以将其“冻结”在一致状态,要么导致备份的不同部分包含与备份开始时不同的数据。
事务日志是数据库执行的每个“事务”的记录。不是每次更改、更新、添加、删除等记录时都写入数据库文件,而是将这些操作写入一个单独的文件,一个事务日志,然后在 SQL 服务器确定它是安全的时候提交到数据库文件中在不停止任何活动的情况下这样做。因此,事务日志实际上是对数据库的更改在它们实际成为对数据库 [文件] 的更改之前进行的地方。
因此,如果您需要返回给定的数据库状态或时间点,事务日志将被“重放”。本质上,不是复制文件数据,而是转到为数据库找到的最新时间点状态,然后执行所有使数据库达到指定 [稍后] 状态的相同操作。但是,请务必注意,在任何给定时间,您的事务日志都将包含尚未提交到数据库的事务。因此,它们不仅仅是执行时间点恢复的能力。它们包含正在进行或即将对数据库进行的 [某些] 更改。
这就是为什么您在清除事务日志之前被迫进行备份的原因 - 一旦备份完成,系统就会有一个数据库的时间点副本以供将来恢复时参考,并且能够确定哪些事务具有已经提交给数据库,哪些还没有。有了这些信息,系统就知道哪些过时的事务日志可以为您删除,哪些不需要。
但是,这可能需要一些时间,具体取决于事务日志的大小。如果您以前从未做过,请做好准备,这需要一段时间。
镜像功能使用日志来跟踪事情,直到它知道其他服务器有那些更改。所以,不,ldf 不仅仅用于时间点恢复。(这对于某些复制方案也很重要,但您没有这样做。)即使是 TRUNCATE_ONLY 也不会丢弃 SQL 可能需要的内容的已记录更改。典型的例子是一些大型或长时间运行的事务。如果您在一个小时的事务处理过程中进行了一半,而 DBA 运行了 TRUNCATE_ONLY,您的内容将不会从 LDF 中清除。LDF 可能会继续增长或遇到其他问题。如果 DBA 终止了您的连接,等待回滚完成,然后运行 TRUNCATE_ONLY,那么日志应该被释放。
您是否尝试过使用:
看看日志为什么这么大?Microsoft在此处记录该系统表。
您还可以运行:
这有点老派,但它应该会向您显示该数据库中任何长时间运行的事务。Microsoft在此处记录该命令。
我会做的是确保按计划进行日志备份。
我会确保我给 TRUNCATE_ONLY 命令一些时间来工作,有时 SQL 需要一段时间才能开始向 LDF 文件的前面写入 VLF。如果 LDF 文件中的最后一个 VLF 是正在写入的那个,则 SQL 无法缩短该文件。如果做不到这一点,我会做一个完整的 BACKUP DATABASE(使用 COPY_ONLY,或者等到定期备份发生,如果将来不会太远的话)。有时这似乎启动了一些事情,但它可能只是在等待当前 VLF 移动到 LDF 文件的前面时备份分散了我的注意力。在当前 VLF 移动到 LDF 文件的前面之后,您应该可以使用 dbcc shrinkfile() 并获得预期的结果。我建议先尝试移除小块,而不是尝试一次性完成所有操作。
此外,您要避免定期执行此操作,因为进入重复的收缩-自动增长-收缩-自动增长循环可能会成为性能杀手。(它会导致文件碎片化,实际的增长过程会花费大量的时间,在此期间没有事务能够提交。将文件增长到足够大,这样它们就不会自动增长。自动增长应该是一个故障安全的事情并且不依赖。