我不是SQL专家,每次我需要做一些超出基础知识的事情时,都会想起这个事实。我有一个规模不大的测试数据库,但是事务日志肯定是这样。如何清除交易日志?
我不是SQL专家,每次我需要做一些超出基础知识的事情时,都会想起这个事实。我有一个规模不大的测试数据库,但是事务日志肯定是这样。如何清除交易日志?
Answers:
对于遇到意外增长(您不希望再次发生这种情况)的情况,应该真正减小日志文件的大小。如果日志文件将再次增长到相同的大小,则暂时缩小将不会有太多效果。现在,根据数据库的恢复目标,这些是您应该执行的操作。
如果发生问题,请务必对数据库进行任何更改,否则请确保无法还原数据库。
(通过时间点恢复,我的意思是您关心的是能够还原到除完整备份或差异备份以外的任何内容。)
大概您的数据库处于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必须将文件归零(与启用即时文件初始化后的数据文件不同),并且用户事务必须等待这种情况发生。您希望尽可能少地执行此增长-收缩-增长-收缩例程,并且您当然不想让您的用户为此付费。
请注意,您可能需要先备份两次日志,然后才能进行收缩(感谢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
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
option 备份日志,然后选择SHRINKFILE
。其中一个TRUNCATE_ONLY
选项已被弃用,并且在当前版本的SQL Server中不再可用。其次,如果您处于FULL
恢复模式,这将破坏您的日志链,并需要新的完整备份。
分离数据库,删除日志文件,然后重新附加。我不能强调这有多危险。您的数据库可能不会备份,它可能会被怀疑备份,您可能必须还原到备份(如果有),等等。
使用“缩小数据库”选项。DBCC SHRINKDATABASE
使用维护计划选项执行相同操作是个坏主意,尤其是在您只需要解决日志问题的情况下。定位您要调整的文件,并使用DBCC SHRINKFILE
或ALTER DATABASE ... MODIFY FILE
(上述示例)分别进行调整。
将日志文件缩小到1 MB。这看起来很诱人,因为,在某些情况下,SQL Server将允许我执行此操作,并查看它释放的所有空间!除非您的数据库是只读的(并且应该使用标记ALTER DATABASE
),否则这绝对会导致许多不必要的增长事件,因为无论恢复模式如何,日志都必须容纳当前事务。暂时释放该空间,以便SQL Server可以缓慢而痛苦地收回它,这有什么意义?
创建第二个日志文件。这将暂时缓解已满磁盘的驱动器,但这就像试图用创可贴修复被刺破的肺部一样。您应该直接处理有问题的日志文件,而不是仅添加另一个潜在的问题。除了将某些事务日志活动重定向到其他驱动器之外,第二个日志文件确实对您没有任何作用(与第二个数据文件不同),因为一次只能使用其中一个文件。保罗·兰德尔(Paul Randal)也解释了为什么以后会有多个日志文件咬你。
与其将您的日志文件缩小到少量并让它自己不断以很小的速度自动增长,不如将它设置为一个相当大的大小(一个可以容纳您最大并发事务集的总和)并设置一个合理的自动增长设置为后备,这样它就不必多次增长就可以满足单个事务,因此在正常业务运营期间必须增长的情况相对很少。
这里最糟糕的设置是1 MB增长或10%增长。有趣的是,这些是SQL Server的默认值(我抱怨过,要求更改无用)-数据文件1 MB,日志文件10%。前者在当今时代太小了,后者每次导致的事件越来越长(例如,您的日志文件为500 MB,第一个增长为50 MB,下一个增长为55 MB,下一个增长为60.5 MB等等。-在慢I / O上,相信我,您会真正注意到此曲线)。
请不要在这里停下来;尽管您看到的有关缩小日志文件的许多建议本质上都是不好的,甚至可能造成灾难性的影响,但有些人更关心数据的完整性而不是释放磁盘空间。
我在2009年撰写的博客文章中,出现了几篇“缩小日志文件的方法”的文章。
博客文章布伦特奥扎尔写了四年前,指向多方资源,响应应该在SQL Server杂志的文章没有被公布。
-- 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)
您可能要先备份。
免责声明:请仔细阅读下面的评论,我认为您已经阅读了接受的答案。正如我近5年前所说:
如果有人对这种方法不是足够或最佳的解决方案有任何意见要补充,请在下面发表评论
右键单击数据库名称。
选择任务→收缩→数据库
然后点击OK!
我通常打开包含数据库文件的Windows资源管理器目录,因此可以立即看到效果。
实际上,我对此感到很惊讶!通常,我以前使用过DBCC,但是我只是尝试了一下,并且它没有缩小任何内容,所以我尝试了GUI(2005),它的效果很好-在10秒内释放了17 GB
在完全恢复模式下,这可能无法正常工作,因此您必须先备份日志,或者更改为简单恢复,然后收缩文件。[为此感谢@onupdatecascade]
-
PS:我很高兴有人对这种做法的危害发表了评论,但是在我的环境中,我自己这样做没有任何问题,尤其是因为我总是首先进行完整备份。因此,在继续之前,请考虑您的环境是什么,以及这如何影响您的备份策略和作业安全性。我所做的只是向人们指出Microsoft提供的功能!
以下是用于缩小事务日志的脚本,但是我绝对建议您在缩小日志之前备份事务日志。
如果仅压缩文件,则将丢失大量数据,这些数据可能在发生灾难时起到救生作用。事务日志包含许多有用的数据,这些数据可以使用第三方事务日志读取器读取(可以手动读取,但需要付出很大的努力)。
对于时间点恢复,事务日志也是必须的,因此不要只是丢掉它,而要确保事先备份它。
这是人们使用事务日志中存储的数据来完成恢复的一些帖子:
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。在这种情况下,请尝试连续执行几次,或者找到减少数据库活动的方法。
这是一种简单且非常微妙且潜在危险的 方式。
如果您不使用事务日志进行还原(即,您只做过完整备份),则可以将恢复模式设置为“简单”,事务日志将很快收缩并且永远不会再次填充。
如果使用的是SQL 7或2000,则可以在数据库选项选项卡中启用“在检查点上截断日志”。这具有相同的效果。
显然,在生产环境中不建议这样做,因为您将无法还原到某个时间点。
Simple
……再也不会填满”-不是真的。我已经看到(过去48小时内)在恢复模型设置为“ SIMPLE”的数据库上发生的情况。日志文件的文件增长设置为“受限”,并且我们一直在对其进行大量操作……我知道这是一种不寻常的情况。(在我们这种情况下,我们有足够的磁盘空间,我们增加了日志文件的大小,并将日志文件的文件增长设置为“不受限制”……顺便说一句,接口错误在更改后显示为“受限制” “,最大大小为2,097,152 MB。)
不推荐John推荐的这项技术,因为不能保证没有日志文件就可以附加数据库。将数据库从完全更改为简单,强制执行检查点并等待几分钟。SQL Server将清除日志,然后可以使用DBCC SHRINKFILE缩小日志。
到目前为止,这里的大多数答案都是假设您实际上不需要事务日志文件,但是,如果您的数据库正在使用FULL
恢复模型,并且您想要保留备份以防万一需要还原数据库,则不需要截断或删除该文件。日志文件的答案很多。
删除日志文件(通过截断,丢弃,擦除等)将破坏您的备份链,并阻止您将其恢复到上次完整,差异或事务日志备份以来的任何时间点,直到下一次完整备份为止或进行差异备份。
我们建议您不要使用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%,将会发生很多事件。
SQL Server事务日志需要适当维护,以防止其意外增长。这意味着经常运行事务日志备份。否则,您就有交易日志变满并开始增长的风险。
除了这个问题的答案之外,我还建议您阅读并理解事务日志的常见神话。这些读数可能有助于理解事务日志并决定使用哪些技术“清除”它:
从10个最重要的SQL Server事务日志神话中可以得出:
误解:我的SQL Server太忙了。我不想进行SQL Server事务日志备份
SQL Server中最大的性能密集型操作之一是联机事务日志文件的自动增长事件。由于没有足够频繁地进行事务日志备份,因此联机事务日志将变满并且必须增长。默认增长大小为10%。数据库越忙,如果未创建事务日志备份,则联机事务日志将越快增长。创建SQL Server事务日志备份不会阻止联机事务日志,但是会自动阻止事件。它可以阻止在线交易日志中的所有活动
从交易日志神话:
误解:定期收缩日志是一种良好的维护做法
假。日志增长非常昂贵,因为必须将新块清零。所有写入活动将在该数据库上停止,直到完成归零为止,并且如果您的磁盘写入速度慢或自动增长的大小很大,则暂停可能会很大,用户会注意到。这就是为什么要避免增长的原因之一。如果缩小日志,它将再次增长,并且您只是在不必要的缩小和增长游戏上浪费了磁盘操作
首先检查数据库恢复模型。默认情况下,SQL Server Express Edition为简单恢复模型创建一个数据库(如果我没有记错的话)。
带有Truncate_Only的备份日志DatabaseName:
DBCC ShrinkFile(yourLogical_LogFileName, 50)
SP_helpfile将为您提供逻辑日志文件名。
参考:
如果您的数据库处于完全恢复模型中,并且没有进行TL备份,则将其更改为SIMPLE。
使用 DBCC ShrinkFile ({logicalLogName}, TRUNCATEONLY)
命令。如果这是一个测试数据库,而您正在尝试节省/回收空间,则将有所帮助。
请记住,尽管TX日志确实具有一定的最小/稳定状态大小,它们会逐渐增长。根据您的恢复模式,您可能无法缩小日志-如果为FULL,并且您不发行TX日志备份,则无法缩小日志-它将永远增长。如果不需要TX日志备份,请将恢复模式切换为“ 简单”。
请记住,在任何情况下都绝对不要删除日志(LDF)文件!您几乎会立即遇到数据库损坏。煮熟了!做完了!数据丢失!如果“未修复”,则主MDF文件可能会永久损坏。
永远不要删除事务日志-您将丢失数据!您的部分数据在TX日志中(与恢复模型无关)...如果您分离并“重命名”了有效删除的TX日志文件部分数据库。
对于那些删除了TX日志的用户,您可能需要运行一些checkdb命令并修复损坏,然后再丢失更多数据。
查看Paul Randal关于此主题的博客文章,不好的建议。
同样,通常不要在MDF文件上使用rinkfile,因为它会严重碎片化数据。查看他的不良建议部分以获取更多信息(“为什么不应该收缩数据文件”)
查看Paul的网站-他涵盖了这些问题。上个月,他在“ 神话一天”系列中探讨了许多这些问题。
截断日志文件:
缩小日志文件:
通过以下任一方式收缩数据库:
使用企业管理器:-右键单击数据库,所有任务,收缩数据库,文件,选择日志文件,确定。
使用T-SQL: -Dbcc Shrinkfile([Log_Logical_Name])
您可以通过运行sp_helpdb或在企业管理器中查找数据库的属性来找到日志文件的逻辑名。
我发生的情况是数据库日志文件为28 GB。
您可以采取什么措施来减少这种情况?实际上,日志文件是发生事务后SQL Server保留的那些文件数据。为了处理事务,SQL Server为其分配页面。但是,在交易完成后,并不会突然释放这些交易,希望可能会有一笔交易与同一笔交易相同。这占用了空间。
步骤1:首先在数据库查询的检查点中运行此命令
步骤2:右键单击数据库任务>备份选择备份类型作为事务日志添加目标地址和文件名以保留备份数据(.bak)
再次重复此步骤,这时再指定一个文件名
步骤3:现在转到数据库右键单击数据库
任务>收缩>文件选择文件类型作为日志收缩动作以释放未使用的空间
第四步:
在SQL 2014中正常检查您的日志文件,可以在以下位置找到
C:\ Program Files \ Microsoft SQL Server \ MSSQL12.MSSQL2014EXPRESS \ MSSQL \ DATA
就我而言,它从28 GB减少到1 MB
尝试这个:
USE DatabaseName
GO
DBCC SHRINKFILE( TransactionLogName, 1)
BACKUP LOG DatabaseName WITH TRUNCATE_ONLY
DBCC SHRINKFILE( TransactionLogName, 1)
GO
DBCC SQLPERF(LOGSPACE)
BACKUP LOG Comapny WITH TRUNCATE_ONLY
DBCC SHRINKFILE (Company_log, 500)
DBCC SQLPERF(LOGSPACE)
针对MSSQL 2017并使用SQL Server Management Studio的答案略有更新。我主要是从这些指示出发受益:https://www.sqlshack.com/sql-server-transaction-log-backup-truncate-and-shrink-operations/
我最近有一个数据库备份,因此我备份了事务日志。然后,我再次对其进行了很好的备份。最后,我压缩了日志文件,将文件大小从20G减小到7MB,这与我的数据大小相符。我不认为自从2年前安装以来就没有备份过交易日志。
数据库事务日志缩小到最小大小:
我在多个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