如何清除SQL Server事务日志?

我不是一个SQL专家,每当我需要做一些超出基本的事情时,我都会想起这个事实。 我有一个不大的testing数据库,但事务日志肯定是。 如何清除交易logging?

减小日志文件应该保留在遇到意想不到的增长的情况下,而不会再发生。 如果日志文件会再次增长到相同的大小,那么暂时收缩就不会太多。 现在,根据数据库的恢复目标,这些是您应该采取的操作。

首先,进行完整备份

如果出现问题,请不要对数据库进行任何更改,除非确保可以恢复数据库。

如果你关心时间点恢复

(通过时间点恢复,我的意思是您可以恢复到完全备份或差异备份以外的其他任何状态。)

推测你的数据库处于FULL恢复模式。 如果不是,那么确保它是:

 ALTER DATABASE testdb SET RECOVERY FULL; 

即使您正在定期进行完整备份,日志文件也会不断增长和增长,直到执行日志备份 – 这是为了您的保护,而不是不必要地浪费您的磁盘空间。 根据您的恢复目标,您应该经常执行这些日志备份。 例如,如果您的业务规则规定您在发生灾难时能够承受损失不超过15分钟的数据,那么您应该每15分钟备份一次日志。 这里是一个脚本,它将根据当前时间生成时间戳文件名(但是您也可以使用维护计划等来完成这项工作,只是不要在维护计划中select任何缩减选项,它们是可怕的)。

 DECLARE @path NVARCHAR(255) = N'\\backup_share\log\testdb_' + CONVERT(CHAR(8), GETDATE(), 112) + '_' + REPLACE(CONVERT(CHAR(8), GETDATE(), 108),':','') + '.trn'; BACKUP LOG foo TO DISK = @path WITH INIT, COMPRESSION; 

请注意, \\backup_share\应位于代表不同的基础存储设备的计算机上。 将这些备份到同一台计算机(或使用相同底层磁盘的不同虚拟机,或同一台物理主机上的不同虚拟机)并不能真正帮助您,因为如果计算机爆炸,您的数据库就会丢失它的备份。 根据您的networking基础设施,在本地备份然后将它们转移到幕后的其他位置可能更有意义; 无论哪种情况,都希望尽快将其从主数据库机器中取出。

现在,一旦你有正常的日志备份运行,把日志文件缩小到比现在更加合理的程度是合理的。 这并不意味着一次又一次地运行SHRINKFILE ,直到日志文件为1 MB – 即使您经常备份日志,仍然需要容纳可能发生的任何并发事务的总和。 日志文件自动增长事件是昂贵的,因为SQL Server必须将文件清零(与启用即时文件初始化时的数据文件不同),并且用户事务必须等待发生这种情况。 你希望尽可能less地做这种增长 – 缩小 – 增长 – 缩小的例程,你当然不希望让用户付钱。

请注意,您可能需要备份日志两次才能缩小(谢谢罗伯特)。

所以,你需要为你的日志文件提供一个实际的大小。 没有人可以告诉你什么是不知道更多关于你的系统,但如果你经常收缩日志文件,它又一次增长,一个很好的水印可能是最大的10-50% 。 假设这个数字是200 MB,并且你希望随后的自动增长事件为50 MB,那么你可以这样调整日志文件的大小:

 USE [master]; GO ALTER DATABASE Test1 MODIFY FILE (NAME = yourdb_log, SIZE = 200MB, FILEGROWTH = 50MB); GO 

请注意,如果日志文件当前> 200 MB,则可能需要先运行这个文件:

 USE yourdb; GO DBCC SHRINKFILE(yourdb_log, 200); GO 

如果你不关心时间点恢复

如果这是一个testing数据库,并且您不关心时间点恢复,那么您应该确保您的数据库处于SIMPLE恢复模式。

 ALTER DATABASE testdb SET RECOVERY SIMPLE; 

将数据库置于SIMPLE恢复模式将确保SQL Server重新使用部分日志文件(实质上是逐步停用非活动事务),而不是增长以保留所有事务的logging(例如FULL恢复直到备份日志为止) 。 CHECKPOINT事件将有助于控制日志,并确保它不需要增长,除非在CHECKPOINT之间生成大量的t日志活动。

接下来,你应该确保这个日志增长是真正由于一个不正常的事件(比如每年春季大扫除或重build你最大的指标),而不是由于日常的正常使用。 如果您将日志文件缩小到一个可笑的小尺寸,并且SQL Server只需再次增长以适应您的正常活动,那么您获得了什么? 你是否能够利用你暂时闲置的磁盘空间? 如果您需要立即修复,那么您可以运行以下命令:

 USE yourdb; GO CHECKPOINT; GO CHECKPOINT; -- run twice to ensure file wrap-around GO DBCC SHRINKFILE(yourdb_log, 200); -- unit is set in MBs GO 

否则,请设定适当的规模和增长率。 根据时间点恢复情况下的示例,您可以使用相同的代码和逻辑来确定适当的文件大小,并设置合理的自动增长参数。

有些事情你不想做

  • 使用TRUNCATE_ONLY选项备份日志,然后使用SHRINKFILE备份日志 。 首先,这个TRUNCATE_ONLY选项已被弃用,并且在当前版本的SQL Server中不再可用。 其次,如果您处于FULL恢复模式,则会破坏您的日志链,并需要新的完整备份。

  • 分离数据库,删除日志文件,然后重新附加 。 我不能强调这是多么危险。 你的数据库可能不会回来,它可能会怀疑,你可能不得不恢复到备份(如果你有一个)等等。

  • 使用“缩小数据库”选项DBCC SHRINKDATABASE和维护计划选项执行相同的操作是不好的想法,特别是如果你真的只需要解决日志问题。 使用DBCC SHRINKFILEALTER DATABASE ... MODIFY FILE (上面的示例)来定位要调整的文件并独立进行调整。

  • 将日志文件收缩到1 MB 。 这看起来很诱人,因为,嘿,SQL Server会让我在某些情况下做到这一点,并看看它释放的所有空间! 除非你的数据库是只读的( ALTER DATABASE ,你应该使用ALTER DATABASE标记),否则这将会导致许多不必要的增长事件,因为日志必须适应当前的事务,而不pipe恢复模式如何。 暂时释放这个空间的意义何在,SQL Server能够缓慢而痛苦地恢复?

  • 创build第二个日志文件 。 这将暂时缓解已经充满磁盘的驱动器,但这就像试图用创可贴修复被刺破的肺。 您应该直接处理有问题的日志文件,而不是仅仅添加另一个潜在的问题。 除了将一些事务日志活动redirect到另一个驱动器之外,第二个日志文件对于您(与第二个数据文件不同)确实不起作用,因为一次只能使用其中一个文件。 保罗·兰德尔还解释了为什么多个日志文件可能会咬你 。

主动

不要把你的日志文件缩小到一小部分,而是让它不断地以一个小的速度自动增长,把它设置为一个相当大的尺寸(一个容纳最大并发事务集合的容量),并设置一个合理的自动增长设置为后备,以便不必多次增长以满足单个交易,因此在正常的业务运营期间必须增长的情况相对较less。

这里最糟糕的设置是1 MB的增长或10%的增长。 有趣的是,这些是SQL Server的默认设置(我已经抱怨过,并要求更改无效 ) – 数据文件为1 MB,日志文件为10%。 前者在这个时代太小了,而后者每次都会导致越来越长的事件(比如你的日志文件是500MB,第一个增长是50MB,下一个增长是55MB,接下来的增长是60.5MB等等等等 – 在慢I / O上,相信我,你会真正注意到这条曲线)。

进一步阅读

请不要在这里停下来; 尽pipe大部分关于缩减日志文件的build议本质上是不好的,甚至可能是灾难性的,但有些人更关心数据完整性而不是释放磁盘空间。

四年前我写了一篇博文,当时我看到一些“这里是如何缩小日志文件”的post 。

一篇博客文章Brent Ozar在四年前写了一篇文章,指出了多种资源,以回应一篇不应该发表的SQL Server杂志文章 。

Paul Randal的一篇博客文章解释了为什么t日志维护很重要 , 为什么你不应该收缩你的数据文件 。

迈克·沃尔什(Mike Walsh)也有一个很好的回答,其中包括了一些这方面的内容,包括你可能无法立即收缩你的日志文件的原因 。

免责声明:请仔细阅读下面的评论,我想你已经阅读了接受的答案。 正如我近5年前所说:

如果任何人有任何意见添加情况下,这不是一个足够的或最佳的解决scheme,请评论下面


  • 右键点击数据库名称。

  • select任务 – >收缩 – >数据库

  • 然后点击确定!

我通常打开包含数据库文件的Windows资源pipe理器目录,以便我可以立即看到效果。

其实我很惊讶这个工作! 通常我以前使用过DBCC,但是我只是尝试过,并没有收缩任何东西,所以我尝试了GUI(2005),它工作得很好 – 在10秒内释放了17Gb

编辑:在完全恢复模式下,这可能不起作用,所以您必须先备份日志,或更改为简单恢复,然后缩小文件。 [感谢@onupdatecascade这个]

ps:我很欣赏有人评论这件事的危险,但是在我的环境中,自己做这件事一点都没有问题,特别是因为我总是先做一个完整的备份。 所以请考虑你的环境是什么,以及这是如何影响你的备份策略和工作安全性,然后再继续。 我所做的只是将人们指向微软提供的function!

 USE AdventureWorks2008R2; GO -- Truncate the log by changing the database recovery model to SIMPLE. ALTER DATABASE AdventureWorks2008R2 SET RECOVERY SIMPLE; GO -- Shrink the truncated log file to 1 MB. DBCC SHRINKFILE (AdventureWorks2008R2_Log, 1); GO -- Reset the database recovery model. ALTER DATABASE AdventureWorks2008R2 SET RECOVERY FULL; GO 

来自: http : //msdn.microsoft.com/en-us/library/ms189493.aspx

你可能要先备份

[回答广告比请求更多的细节,但我希望它是有用的]

下面是一个收缩事务日志的脚本,但是我绝对推荐在收缩之前备份事务日志。

如果你只是缩小文件,你将失去大量的数据,可能会在灾难的情况下作为一个现场救星。 事务日志包含许多有用的数据,可以使用第三方事务日志阅读器读取(虽然可以通过手动读取,但是可以用极大的努力)。 事务日志对于时间点恢复来说也是必须的,所以不要把它丢掉,而是要确保事先备份它。

这里有几个post,人们使用存储在事务日志中的数据来完成恢复

如何查看SQL Server 2008中的事务日志

阅读sql server 2008中的日志文件(* .LDF)

 USE DATABASE_NAME; GO ALTER DATABASE DATABASE_NAME SET RECOVERY SIMPLE; GO --first parameter is log file name and second is size in MB DBCC SHRINKFILE (DATABASE_NAME_Log, 1); ALTER DATABASE DATABASE_NAME SET RECOVERY FULL; GO 

执行上面的命令时,您可能会看到如下所示的错误

 “Cannot shrink log file (log file name) because the logical log file located at the end of the file is in use “ 

这意味着TLOG正在使用中。 在这种情况下,尝试连续执行几次或find一种减less数据库活动的方法。

如果您不使用事务日志进行还原(即只进行完整备份),则可以将恢复模式设置为“简单”,并且事务日志将很快缩小并且不会再次填满。

如果您正在使用SQL 7或2000,则可以在数据库选项选项卡中启用“截断login检查点”。 这也有同样的效果。

这显然不是在生产环境中推荐的,因为你将无法恢复到某个时间点。

这是一个简单, 非常不雅潜在危险的方式。

  1. 备份数据库
  2. 分离数据库
  3. 重命名日志文件
  4. 附加数据库
  5. 新的日志文件将被重新创build
  6. 删除重命名的日志文件。

我猜你没有做日志备份。 (这会截断日志)。 我的build议是将恢复模式从完整改为简单 。 这将防止日志膨胀。

Johnbuild议不要使用这种技术,因为不能保证数据库不附带日志文件。 将数据库从完全更改为简单,强制检查点并等待几分钟。 SQL Server将清除日志,然后您可以使用DBCC SHRINKFILE缩小日志。

到目前为止,大多数答案都假设您实际上不需要事务日志文件,但是如果您的数据库正在使用FULL恢复模式,并且希望保留备份以防需要恢复数据库,则不要截断或删除日志文件的方式很多这些答案build议。

消除日志文件(通过截断日志文件,丢弃日志文件,清除日志文件等)将会破坏您的备份链,并且会阻止您恢复到自上次完整,差异备份或事务日志备份以来的任何时间点,直到下一个满或差分备份。

从微软的BACKUP文章

我们build议您不要使用NO_LOG或TRUNCATE_ONLY来手动截断事务日志,因为这会中断日志链。 直到下一个完整或差异数据库备份,数据库不受介质故障的保护。 只在非常特殊的情况下使用手动日志截断,并立即创build数据的备份。

为了避免这种情况,请在收缩之前将日志文件备份到磁盘 。 语法看起来像这样:

 BACKUP LOG MyDatabaseName TO DISK='C:\DatabaseBackups\MyDatabaseName_backup_2013_01_31_095212_8797154.trn' DBCC SHRINKFILE (N'MyDatabaseName_Log', 200) 

SQL Server事务日志需要妥善维护,以防止其不必要的增长。 这意味着经常运行事务日志备份。 如果不这样做,就会使交易日志变得充满并开始增长。

除了在这个线程中提到的答案,我build议阅读和理解交易日志常见的神话。 这些读数可能有助于理解事务日志并决定使用什么技术来“清除”它:

http://www.sqlshack.com/10-important-sql-server-transaction-log-myths/

神话:我的SQL Server太忙了,我不想做SQL Server事务日志备份

SQL Server中性能最强的操作之一是联机事务日志文件的自动增长事件。 通过不经常进行事务日志备份,在线事务日志将变满,并且将不得不增长。 默认增长大小是10%。 数据库越忙,如果事务日志备份未创build,则联机事务日志将越快增长创buildSQL Server事务日志备份不会阻止联机事务日志,但会自动增长事件。 它可以阻止在线事务日志中的所有活动

http://blog.sqlxdetails.com/transaction-log-myths/

神话:规则的日志收缩是一个很好的维护做法

假。 日志增长非常昂贵,因为新块必须清零。 所有的写操作都停止在该数据库上,直到归零完成,而且如果你的磁盘写入速度慢或者自动增长的规模很大,那么这个暂停可能很大,用户会注意到。 这就是为什么你要避免增长的一个原因。 如果你缩小日志,它会再次增长,你只是浪费磁盘操作在不必要的缩小和再次成长的游戏<<

首先检查数据库恢复模式。 默认情况下,SQL Server Epxress版本在简单恢复模型中创build数据库(如果iam没有错的话)。

使用Truncate_Only备份日志数据库名称

DBCC ShrinkFile(yourLogical_LogFileName,50)

SP_helpfile将为您提供逻辑日志文件名称

请参阅:

http://support.microsoft.com/kb/873235

如果您的数据库处于完全恢复模式,并且您没有进行TL备份,则将其更改为SIMPLE。

使用DBCC ShrinkFile({logicalLogName},TRUNCATEONLY)命令。 如果这是一个testing数据库,并且您尝试保存/回收空间,这将有所帮助。 请记住,TX日志确实有一个最小/稳定状态的大小,他们将长大。 根据您的恢复模式,您可能无法缩小日志 – 如果在“完整”中,而您没有发送TX日志备份,日志将无法缩小 – 它将会一直增长。 如果您不需要tx日志备份,请将恢复模式切换为简单。

请记住,永远不会在任何情况下删除日志(LDF)文件! 你几乎会有即时的数据库损坏。 熟! 完成! 丢失数据! 如果留下“不修补”的主要中密度纤维板可能会永久腐败。

永远不要删除事务日志 – 你将失去数据! 部分数据在TX日志中(不pipe恢复模式如何)…如果分离并“重命名”有效删除数据库部分的TX日志文件。

对于那些已经删除TX日志,你可能想运行一些checkdb命令,并修复损坏之前,你失去更多的数据。

在这个话题上看看Paul Randal的博客。 http://sqlskills.com/BLOGS/PAUL/category/Bad-Advice.aspx#p4

另外一般来说,不要在MDF上使用shrinkfile,因为它会严重地破坏数据。 查看他的坏build议部分了解更多信息(“为什么你不应该收缩你的数据文件”)

看看保罗的网站 – 他涵盖了这些问题。 上个月,他在“神话一天”系列中讲述了许多这些问题。

截断日志文件:

  • 备份数据库
  • 通过使用企业pipe理器或执行:分离数据库: Sp_DetachDB [DBName]
  • 删除事务日志文件。 (或者重命名文件,以防万一)
  • 重新附加数据库使用: Sp_AttachDB [DBName]
  • 附加数据库时,会创build一个新的事务日志文件。

收缩日志文件:

  • 使用No_Log备份日志[DBName]
  • 通过以下任一方式收缩数据库:

    使用企业pipe理器: – 右键单击​​数据库,所有任务,收缩数据库,文件,select日志文件,确定。

    使用T-SQL: – Dbcc Shrinkfile([Log_Logical_Name])

您可以通过运行sp_helpdb或通过在Enterprise Manager中查看数据库的属性来find日志文件的逻辑名称。

根据我在大多数SQL Server上的经验,没有事务日志的备份。 完整备份或差异备份是常见操作,但事务日志备份实际上很less。 所以事务日志文件永远增长(直到磁盘已满)。 在这种情况下, 恢复模式应设置为“ 简单 ”。 不要忘记修改系统数据库“model”和“tempdb”。

数据库“tempdb”的备份是没有意义的,所以这个数据库的恢复模式应该总是“简单”。

  1. 取回MDB文件。
  2. 停止sql服务
  3. 重命名日志文件
  4. 开始服务

(系统将创build一个新的日志文件。)

删除或移动重命名的日志文件。

尝试这个:

 USE DatabaseName GO DBCC SHRINKFILE( TransactionLogName, 1) BACKUP LOG DatabaseName WITH TRUNCATE_ONLY DBCC SHRINKFILE( TransactionLogName, 1) GO 

数据库 – >右键单击属性 – >文件 – >添加另一个不同名称的日志文件,并设置不同文件名的旧日志文件的path。 数据库自动拾取新创build的日志文件。

  1. 备份数据库
  2. 分离数据库
  3. 重命名日志文件
  4. 附加数据库(附加删除重命名.ldf(日志文件)。select它,并通过按删除button删除)
  5. 新的日志文件将被重新创build
  6. 删除重命名的日志文件。

这将工作,但build议先备份您的数据库。

例:-

DBCC SQLPERF(LOGSPACE)

备份日志与TRUNCATE_ONLY共同

DBCC SHRINKFILE(Company_log,500)

DBCC SQLPERF(LOGSPACE)

数据库事务日志收缩到最小尺寸

  1. 备份:事务日志
  2. 收缩文件:事务日志
  3. 备份:事务日志
  4. 收缩文件:事务日志

我做了几个数据库的testing: 这个序列的工作

它通常缩小到2MB

OR by a script:

 DECLARE @DB_Name nvarchar(255); DECLARE @DB_LogFileName nvarchar(255); SET @DB_Name = '<Database Name>'; --Input Variable SET @DB_LogFileName = '<LogFileEntryName>'; --Input Variable EXEC ( 'USE ['+@DB_Name+']; '+ 'BACKUP LOG ['+@DB_Name+'] WITH TRUNCATE_ONLY ' + 'DBCC SHRINKFILE( '''+@DB_LogFileName+''', 2) ' + 'BACKUP LOG ['+@DB_Name+'] WITH TRUNCATE_ONLY ' + 'DBCC SHRINKFILE( '''+@DB_LogFileName+''', 2)' ) GO