在镜像生产数据库上收缩事务日志文件的最简单方法

在镜像生产数据库上收缩事务日志文件最简单的方法是什么?

我必须,因为我的磁盘空间不足了。

在执行此操作之前,我会做一个完整的数据库备份,所以我不需要保留事务日志中的任何东西(对吗?我每天都有完整的数据库备份,可能永远不需要时间点恢复,尽pipe我会保留如果可以的话,这个选项是打开的 – 这就是所有的.ldf是真的,对吗?)。

解决了:
OK, 通过SSMS (而不是TSQL)对日志进行2次备份 ,创build一个全新的备份集 ,SSMS中的Shrink-Files-Log对话框最终实际工作,释放了一些磁盘空间。

不知道为什么需要2个备份,或为什么TSQL不起作用,收缩对话框中报告的“可回收空间”没有差别(第一次备份之后的所有收缩尝试都是99%但是,仍然没有释放任何空间),但现在解决了问题。 谢谢大家。

使用任何您感觉最舒适的方法进行事务日志备份。

这将导致已经提交到数据库的事务日志从磁盘中删除。 理想情况下,实际上你应该创build一个数据库维护任务,为了这个原因定期为你做这个事情 – 消除旧的事务日志,所以你不会填满你的磁盘。

根据你的问题的其他位…不,不是真的。 是的,他们执行这个function,但不仅仅是这个function。

数据库不会以其他文件传统的方式进行备份(或写入),因为数据库文件本身一直在使用并不断变化。 因此,备份单个“时间点”需要使数据库脱机以“冻结”一致的状态,或导致备份的不同部分包含与备份开始时不同的数据。

什么事务日志是数据库执行的每个“事务”的logging。 这些操作不是在每次更改,更新,添加或删除logging时写入数据库文件,而是写入单独的文件,事务日志,然后在SQL服务器确定安全时将其提交到数据库文件这样做没有任何活动停下来。 所以事务日志实际上是在数据库实际上变成数据库[文件]之前变化的地方。

因此,如果您需要回到给定的数据库状态或时间点,则“重播”事务日志。 本质上,不复制文件数据,而是转到为数据库find的最新的时间点状态,然后执行所有使数据库达到指定的[稍后]状态的相同的事情。 但是,需要注意的是,在任何时候,您的事务日志将包含尚未提交给数据库的事务。 所以它们不仅仅是执行时间点恢复的能力。 它们包含正在进行的一些更改,或者很快将对数据库进行更改。

这就是为什么您在清除事务日志之前被迫执行备份的原因 – 一旦备份完成,系统就会有一个时间点的数据库备份以供将来的恢复使用, 能够确定哪些事务具有一直致力于数据库,而没有。 通过这些信息,系统知道哪些过时的事务日志要删除,哪些不会。

但是,这可能需要一些时间,具体取决于事务日志的大小。 如果你以前从来没有做过,那么就要花点时间。

这是一个较老的问题,但有些事情没有得到很好的解释,希望能够给我们一些启示。 大多数人都回答了这个问题,但是这将解释你实际上在做什么的“原因”。

备份,特别是日志备份,可以做几件事情。 将数据写入磁盘作为备份集,以便根据需要稍后使用或丢弃。 每个后续的备份都添加到该集中,在完全logging的数据库中。 截断日志或启动一个新的备份集打破了链条,并且在很多情况下会阻止您恢复到断链之前的某个时间点的能力。

日志中的数据实际上并未被删除,日志文件在备份过程中也没有收缩。 活动的VLF被标记为非活动状态,除非那些不能完全提交的活动 – 它们保持活动状态。 不活跃的VLF可以重写,使你的日志成为圆形,就像蛇吃自己的尾巴一样。 作为备份的一部分发出检查点,一旦当前的VLF填满,就会通知数据库开始写入日志的开头。 如果此时执行缩小操作,您将收回日志末尾的所有空间,直到活动VLF的位置。

第二次备份似乎“诀窍”的原因是因为在此期间活动的VLF通常会填满,并且从头开始写入日志。 在进行第二次备份时,活动的VLF作为备份集的一部分(或不是)写入磁盘,并且VLF被标记为非活动状态。 由于这是由于前一次缩小而导致的日志尾部,因此执行缩小现在可以将所有空间释放到日志开头,直到当前活动的VLF。

所有这一切都假设了两件事:1)你没有大量的VLF需要花费几个小时或几天的时间来填满,2)你的数据库是相当不活跃的,没有一大堆事务被写入日志。 如果这些条件中的任何一个对您来说都是个问题,那么缩小日志也是一个问题。

所有这些对于未镜像和镜像数据库都是如此。 不同之处在于,您只需要在镜像场景中对主服务器执行维护,假定镜像的构build方式相同。

镜像function使用日志来跟踪事物,直到知道其他服务器有这些更改。 所以,不,ldf不仅仅是针对时间点的恢复。 (这对于一些复制scheme也很重要,但是你不这样做。)甚至TRUNCATE_ONLY也不会抛弃SQL可能需要的东西的logging更改。 典型的例子是一些大型或长期运行的交易。 如果您正在进行一个小时的事务,而DBA运行TRUNCATE_ONLY,那么您的东西将不会从LDF中清除。 LDF可能会继续增长或遇到其他问题。 如果DBA杀死你的连接,等待回滚完成,然后运行TRUNCATE_ONLY,那么日志应该释放。

你有没有尝试过使用:

 select log_reuse_wait_desc from sys.databases where name = 'mydb' 

看看为什么日志是如此之大? 微软文件系统表在这里 。

你也可以运行:

 dbcc opentran() 

这是一种老派,但它应该显示在该数据库中的任何长期运行的交易。 微软文件在这里命令 。

我会做的是确保有一个日程安排发生在日程安排上。

我会确保给TRUNCATE_ONLY命令一小段时间的工作,有时需要一段时间才能开始写入到LDF文件前面的VLF。 如果LDF文件中的最后一个VLF是正在写入的文件,则SQL不能缩短文件。 否则,我会做一个完整的BACKUP DATABASE(使用COPY_ONLY,或者等到定期备份发生,如果将来不太远的话)。 有时候,这似乎启动了一些东西,但可能只是在等待当前VLF移动到LDF文件的前面时,备份会让我分心。 在当前的VLF移动到LDF文件的前面之后,您应该可以使用dbcc shrinkfile()并获得预期的结果。 我build议先尝试去除小块,而不是一次尝试完成。

同样,你也想避免这样做,因为进入一个重复的缩小自动缩小缩小自动增长循环可能是一个性能杀手。 (这可能会导致文件碎片化,实际的增长过程可能会花费大量的时间,在此期间无法进行事务处理。将文件放大到足够大以避免自动增长。自动增长应该是一种失败的安全措施,不依赖于。