如何清除SQL Server事务日志?

时间:2008-09-11 14:08:12

标签: sql-server transaction-log

我不是SQL专家,每当我需要做一些超出基础知识的事情时,我就会想起这个事实。我有一个不大的测试数据库,但事务日志肯定是。如何清除事务日志?

22 个答案:

答案 0 :(得分:694)

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

首先,进行完整备份

永远不要对数据库进行任何更改,除非确保在出现问题时可以恢复它。

如果您关心时间点恢复

(通过即时恢复,我的意思是你关心的是能够恢复到完整或差异备份以外的任何东西。)

据推测,您的数据库处于FULL恢复模式。如果没有,请确保它是:

ALTER DATABASE testdb SET RECOVERY FULL;

即使您正在进行定期完整备份,日志文件也会增长并增长,直到您执行日志备份 - 这是为了您的保护,而不是不必要地占用您的磁盘空间。您应该根据恢复目标频繁地执行这些日志备份。例如,如果您有一个业务规则表明您可以承受在发生灾难时丢失不超过15分钟的数据,那么您应该有一个每15分钟备份一次日志的作业。这是一个脚本,它将根据当前时间生成带时间戳的文件名(但您也可以通过维护计划等来执行此操作,只是不要选择维护计划中的任何缩小选项,它们会很糟糕)。

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\应位于代表不同底层存储设备的其他计算机上。将这些备份到同一台计算机(或使用相同底层磁盘的不同计算机,或同一物理主机上的其他VM)并不能真正帮助您,因为如果计算机爆炸,您可以# 39;已丢失数据库其备份。根据您的网络基础设施,在本地备份然后将它们传输到幕后的不同位置可能更有意义;在任何一种情况下,您都希望尽快将它们从主数据库机器上移除。

现在,一旦你运行了常规的日志备份,将日志文件缩小到比它现在爆炸的更合理的东西是合理的。这 not 意味着一遍又一遍地运行SHRINKFILE,直到日志文件为1 MB - 即使您经常备份日志,它仍然需要容纳任何并发事务的总和可能会发生。日志文件自动增长事件是昂贵的,因为SQL Server必须将文件清零(与启用即时文件初始化时的数据文件不同),并且用户事务必须等待发生这种情况。您希望尽可能少地执行这种增长 - 缩减 - 增长 - 缩减程序,并且您当然不希望让您的用户为此付费。

请注意,您可能需要在缩小之前备份日志两次(感谢Robert)。

因此,您需要为日志文件提供实用的大小。这里没有人能够在不了解你的系统的情况下告诉你这是什么,但是如果你经常缩小日志文件并且它已经再次增长,那么一个好的水印可能比最大的水印高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

如果您不关心时间点恢复

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

ALTER DATABASE testdb SET RECOVERY SIMPLE;

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

接下来,您应该绝对确保此日志增长确实是由于异常事件(例如,每年春季清洁或重建您的最大指数),而不是由于正常的日常使用。如果您将日志文件缩小到一个非常小的大小,并且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标记它),否则这绝对会导致许多不必要的增长事件,因为无论恢复模型如何,日志都必须适应当前事务。暂时释放该空间的重点是什么,只是因此SQL Server可以缓慢而痛苦地取回它?

  • 创建第二个日志文件。这将暂时缓解已装满磁盘的驱动器,但这就像尝试使用创可贴修复刺破的肺部一样。您应该直接处理有问题的日志文件,而不是仅仅添加另一个潜在的问题。除了将某些事务日志活动重定向到不同的驱动器之外,第二个日志文件实际上对您没有任何作用(与第二个数据文件不同),因为一次只能使用其中一个文件。 Paul Randal also explains why multiple log files can bite you later

积极主动

不是将日志文件缩小到少量并且让它自己以较小的速率自动进行自动增长,而是将其设置为一个相当大的大小(一个可以容纳最大并发事务集的总和)并设置一个合理的自动增长设置作为后备,因此它不必增长多次以满足单个事务,因此在正常业务操作期间它必须增长相对较少。

这里最糟糕的设置是1 MB增长或10%增长。有趣的是,这些是SQL Server的默认设置(我已经抱怨和asked for changes to no avail) - 数据文件为1 MB,日志文件为10%。前者在这个时代太小了,后者每次都会导致更长更长的事件(例如,你的日志文件是500 MB,第一个增长是50 MB,下一个增长是55 MB,下一个增长是60.5 MB等等 - 在缓慢的I / O上,相信我,你会真正注意到这条曲线。)

进一步阅读

请不要停在这里;虽然你在那里看到的有关缩小日志文件的大部分建议本质上都很糟糕甚至可能是灾难性的,但有些人更关心数据完整性而不是释放磁盘空间。

A blog post I wrote in 2009, when I saw a few "here's how to shrink the log file" posts spring up

A blog post Brent Ozar wrote four years ago, pointing to multiple resources, in response to a SQL Server Magazine article that should not have been published

A blog post by Paul Randal explaining why t-log maintenance is importantwhy you shouldn't shrink your data files, either

Mike Walsh has a great answer covering some of these aspects too, including reasons why you might not be able to shrink your log file immediately

答案 1 :(得分:183)

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

  

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


  • 右键单击数据库名称。

  • 选择任务→收缩→数据库

  • 然后点击确定

我经常打开包含数据库文件的Windows资源管理器目录,这样我就可以立即看到效果。

我真的很惊讶这个工作!通常我之前使用过DBCC,但我只是尝试了它并没有缩小任何东西,所以我尝试了GUI(2005)并且效果很好 - 在10秒内释放17 GB

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

-

PS:我很欣赏一些人对这个危险的评论,但在我的环境中,我自己也没有遇到任何问题,特别是因为我总是首先做一个完整的备份。因此,请在继续之前考虑您的环境,以及这将如何影响您的备份策略和工作安全性。我所做的只是将人们指向微软提供的功能!

答案 2 :(得分:178)

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

发件人: DBCC SHRINKFILE (Transact-SQL)

您可能需要先备份。

答案 3 :(得分:54)

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

如果您只是收缩文件,那么您将丢失大量数据,这些数据可能会在发生灾难时节省生命。事务日志包含许多可以使用第三方事务日志读取器读取的有用数据(可以手动读取,但需要付出极大的努力)。

当涉及到时间点恢复时,事务日志也是必须的,所以不要只是扔掉它,而是确保事先备份它。

以下是一些帖子,其中人们使用存储在事务日志中的数据来完成恢复:

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

执行上面的命令时,您可能会收到类似这样的错误

  

“无法收缩日志文件(日志文件名)因为逻辑错误       位于文件末尾的日志文件正在使用“

这意味着TLOG正在使用中。在这种情况下,请尝试连续多次执行此操作,或者找到减少数据库活动的方法。

答案 4 :(得分:28)

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

如果您使用的是SQL 7或2000,则可以在数据库选项选项卡中启用“截断登录检查点”。这具有相同的效果。

这显然不适用于生产环境,因为您将无法恢复到某个时间点。

答案 5 :(得分:27)

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

  1. 备份数据库
  2. 分离数据库
  3. 重命名日志文件
  4. 附加数据库
  5. 将重新创建新日志文件
  6. 删除重命名的日志文件。
  7. 我猜你没有做日志备份。 (截断日志)。我的建议是将恢复模式从full更改为simple。这样可以防止log膨胀。

答案 6 :(得分:9)

需要正确维护SQL Server事务日志,以防止其不必要的增长。这意味着经常运行事务日志备份。如果不这样做,您就有可能使事务日志变满并开始增长。

除了这个问题的答案,我建议阅读并理解事务日志常见的神话。这些读数可能有助于理解事务日志并决定使用哪种技术来“清除”它:

来自 10 most important SQL Server transaction log myths

  

神话:我的SQL Server太忙了。我不想进行SQL Server事务日志备份

     

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

来自 Transaction log myths

  
    

误区:定期日志缩小是一种很好的维护实践

  
     

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

答案 7 :(得分:9)

到目前为止,大多数答案假设您实际上并不需要事务日志文件,但是如果您的数据库使用FULL恢复模型,并且您希望保留备份以防您需要还原数据库,然后以许多这些答案所暗示的方式截断或删除日志文件。

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

来自Microsoft article onBACKUP

  

我们建议您永远不要手动使用NO_LOG或TRUNCATE_ONLY   截断事务日志,因为这会破坏日志链。直到   下一个完整或差异数据库备份,数据库不是   防止媒体失败。仅使用手动日志截断   特殊情况,并立即创建数据备份。

为避免这种情况,请先将日志文件备份到磁盘,然后再缩小。语法看起来像这样:

BACKUP LOG MyDatabaseName 
TO DISK='C:\DatabaseBackups\MyDatabaseName_backup_2013_01_31_095212_8797154.trn'

DBCC SHRINKFILE (N'MyDatabaseName_Log', 200)

答案 8 :(得分:8)

不建议使用John建议的这种技术,因为无法保证数据库在没有日志文件的情况下附加。将数据库从完全更改为简单,强制检查点并等待几分钟。 SQL Server将清除日志,然后您可以使用DBCC SHRINKFILE缩小日志。

答案 9 :(得分:5)

首先检查数据库恢复模型。默认情况下,SQL Server Express Edition为简单恢复创建数据库 模特(如果我没记错的话)。

使用Truncate_Only备份日志DatabaseName:

DBCC ShrinkFile(yourLogical_LogFileName, 50)

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

参考:

Recover from a full transaction log in a SQL Server database

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

答案 10 :(得分:5)

使用DBCC ShrinkFile ({logicalLogName}, TRUNCATEONLY)命令。如果这是一个测试数据库并且您正在尝试保存/回收空间,这将有所帮助。

请记住,虽然TX日志确实有一种最小/稳定的状态大小,但它们会长大。根据您的恢复模型,您可能无法缩小日志 - 如果在FULL中并且您没有发出TX日志备份,则日志无法缩小 - 它将永远增长。如果您不需要TX日志备份,请将恢复模型切换为简单

请记住,在任何情况下都不会删除日志(LDF)文件!你几乎会有即时数据库损坏。熟!完成!丢失的数据!如果保留“未修复”,则主MDF文件可能会永久损坏。

永远不要删除事务日志 - 您将丢失数据!部分数据位于TX日志中(无论恢复模式如何)...如果您分离并“重命名”有效删除部分数据库的TX日志文件。

对于已删除TX日志的用户,您可能需要运行一些checkdb命令并修复损坏,然后再丢失更多数据。

查看Paul Randal关于这个主题的博文, bad advice

通常也不要在MDF文件上使用shrinkfile,因为它会严重破坏您的数据。查看他的“错误建议”部分以获取更多信息(“为什么不应缩小数据文件”)

查看Paul的网站 - 他介绍了这些问题。上个月,他在每日神话系列中了解了许多这些问题。

答案 11 :(得分:4)

截断日志文件:

  • 备份数据库
  • 使用Enterprise Manager或执行以下命令分离数据库: Sp_DetachDB [DBName]
  • 删除事务日志文件。 (或重命名文件,以防万一)
  • 使用以下命令重新附加数据库: Sp_AttachDB [DBName]
  • 附加数据库后,将创建一个新的事务日志文件。

收缩日志文件:

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

    使用企业管理器: - 右键单击数据库,All tasks,Shrink database,Files,Select log file,OK。

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

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

答案 12 :(得分:4)

  1. 备份MDB文件。
  2. 停止SQL服务
  3. 重命名日志文件
  4. 启动服务
  5. (系统将创建一个新的日志文件。)

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

答案 13 :(得分:4)

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

数据库“tempdb”的备份没有意义,因此这个db的恢复模型应该总是“简单”。

答案 14 :(得分:2)

试试这个:

USE DatabaseName

GO

DBCC SHRINKFILE( TransactionLogName, 1)

BACKUP LOG DatabaseName WITH TRUNCATE_ONLY

DBCC SHRINKFILE( TransactionLogName, 1)

GO 

答案 15 :(得分:2)

数据库→右键单击属性→文件→添加另一个具有不同名称的日志文件,并使用不同的文件名设置与旧日志文件相同的路径。

数据库会自动获取新创建的日志文件。

答案 16 :(得分:1)

  1. 备份数据库
  2. 分离数据库
  3. 重命名日志文件
  4. 附加数据库(同时附加删除重命名的.ldf(日志文件)。选择它并按“删除”按钮删除)
  5. 将重新创建新日志文件
  6. 删除重命名的日志文件。
  7. 这样可行,但建议先备份数据库。

答案 17 :(得分:0)

其他一些答案对我不起作用:在数据库联机时无法创建检查点,因为事务日志已满(具有讽刺意味)。但是,在将数据库设置为紧急模式后,我可以缩小日志文件:

alter database <database_name> set emergency;
use <database_name>;
checkpoint;
checkpoint;
alter database <database_name> set online;
dbcc shrinkfile(<database_name>_log, 200);

答案 18 :(得分:0)

针对MSSQL 2017并使用SQL Server Management Studio的答案略有更新。 我主要是从这些说明https://www.sqlshack.com/sql-server-transaction-log-backup-truncate-and-shrink-operations/

出发

我最近有一个数据库备份,因此我备份了事务日志。然后,我再次对其进行了很好的备份。 最后,我压缩了日志文件,将文件大小从20G增加到7MB,这与我的数据大小相符。 我不认为自从2年前安装以来就没有备份过交易日志。因此,请将此任务放在客房整理日历上。

答案 19 :(得分:0)

我发生了数据库日志文件为28 GB的情况。

你可以做些什么来减少这种情况? 实际上,日志文件是SQL服务器在发生事务时保留的那些文件数据。对于处理SQL服务器的事务,为其分配页面。但是在交易完成之后,这些并没有突然发布,希望可能会有同样的交易。这撑起了空间。

第1步: 首先在探索的数据库查询中运行此命令 检查点

第2步: 右键单击数据库 任务&GT;备份 选择备份类型作为事务日志 添加目标地址和文件名以保留备份数据(.bak)

再次重复此步骤,此时再给出另一个文件名

enter image description here

第3步: 现在转到数据库 右键单击数据库

任务和GT;收缩&GT;档 选择文件类型为日志 收缩动作释放未使用的空间

enter image description here

第4步:

检查您的日志文件 通常在SQL 2014中可以在

找到

C:\ Program Files \ Microsoft SQL Server \ MSSQL12.MSSQL2014EXPRESS \ MSSQL \ DATA

在我的情况下,它从28 GB减少到1 MB

答案 20 :(得分:0)

实施例

DBCC SQLPERF(LOGSPACE)

BACKUP LOG Comapny WITH TRUNCATE_ONLY

DBCC SHRINKFILE (Company_log, 500)

DBCC SQLPERF(LOGSPACE)

答案 21 :(得分:-1)

数据库事务日志缩小到最小值

  1. 备份:交易记录
  2. 收缩文件:交易日志
  3. 备份:交易记录
  4. 收缩文件:交易日志
  5. 我对几个数据库进行了测试:此序列有效

    通常缩小到2MB

    OR脚本:

    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