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


当前回答

DB事务日志收缩到最小大小:

备份:事务日志 收缩文件:事务日志 备份:事务日志 收缩文件:事务日志

我在几个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

其他回答

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

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

来自微软关于备份的文章

我们建议不要手动使用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)

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

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

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

首先,进行完全备份

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

如果你关心时间点的恢复

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

假设您的数据库处于FULL恢复模式。如果不是,那么确保它是:

ALTER DATABASE testdb SET RECOVERY FULL;

Even if you are taking regular full backups, the log file will grow and grow until you perform a log backup - this is for your protection, not to needlessly eat away at your disk space. You should be performing these log backups quite frequently, according to your recovery objectives. For example, if you have a business rule that states you can afford to lose no more than 15 minutes of data in the event of a disaster, you should have a job that backs up the log every 15 minutes. Here is a script that will generate timestamped file names based on the current time (but you can also do this with maintenance plans etc., just don't choose any of the shrink options in maintenance plans, they're awful).

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;

Note that \\backup_share\ should be on a different machine that represents a different underlying storage device. Backing these up to the same machine (or to a different machine that uses the same underlying disks, or a different VM that's on the same physical host) does not really help you, since if the machine blows up, you've lost your database and its backups. Depending on your network infrastructure it may make more sense to backup locally and then transfer them to a different location behind the scenes; in either case, you want to get them off the primary database machine as quickly as possible.

Now, once you have regular log backups running, it should be reasonable to shrink the log file to something more reasonable than whatever it's blown up to now. This does not mean running SHRINKFILE over and over again until the log file is 1 MB - even if you are backing up the log frequently, it still needs to accommodate the sum of any concurrent transactions that can occur. Log file autogrow events are expensive, since SQL Server has to zero out the files (unlike data files when instant file initialization is enabled), and user transactions have to wait while this happens. You want to do this grow-shrink-grow-shrink routine as little as possible, and you certainly don't want to make your users pay for it.

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

因此,您需要为您的日志文件提出一个实用的大小。如果不了解您的系统,这里没有人能告诉您这是什么,但是如果您经常缩小日志文件,并且它再次增长,那么一个好的水印可能比它的最大值高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重用日志文件的部分(基本上淘汰不活跃的事务),而不是不断增长以保留所有事务的记录(就像完全恢复一样,直到备份日志)。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

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

有些事你不想做

Back up the log with TRUNCATE_ONLY option and then SHRINKFILE. For one, this TRUNCATE_ONLY option has been deprecated and is no longer available in current versions of SQL Server. Second, if you are in FULL recovery model, this will destroy your log chain and require a new, full backup. Detach the database, delete the log file, and re-attach. I can't emphasize how dangerous this can be. Your database may not come back up, it may come up as suspect, you may have to revert to a backup (if you have one), etc. etc. Use the "shrink database" option. DBCC SHRINKDATABASE and the maintenance plan option to do the same are bad ideas, especially if you really only need to resolve a log problem issue. Target the file you want to adjust and adjust it independently, using DBCC SHRINKFILE or ALTER DATABASE ... MODIFY FILE (examples above). Shrink the log file to 1 MB. This looks tempting because, hey, SQL Server will let me do it in certain scenarios, and look at all the space it frees! Unless your database is read only (and it is, you should mark it as such using ALTER DATABASE), this will absolutely just lead to many unnecessary growth events, as the log has to accommodate current transactions regardless of the recovery model. What is the point of freeing up that space temporarily, just so SQL Server can take it back slowly and painfully? Create a second log file. This will provide temporarily relief for the drive that has filled your disk, but this is like trying to fix a punctured lung with a band-aid. You should deal with the problematic log file directly instead of just adding another potential problem. Other than redirecting some transaction log activity to a different drive, a second log file really does nothing for you (unlike a second data file), since only one of the files can ever be used at a time. Paul Randal also explains why multiple log files can bite you later.

要积极主动

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

The worst possible settings here are 1 MB growth or 10% growth. Funny enough, these are the defaults for SQL Server (which I've complained about and asked for changes to no avail) - 1 MB for data files, and 10% for log files. The former is much too small in this day and age, and the latter leads to longer and longer events every time (say, your log file is 500 MB, first growth is 50 MB, next growth is 55 MB, next growth is 60.5 MB, etc. etc. - and on slow I/O, believe me, you will really notice this curve).

进一步的阅读

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

我在2009年写了一篇博文,当时我看到一些“这里是如何缩小日志文件”的帖子涌现出来。

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

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

Mike Walsh给出了一个很好的答案,涵盖了这些方面,包括为什么您可能无法立即缩小日志文件的原因。

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

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

从10个最重要的SQL Server事务日志神话:

Myth: My SQL Server is too busy. I don’t want to make SQL Server transaction log backups One of the biggest performance intensive operations in SQL Server is an auto-grow event of the online transaction log file. By not making transaction log backups often enough, the online transaction log will become full and will have to grow. The default growth size is 10%. The busier the database is, the quicker the online transaction log will grow if transaction log backups are not created Creating a SQL Server transaction log backup doesn’t block the online transaction log, but an auto-growth event does. It can block all activity in the online transaction log

来自事务日志神话:

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

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

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