如何清除SQL Server事务日志?

我不是SQL专家,每当我需要做一些基本之外的事情时,我就会想起这个事实。我有一个测试数据库,它的大小不是很大,但是事务日志确实很大。如何清除事务日志?

1417727 次浏览

这里有一个简单的和很不雅的 &# EYZ1方式。

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

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

截断日志文件。

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

使用实例收缩日志文件。

  • 使用No_Log备份日志[DBName]
  • 收缩数据库:

    使用企业管理器:- 右键单击数据库,所有任务,收缩数据库,文件,选择日志文件,确定

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

    . Dbcc收缩文件([Log_Logical_Name]

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

如果不使用事务日志进行恢复(即只进行完全备份),可以将恢复模式设置为“简单”,那么事务日志很快就会缩小,再也不会被填满。

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

显然,在生产环境中不建议这样做,因为您将无法恢复到某个时间点。

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

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

免责声明:请仔细阅读下面的评论,我假设你已经阅读了公认的答案。就像我5年前说的:

如果有人有任何评论要添加的情况下,这不是一个 充分的或最优的解决方案,然后请在

下面评论

  • 右键单击数据库名称。

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

  • 然后点击OK!

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

我真的很惊讶这竟然能起作用!通常我以前使用DBCC,但我刚刚尝试了一下,它没有收缩任何东西,所以我尝试了GUI(2005),它工作得很好——在10秒内释放了17 GB

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

--

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

不推荐John推荐的这种技术,因为没有日志文件就不能保证数据库会附加。将数据库从full更改为simple,强制设置检查点并等待几分钟。SQL Server将清除日志,然后使用DBCC SHRINKFILE收缩日志。

首先检查数据库恢复模式。默认情况下,SQL Server Express Edition会为简单恢复创建一个数据库

. model(如果我没记错的话)

备份日志DatabaseName With Truncate_Only

DBCC ShrinkFile(yourLogical_LogFileName, 50)

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

请参考:

从SQL Server数据库的完整事务日志中恢复

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

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

记住,TX日志确实有一个最小/稳定状态大小,它们将逐渐增长。根据您的恢复模型,您可能无法收缩日志-如果是FULL且您没有发布TX日志备份,则日志不能收缩-它将永远增长。如果不需要TX日志备份,请将恢复模型切换到简单的

记住,在任何情况下都不要删除日志(LDF)文件!您几乎会立即破坏数据库。煮熟的!完成了!数据丢失!如果“未修复”,主MDF文件可能会永久损坏。

永远不要删除事务日志-你会丢失数据!你的部分数据在TX日志中(不管哪种恢复模式)…如果您分离并“重命名”TX日志文件,该文件实际上是数据库的删除部分。

对于那些已经删除了TX日志的用户,您可能希望在丢失更多数据之前运行一些checkdb命令并修复损坏。

看看Paul Randal关于这个话题的博客文章,坏建议

此外,一般不要在MDF文件上使用收缩文件,因为它会严重破坏你的数据。查看他的坏建议部分以获得更多信息(“为什么你不应该缩小你的数据文件”)

看看保罗的网站,他讨论了这些问题。上个月,他在一天的神话系列文章中讨论了许多这些问题。

  1. 备份数据库
  2. 分离数据库
  3. 重命名日志文件
  4. 附加DB(同时附加删除重命名的.ldf(日志文件)。选择它并按下删除按钮)
  5. 将重新创建新的日志文件
  6. 删除重命名日志文件。

这可以工作,但建议先备份数据库。

试试这个:

USE DatabaseName


GO


DBCC SHRINKFILE( TransactionLogName, 1)


BACKUP LOG DatabaseName WITH TRUNCATE_ONLY


DBCC SHRINKFILE( TransactionLogName, 1)


GO

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

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

我在几个db上做了测试:这个序列是可行的

通常是缩小到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
  1. 对MDB文件进行备份。
  2. 停止SQL服务
  3. 重命名日志文件
  4. 启动服务

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

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

-- 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

来自:# EYZ0

您可能需要先备份。

到目前为止,这里的大多数回答都假设您实际上并不需要事务日志文件,但是,如果您的数据库使用FULL恢复模型,并且您希望保留备份,以便在需要恢复数据库时使用,那么将截断或删除日志文件,这是许多回答所建议的方法。

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

来自微软的文章BACKUP

我们建议您不要手动使用NO_LOG或TRUNCATE_ONLY 截断事务日志,因为这会中断日志链。直到 下一次全量或差异数据库备份时,数据库不备份 防止媒体故障。仅在very中使用手动日志截断

.在特殊情况下,立即创建数据备份

为了避免这种情况,请在收缩日志文件到磁盘之前备份它。语法应该是这样的:

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


DBCC SHRINKFILE (N'MyDatabaseName_Log', 200)

下面是收缩事务日志的脚本,但是我强烈建议在收缩之前备份事务日志。

如果你只是缩小文件,你将失去大量的数据,这些数据在灾难发生时可能会成为救星。事务日志包含大量有用的数据,可以使用第三方事务日志读取器读取(可以手动读取,但需要付出很大的努力)。

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

以下是人们使用存储在事务日志中的数据来完成恢复的几篇文章:

,

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

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

"不能收缩日志文件(日志文件名),因为逻辑

. Log

. Log

. Log

. Log

. Log

这意味着正在使用TLOG。在这种情况下,尝试在一行中多次执行该命令,或者找到减少数据库活动的方法。

减小日志文件的大小应该用于遇到您不希望再次发生的意外增长的情况。如果日志文件将再次增长到相同的大小,那么通过临时缩小它并不能完成太多工作。现在,根据数据库的恢复目标,您应该采取以下操作。

首先,进行完全备份

如果没有确保在出现问题时可以恢复数据库,就不要对数据库进行任何更改。

如果你关心时间点的恢复

(所谓的时间点恢复,我的意思是您关心是否能够恢复到完全备份或差异备份之外的任何内容。)

假设您的数据库处于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)并不能真正帮助您,因为如果机器崩溃,您就会丢失数据库而且及其备份。根据您的网络基础设施,在本地备份,然后将它们转移到幕后的不同位置可能更有意义;在这两种情况下,您都希望尽快将它们从主数据库机器上删除。

现在,一旦运行了定期的日志备份,就应该合理地将日志文件缩小到比现在的大小更合理的程度。这并不意味着意味着反复运行SHRINKFILE,直到日志文件为1 MB—即使您频繁备份日志,它仍然需要容纳可能发生的任何并发事务的总和。日志文件自动增长事件是昂贵的,因为SQL Server必须将文件归零(不像启用即时文件初始化时的数据文件),并且在此过程中用户事务必须等待。您希望尽可能少地执行这种增长-收缩-增长-收缩的例行程序,当然也不想让用户为此付费。

请注意,你可能需要备份两次日志才有可能去看心理医生(谢谢罗伯特)。

因此,您需要为您的日志文件提出一个实用的大小。如果不了解您的系统,这里没有人能告诉您这是什么,但是如果您经常缩小日志文件,并且它再次增长,那么一个好的水印可能比它的最大值高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(上面的例子)单独调整它。

  • 将日志文件压缩为1mb . txt。这看起来很诱人,因为SQL Server会让我在某些场景中这样做,看看它释放的所有空间!除非您的数据库是只读的(确实是,您应该使用ALTER DATABASE将其标记为只读),否则这绝对会导致许多不必要的增长事件,因为无论恢复模型如何,日志都必须容纳当前事务。为什么要暂时释放这些空间,让SQL Server可以缓慢而痛苦地收回这些空间呢?

  • 创建第二个日志文件。这将暂时缓解磁盘中的驱动器,但这就像试图用创可贴修补穿孔的肺。您应该直接处理有问题的日志文件,而不是添加另一个潜在的问题。除了将一些事务日志活动重定向到另一个驱动器之外,第二个日志文件实际上对您没有任何帮助(与第二个数据文件不同),因为一次只能使用其中一个文件。Paul Randal还解释了为什么多个日志文件稍后会咬你

要积极主动

一些少量而不是缩小你的日志文件,让它不断自动增长速度小,设置一些合理的大尺寸(最大可以容纳的总和你组并发事务),设定一个合理的自动增长设置回退,所以它不需要多次增长来满足单交易,所以,这将是相对罕见的曾经生长在正常业务操作。

这里最糟糕的设置是1mb的增长或10%的增长。有趣的是,这些是SQL Server的默认值(我抱怨过要求改变,但无济于事) -数据文件为1mb,日志文件为10%。前者在当今时代太小了,而后者每次都会导致越来越长的事件(例如,您的日志文件是500 MB,第一次增长是50 MB,下一次增长是55 MB,下一次增长是60.5 MB,等等——在慢I/O时,相信我,您真的会注意到这条曲线)。

进一步的阅读

请不要停在这里;虽然您所看到的许多关于缩减日志文件的建议本质上都是不好的,甚至可能是灾难性的,但有些人更关心数据完整性,而不是释放磁盘空间。

# EYZ0。

# EYZ0。

Paul Randal的一篇博文解释了为什么t-log维护很重要为什么你不应该缩小你的数据文件

# EYZ0。

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

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

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

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

从# EYZ0:

流言:我的SQL服务器太忙了。我不想做SQL Server事务日志备份

SQL Server中最大的性能密集型操作之一是在线事务日志文件的自动增长事件。由于没有足够频繁地进行事务日志备份,在线事务日志将变得满,并且必须增加。默认增长规模为10%。如果不创建事务日志备份,则数据库越繁忙,在线事务日志的增长速度就越快 创建SQL Server事务日志备份不会阻塞在线事务日志,但自动增长事件会。它可以阻止在线事务日志

中的所有活动

从# EYZ0:

神话:定期收缩日志是一种很好的维护实践

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

它发生在我身上,数据库日志文件是28 gb。

你能做些什么来减少这种情况? 实际上,日志文件是SQL服务器在事务发生时保存的文件数据。对于要处理的事务,SQL服务器为其分配页面。但在交易完成后,它们不会突然被释放,希望可能会有类似的交易到来。这撑起了空间。< / p > < p >步骤1: 首先在已探索的数据库查询中运行此命令 检查点< / p > < p >步骤2: 右键单击数据库 任务>备份 选择备份类型为事务日志 增加备份数据(.bak)

的目的地址和文件名

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

enter image description here

< p >步骤3: 现在转到数据库 右键单击数据库

Tasks>收缩>文件 “文件类型”选择“日志” 收缩动作释放未使用空间

enter image description here

步骤4:

检查日志文件 通常在SQL 2014中,这个可以在

找到

C:\Program Files\Microsoft SQL Server\MSSQL12。MSSQL2014EXPRESS \该\数据

在我的例子中,它从28 GB减少到1 MB

其他一些答案对我来说不适用:当db在线时不可能创建检查点,因为事务日志已满(多么讽刺)。但是,在将数据库设置为紧急模式后,我能够收缩日志文件:

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

稍微更新的答案,对于MSSQL 2017,并使用SQL服务器管理工作室。 我主要是从这些指令https://www.sqlshack.com/sql-server-transaction-log-backup-truncate-and-shrink-operations/

我有一个最近的数据库备份,所以我备份了事务日志。然后我又备份了一次。 最后,我缩小了日志文件,从20G减小到7MB,这更符合我的数据大小。 自从2年前安装这个系统以来,我认为交易日志从来没有备份过。