我不是SQL专家,每当我需要做一些基本之外的事情时,我就会想起这个事实。我有一个测试数据库,它的大小不是很大,但是事务日志确实很大。如何清除事务日志?
当前回答
其他一些答案对我来说不适用:当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年前安装这个系统以来,我认为交易日志从来没有备份过。所以把这项任务写在家务管理日历上。
这是一种简单且不优雅且有潜在危险的方法。
备份数据库 分离数据库 重命名日志文件 附加数据库 将重新创建新的日志文件 删除重命名日志文件。
我猜您没有做日志备份。(截断日志)。我的建议是将恢复模式从完全恢复改为简单恢复。这将防止日志膨胀。
减小日志文件的大小应该用于遇到您不希望再次发生的意外增长的情况。如果日志文件将再次增长到相同的大小,那么通过临时缩小它并不能完成太多工作。现在,根据数据库的恢复目标,您应该采取以下操作。
首先,进行完全备份
如果没有确保在出现问题时可以恢复数据库,就不要对数据库进行任何更改。
如果你关心时间点的恢复
(所谓的时间点恢复,我的意思是您关心是否能够恢复到完全备份或差异备份之外的任何内容。)
假设您的数据库处于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给出了一个很好的答案,涵盖了这些方面,包括为什么您可能无法立即缩小日志文件的原因。
使用DBCC ShrinkFile ({logicalLogName}, TRUNCATEONLY)命令。如果这是一个测试数据库,并且您试图节省/回收空间,这将有所帮助。
记住,TX日志确实有一个最小/稳定状态大小,它们将逐渐增长。根据您的恢复模型,您可能无法收缩日志-如果是FULL且您没有发布TX日志备份,则日志不能收缩-它将永远增长。如果不需要TX日志备份,请将恢复模式切换为Simple。
记住,在任何情况下都不要删除日志(LDF)文件!您几乎会立即破坏数据库。煮熟的!完成了!数据丢失!如果“未修复”,主MDF文件可能会永久损坏。
永远不要删除事务日志-你会丢失数据!你的部分数据在TX日志中(不管哪种恢复模式)…如果分离并“重命名”TX日志文件,将有效地删除数据库的一部分。
对于那些已经删除了TX日志的用户,您可能希望在丢失更多数据之前运行一些checkdb命令并修复损坏。
看看保罗·兰德尔关于这个话题的博客文章,糟糕的建议。
此外,一般不要在MDF文件上使用收缩文件,因为它会严重破坏你的数据。查看他的坏建议部分以获得更多信息(“为什么你不应该缩小你的数据文件”)
看看保罗的网站,他讨论了这些问题。上个月,他在他的“一天的神话”系列文章中探讨了许多这样的问题。
免责声明:在尝试之前请仔细阅读下面的评论,并确保检查接受的答案。就像我5年前说的:
如果有人有任何评论要补充的情况下,这不是一个 适当的或最优的解决方案,然后请在下面评论
事实证明有:-)
最初的回答:
右键单击数据库名称。 选择“任务→收缩→数据库” 然后单击“确定”!
我通常打开包含数据库文件的Windows资源管理器目录,所以我可以立即看到效果。
我真的很惊讶这竟然能起作用!通常我以前使用DBCC,但我刚刚尝试了一下,它没有缩小任何东西,所以我尝试了GUI(2005),它工作得很好——在10秒内释放了17 GB
在完全恢复模式下,这可能不起作用,因此您必须首先备份日志,或者更改为简单恢复,然后收缩文件。[感谢@onupdatecascade]
--
PS:我很欣赏一些关于这种危险的评论,但在我的环境中,我自己这样做没有任何问题,尤其是因为我总是先做完全备份。因此,在继续之前,请考虑您的环境,以及这会如何影响您的备份策略和工作安全性。我所做的一切只是把人们指向微软提供的一个功能!
推荐文章
- SQL Server数据库备份恢复到低版本
- SQL Server:过滤sp_who2的输出
- 在SQL Server上使用varchar(MAX) vs TEXT
- Visual Studio: ContextSwitchDeadlock
- Sql Server字符串到日期的转换
- 如何将SQL Azure数据库复制到本地开发服务器?
- SQL Server 2008不能用新创建的用户登录
- SQL Server中User和Login的区别
- 在参数声明中,varchar(MAX)的大小是多少?
- 数据库性能调优有哪些资源?
- 为两列的组合添加唯一的约束
- SQL Server的隐藏特性
- 方括号[]在sql语句中有什么用?
- 对象'DF__*'依赖于列'*' -将int改为double
- 如何根据出生日期和getDate()计算年龄(以年为单位)