如何清除 SQL Server 事务日志?
Posted
技术标签:
【中文标题】如何清除 SQL Server 事务日志?【英文标题】:How do you clear the SQL Server transaction log? 【发布时间】:2010-09-08 13:40:11 【问题描述】:我不是 SQL 专家,每次我需要做一些超出基础的事情时,我都会想起这样一个事实。我有一个规模不大的测试数据库,但事务日志肯定是。如何清除事务日志?
【问题讨论】:
How to use the DBCC SHRINKFILE statement to shrink the transaction log file in SQL Server 2005 Managment Studio 里面应该有一个命令:“点击收缩日志”就大功告成了。 【参考方案1】:略微更新的答案,适用于 MSSQL 2017,并使用 SQL 服务器管理工作室。 我主要是按照这些说明进行的https://www.sqlshack.com/sql-server-transaction-log-backup-truncate-and-shrink-operations/
我最近有一个数据库备份,所以我备份了事务日志。然后我再次备份它以备不时之需。 最后我缩小了日志文件,从 20G 到 7MB,更符合我的数据大小。 我认为自从 2 年前安装后,交易日志就没有备份过。所以把这个任务放在家务日历上。
【讨论】:
【参考方案2】:-- DON'T FORGET TO BACKUP THE DB :D (Check [here][1])
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)
您可能需要先备份。
【讨论】:
谢谢,我不认为为此浪费太多时间,你的回答是我最好的:) 这种方法将恢复类型设置为“FULL”,即使恢复类型之前是其他类型 像魔术一样工作!注意日志文件的名字其实就是它的逻辑名(可以在db->properties->files中找到) 我会在这个脚本中包含一个 BACKUP DATABASE 子句,所以没有人会忘记这部分。我这么说是因为几年前我在一个可用空间太少的磁盘中缩小了一个数据库。在收缩过程中,文件越来越大,并引发了空间不足的错误。结果:我丢失了数据库。幸运的是日志数据库失去了容忍度。 @Dragas 答案中有官方文档的链接,您可能需要考虑在官方文档中查看它。顺便说一句,一个好的 DBA 不会在 *** 中查看如何清除日志,很确定他们会知道,但我不是 DBA :)【参考方案3】:确实应该为遇到意外增长而您不希望再次发生的情况保留使日志文件更小的情况。如果日志文件将再次增长到相同的大小,则暂时缩小它并不能完成很多工作。现在,根据您的数据库的恢复目标,这些是您应该采取的行动。
首先,进行完整备份
永远不要对数据库进行任何更改,除非确保在出现问题时可以恢复它。
如果您关心时间点恢复
(通过时间点恢复,我的意思是您关心能够恢复到除完整备份或差异备份之外的任何内容。)
大概您的数据库处于FULL
恢复模式。如果不是,请确保它是:
ALTER DATABASE testdb SET RECOVERY FULL;
即使您定期进行完整备份,日志文件也会不断增长,直到您执行 log 备份 - 这是为了保护您,而不是不必要地占用您的磁盘空间。根据您的恢复目标,您应该非常频繁地执行这些日志备份。例如,如果您的业务规则规定您可以承受在发生灾难时丢失不超过 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)并不能真正帮助您,因为如果机器发生故障,您就会丢失数据库和它的备份。根据您的网络基础设施,在本地备份然后将它们转移到幕后的不同位置可能更有意义;在任何一种情况下,您都希望尽快将它们从主数据库机器上移除。
现在,一旦您运行了常规日志备份,将日志文件缩小到比现在被炸毁的任何东西更合理的东西应该是合理的。这确实不意味着一遍又一遍地运行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
recovery 一样,直到您备份日志)。 CHECKPOINT
事件将有助于控制日志并确保它不需要增长,除非您在 CHECKPOINT
s 之间生成大量 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 SHRINKFILE
或ALTER 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 important 和 why 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.
【讨论】:
时间点恢复并不是使用完全恢复模式的唯一原因。主要原因是防止数据丢失。数据丢失的可能性是备份之间的长度。如果您只进行每日备份,则数据丢失的可能性是 24 小时。如果随后每半小时添加一次日志备份,则数据丢失的可能性将变为 30 分钟。此外,执行任何类型的零碎恢复(例如从损坏中恢复)都需要日志备份。 除此之外,这是本页给出的最完整、最正确的答案。 我还想补充一点,清除日志是通过备份日志(完整或批量记录恢复)或检查点(简单恢复)来完成的。但是,如果您处于必须缩小日志文件的情况,这还不够。您需要使当前活动的 VLF 循环回到日志文件的开头。您可以在 SQL 2008 和更新版本中通过连续发布两个日志备份或检查点来强制执行此操作。第一个清除它,第二个循环它回到文件的开头。 @Doug_Ivison 因为在任何时候,日志记录都可能被清除。允许您备份不完整的日志有什么意义?在简单恢复中,日志仅真正用于允许事务回滚。一旦事务被提交或回滚,下一秒它就可能从日志中消失。 @zinczinc 好的,谢谢您的反馈。我看到的问题是先给出答案,然后再解释,他们永远不会阅读重要的部分。我淹没读者的演讲实际上比最后的答案重要得多,恕我直言,我提供的背景对于做出这些选择非常重要。但是,嘿,如果您想提交一个单行答案,因为您认为这对 OP 更好,请随时使用我的那部分答案来制作一个更好的答案,我们都可以从中学习。【参考方案4】:其他一些答案对我不起作用:数据库在线时无法创建检查点,因为事务日志已满(多么讽刺)。但是,将数据库设置为紧急模式后,我能够缩小日志文件:
alter database <database_name> set emergency;
use <database_name>;
checkpoint;
checkpoint;
alter database <database_name> set online;
dbcc shrinkfile(<database_name>_log, 200);
【讨论】:
【参考方案5】:它发生在我的数据库日志文件为 28 GB 的情况下。
你能做些什么来减少这种情况? 实际上,日志文件是 SQL 服务器在事务发生时保留的那些文件数据。对于要处理的事务,SQL 服务器会为其分配页面。但是交易完成后,这些都不是突然放出来的,希望有可能有同样的交易来。这占据了空间。
第 1 步: 首先在探索的数据库查询中运行此命令 检查点
第 2 步: 右键单击数据库 任务>备份 选择备份类型作为事务日志 添加目标地址和文件名以保留备份数据(.bak)
再次重复此步骤,此时给另一个文件名
第 3 步: 现在去数据库 右键单击数据库
任务>收缩>文件 选择文件类型作为日志 释放未使用空间时的收缩动作
第 4 步:
检查您的日志文件 通常在 SQL 2014 中,可以在
找到C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014EXPRESS\MSSQL\DATA
在我的例子中,它从 28 GB 减少到 1 MB
【讨论】:
【参考方案6】:需要正确维护 SQL Server 事务日志,以防止其不必要的增长。这意味着足够频繁地运行事务日志备份。如果不这样做,您将面临事务日志已满并开始增长的风险。
除了这个问题的答案,我建议阅读和理解事务日志常见的神话。这些读数可能有助于理解事务日志并决定使用什么技术来“清除”它:
来自10 most important SQL Server transaction log myths:
误区:我的 SQL Server 太忙了。我不想制作 SQL Server 事务日志备份
SQL Server 中最大的性能密集型操作之一是联机事务日志文件的自动增长事件。由于不经常进行事务日志备份,在线事务日志将变满并且必须增长。默认增长大小为 10%。数据库越忙,如果不创建事务日志备份,在线事务日志增长得越快 创建 SQL Server 事务日志备份不会阻止联机事务日志,但自动增长事件会。它可以阻止在线事务日志中的所有活动
来自Transaction log myths:
误区:定期收缩日志是一种很好的维护习惯
错误。日志增长非常昂贵,因为新块必须清零。该数据库上的所有写入活动都会停止,直到归零完成,如果您的磁盘写入速度很慢或自动增长大小很大,则该暂停可能会很大并且用户会注意到。这就是你想要避免增长的原因之一。如果你收缩日志,它会再次增长,你只是在不必要的收缩和增长游戏中浪费磁盘操作
【讨论】:
【参考方案7】:数据库→右键属性→文件→添加另一个不同名称的日志文件,并将路径设置为与旧日志文件相同的文件名。
数据库自动拾取新创建的日志文件。
【讨论】:
【参考方案8】:以下是收缩事务日志的脚本,但我绝对建议在收缩之前备份事务日志。
如果您只是缩小文件,您将丢失大量数据,这些数据可能会在发生灾难时成为救命稻草。事务日志包含许多有用的数据,可以使用第三方事务日志阅读器读取(可以手动读取,但需要付出极大的努力)。
事务日志在时间点恢复时也是必须的,所以不要随便扔掉,而是要确保事先备份。
这里有几篇文章,人们使用存储在事务日志中的数据来完成恢复:
How to view transaction logs in SQL Server 2008
Read the log file (*.LDF) in SQL Server 2008
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 正在使用中。在这种情况下,请尝试连续多次执行此操作或找到减少数据库活动的方法。
【讨论】:
【参考方案9】:-
备份 MDB 文件。
停止 SQL 服务
重命名日志文件
启动服务
(系统会创建一个新的日志文件。)
删除或移动重命名的日志文件。
【讨论】:
【参考方案10】:使用DBCC ShrinkFile (logicalLogName, TRUNCATEONLY)
命令。如果这是一个测试数据库并且您正在尝试节省/回收空间,这将有所帮助。
请记住,虽然 TX 日志确实有一种最小/稳定状态大小,但它们会长大。根据您的恢复模式,您可能无法缩小日志 - 如果在 FULL 并且您没有发出 TX 日志备份,则无法缩小日志 - 它将永远增长。如果您不需要 TX 日志备份,请将您的恢复模式切换为简单。
请记住,在任何情况下都不要删除日志 (LDF) 文件!您几乎会立即发生数据库损坏。煮熟!完毕!丢失数据!如果“未修复”,主 MDF 文件可能会永久损坏。
永远不要删除事务日志——你会丢失数据!您的部分数据位于 TX 日志中(无论恢复模式如何)...如果您分离并“重命名”有效地删除部分数据库的 TX 日志文件。
对于那些已删除 TX 日志的用户,您可能需要运行一些 checkdb 命令并在丢失更多数据之前修复损坏。
查看 Paul Randal 关于这个主题的博文,bad advice。
通常不要在 MDF 文件上使用压缩文件,因为它会严重分割您的数据。查看他的“坏建议”部分了解更多信息(“为什么不应该缩小数据文件”)
查看 Paul 的网站 - 他涵盖了这些问题。上个月,他在他的Myth A Day 系列中讨论了许多此类问题。
【讨论】:
+1 作为第一个提到这可能不是一个好主意的答案! OP 指定了一个测试数据库,但对于更一般的情况来说,这一点非常值得。 我应该添加 - 如果你删除 TX 日志 - 更新简历!【参考方案11】:首先检查数据库恢复模式。默认情况下,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。
【讨论】:
这是我清除开发箱日志文件的方式。带有所有相关备份策略的生产环境等我留给 DBA :-)TRUNCATE_ONLY
在当前版本的 SQL Server 中不再是一个选项,并且不建议在支持它的版本上使用它(请参阅Rachel's answer)。【参考方案12】:
免责声明:请仔细阅读下面的 cmets,我假设您已经阅读了接受的答案。正如我将近 5 年前所说:
如果有人有任何 cmets 可以添加到这不是 足够或最佳的解决方案,然后请在下面发表评论
右键单击数据库名称。
选择任务 → 收缩 → 数据库
然后点击确定!
我通常打开包含数据库文件的Windows资源管理器目录,所以我可以立即看到效果。
我真的很惊讶这能奏效!通常我以前用过 DBCC,但我只是尝试过,它并没有缩小任何东西,所以我尝试了 GUI (2005),效果很好——在 10 秒内释放了 17 GB
在完全恢复模式下,这可能不起作用,因此您必须先备份日志,或者更改为简单恢复,然后缩小文件。 [感谢@onupdatecascade]
--
PS:我很欣赏一些人对此危险的评论,但在我的环境中,我自己没有任何问题,特别是因为我总是先进行完整备份。因此,在继续之前,请考虑您的环境是什么,以及这如何影响您的备份策略和工作安全性。我所做的只是向人们指出 Microsoft 提供的一项功能!
【讨论】:
在完全恢复模式下这可能不起作用,因此您必须先备份日志,或者更改为简单恢复,然后缩小文件。 @onupdatecascade - 很好地呼吁完全恢复技巧。有另一个带有大量日志的数据库:切换到简单,然后缩小数据库并切换回完整。日志文件减少到 500kb! 对不起。但这个答案简直不能再错了。通过收缩数据库,您将增加事务日志文件。每当您在 SQL Server 数据库中移动数据时,都需要记录日志——使日志文件膨胀。要减小日志大小,请将数据库设置为简单恢复,或者(如果您关心/需要记录的数据——而且您几乎总是在生产中这样做)备份日志。这些简单的免费视频中的更多详细信息:sqlservervideos.com/video/logging-essentialssqlservervideos.com/video/sql2528-log-files 哇,这个答案获得了 1300+ 代表的荣誉,但这确实是一个糟糕的建议。 这里夸张地展示了正在发生的事情以及为什么定期收缩绝对至关重要:记录 A 在备份完成之前更改了 100 万次。日志中有什么? 999,999 条不相关的数据。如果日志永远不会缩小,您将永远不会知道数据库的真正运营费用是多少。此外,您很可能会在 SAN 上占用宝贵的资源。收缩是很好的维护,让您与环境保持联系。告诉我一个认为你永远不应该退缩的人,我会告诉你一个无视他们环境的人。【参考方案13】:试试这个:
USE DatabaseName
GO
DBCC SHRINKFILE( TransactionLogName, 1)
BACKUP LOG DatabaseName WITH TRUNCATE_ONLY
DBCC SHRINKFILE( TransactionLogName, 1)
GO
【讨论】:
TRUNCATE_ONLY
在当前版本的 SQL Server 中不再是一个选项,并且不建议在支持它的版本上使用它(请参阅Rachel's answer)。
它适用于我使用 MSSQL Server 2005 标准版【参考方案14】:
到目前为止,这里的大多数答案都是假设您实际上并不需要事务日志文件,但是如果您的数据库使用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)
【讨论】:
我同意你的回答,除了, 1)
部分。问题是,如果将其缩小到 1 MB,导致 正常 日志大小的增长事件将非常昂贵,如果增长将有 许多率保留为默认值 10%。【参考方案15】:
这是一个简单且非常不雅 & 潜在危险的方法。
-
备份数据库
分离数据库
重命名日志文件
附加数据库
将重新创建新的日志文件
删除重命名的日志文件。
我猜你没有做日志备份。 (这会截断日志)。我的建议是将恢复模式从 full 更改为 simple。这将防止日志膨胀。
【讨论】:
恕我直言,删除/重命名/重新创建/替换日志是一个非常糟糕的主意。收缩的风险一定要小一些,而且做起来也很简单。 +1 - 不管是否不优雅,这种方法让我几次摆脱困境,数据库日志填满了整个磁盘,以至于即使是收缩命令也无法运行。 日志中是否存在未检查点事务的风险? 这对于较小的数据库也可能没问题,但如果您有 3 或 4 TB 的数据库,它可能不是最佳解决方案。 如果您已经开发了很长时间的系统并在开发期间加载/删除了数千条记录,这似乎没问题。那么当你想使用这个数据库部署到live时,已经记录的测试/开发数据是多余的,因此丢失也无所谓,不是吗?【参考方案16】:-
备份数据库
分离数据库
重命名日志文件
附加数据库(附加删除重命名的.ldf(日志文件)时。选择它并按删除按钮删除)
将重新创建新的日志文件
删除重命名的日志文件。
这可行,但建议先备份您的数据库。
【讨论】:
【参考方案17】:数据库事务日志缩小到最小尺寸:
-
备份:事务日志
收缩文件:事务日志
备份:事务日志
收缩文件:事务日志
我对几个数据库进行了测试:这个序列有效。
它通常缩小到 2MB。
或通过脚本:
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
【讨论】:
TRUNCATE_ONLY
在当前版本的 SQL Server 中不再是一个选项,并且不建议在支持它的版本上使用它(请参阅Rachel's answer)。【参考方案18】:
不推荐使用 John 推荐的这种技术,因为无法保证数据库在没有日志文件的情况下会附加。将数据库从完整更改为简单,强制检查点并等待几分钟。 SQL Server 将清除日志,然后您可以使用 DBCC SHRINKFILE 缩小日志。
【讨论】:
...但我已经做了几十次没有问题。也许您可以解释为什么数据库可能无法重新连接。 我偶尔(不经常)看到当日志文件被删除时 SQL Server 无法将数据库附加回数据库。这会给您留下一个无用的 MDF 文件。有几种可能会导致该问题。想到等待回滚的事务。 我同意这种策略,但它应该保留在日志由于某些不可预见和/或异常事件而炸毁的情况下。如果你每周都安排一个工作来做这件事,那你就大错特错了。 是的,这只是发生在我们身上。我们想放弃 20G 的日志文件,因为我们在移动数据库之前刚刚备份了数据。如果没有庞大的日志文件,MSSQL 绝不会允许我们重新附加新数据库。【参考方案19】:根据我在大多数 SQL Server 上的经验,没有事务日志备份。 完全备份或差异备份是常见的做法,但事务日志备份确实很少见。 因此事务日志文件永远增长(直到磁盘已满)。 在这种情况下,恢复模型应设置为“simple”。 不要忘记修改系统数据库“model”和“tempdb”。
数据库“tempdb”的备份没有意义,因此该数据库的恢复模式应该始终是“简单”的。
【讨论】:
仅将数据库设置为简单不会缩小日志文件,无论它当前处于何种状态。它只是有助于防止它进一步增长(但它仍然可以)。【参考方案20】:如果您不使用事务日志进行恢复(即您只进行完整备份),您可以将恢复模式设置为“简单”,事务日志将很快缩小并且永远不会再次填满。
如果您使用的是 SQL 7 或 2000,您可以在数据库选项选项卡中启用“truncate log on checkpoint”。这具有相同的效果。
显然不建议在生产环境中这样做,因为您将无法恢复到某个时间点。
【讨论】:
将恢复模式设置为简单不会自行神奇地缩小事务日志。 @Aaron 不是靠它自己,不。我假设 OP 将使用他们的测试数据库,因此“事务日志将很快缩小”,但你是正确的,因为它更多的是副作用:简单的恢复模式可能会让你最终缩小交易日志很快 “Simple
...永远不会再填满”——不正确。我已经看到它发生在恢复模型设置为“简单”的数据库上(过去 48 小时内)。日志文件的文件增长设置为“受限”,我们一直在对其进行一些巨大的活动......我知道这是一种不寻常的情况。 (在我们的情况下,我们有足够的磁盘空间,我们增加了日志文件大小,并将日志文件文件增长设置为“无限制”......顺便说一下--interface bug--在更改后显示为“受限" 最大大小为 2,097,152 MB。)
@Doug_Ivison 是的,事务日志中会包含打开的事务,但是一旦发生检查点,它们将在简单模式下被删除。这个答案只是为了快速“我的开发/测试框有一个很大的事务日志,我希望它消失,所以我不需要经常担心它”,而不是打算投入生产环境。重申:不要在生产环境中这样做。
没错,我知道这是一种仅用于开发的快速方法。为什么我评论:直到它发生在我身上,我实际上认为简单的恢复模型永远不会填满......我认为我花了更长的时间来弄清楚/解决,而我开始明白异常大的交易可以做到这一点。 【参考方案21】:
截断日志文件:
备份数据库 使用企业管理器或执行以下命令分离数据库:Sp_DetachDB [DBName] 删除事务日志文件。 (或重命名文件,以防万一) 使用以下命令再次重新附加数据库:Sp_AttachDB [DBName] 附加数据库后,会创建一个新的事务日志文件。缩小日志文件:
使用 No_Log 备份日志 [DBName]通过以下任一方式收缩数据库:
使用企业管理器:- 右键数据库,所有任务,收缩数据库,文件,选择日志文件,确定。
使用 T-SQL :- Dbcc Shrinkfile ([Log_Logical_Name])
您可以通过运行 sp_helpdb 或在企业管理器中查看数据库的属性来找到日志文件的逻辑名称。
【讨论】:
永远不要删除事务日志。您的部分数据在日志中。删除它,数据库将损坏。我没有代表可以投反对票。 对我来说 DBCC SHRINKFILE 不会减少日志文件 ldf(恢复很简单)。对我来说 log_reuse_wait_desc 不返回任何数据。 DBCC SQLPerf(logspace) 返回 99,99% 已用日志空间 DBCC LOGINFO 返回 11059 行,所有状态 = 2。以上是关于如何清除 SQL Server 事务日志?的主要内容,如果未能解决你的问题,请参考以下文章
sql server 2000中,如何查询事务日志?事务日志有啥作用?