SQL Server 2005事务日志不会截断

时间:2012-05-10 21:41:52

标签: sql-server transactions database-backups ssms

我有一个138 GB的数据库.mdf文件以及55 GB的事务日志文件。

恢复模式设置为 Full (它不需要)。我运行了数据库和事务日志的完整备份。事务日志仍为55 GB,没有可用空间来缩小文件。

我通过SQL Server Management Studio GUI运行该备份。然后,我运行以下命令以尝试强制转换日志收缩:

BACKUP LOG database WITH TRUNCATE_ONLY
DBCC SHRINKFILE (logfile, TRUNCATEONLY )

日志文件仍为55 GB。然后我将恢复模型更改为Simple并让它静置几天,但它仍然是55 GB。我再次尝试了上面的那两个命令,但它仍然没有截断任何内容。

无论我尝试什么,这个日志文件都不会缩小。由于我们根本不需要事务日志,我甚至尝试分离数据库,重命名日志文件并重新连接。这不起作用,因为实际上有2个事务日志,并且在尝试重新连接而没有日志时出现错误。另一个日志文件只有1 MB,我也尝试删除它,但也得到一个错误,说它不是空的。

我有什么遗漏,或者其他我可以尝试的东西吗?

感谢您的帮助!

7 个答案:

答案 0 :(得分:2)

在我必须缩小事务日志的极少数情况下,我在SQL Server 2005上使用的命令与您尝试的命令略有不同:

backup log database with no_log
dbcc shrinkfile (logfile,1)

...with no_log代替...with truncate_onlydbcc shrinkfile的第二个参数必须是日志文件所需的新大小)

为了确保我正确获取日志文件的名称(因为我懒得输入数据库的名称),我使用这个脚本自动获取数据库和日志文件的名称:

declare @dbname varchar(255)
declare @logfile varchar(255)

select @dbname = db_name()
select @logfile = name from sysfiles where filename like '%.ldf'

backup log @dbname with no_log
dbcc shrinkfile (@logfile,1)

您需要直接在要收缩日志文件的数据库中运行它 免责声明:我从未在具有多个日志文件的数据库上使用它,就像您的一样。如果默认情况下找到错误的日志文件,可能需要更改它。

如果您不需要Simple恢复模式,则可以在运行脚本之前将恢复模式设置为Full

收缩日志后,您应该立即进行完整备份 如果您将数据库保留在Full恢复模式,这非常重要! (因为缩小日志会破坏日志链,这意味着在您执行下一次完整备份之前,后续日志备份将毫无用处)

答案 1 :(得分:0)

尝试设置checkpoint http://msdn.microsoft.com/en-us/library/ms188748.aspx

这会将所有脏页写入磁盘,从当前数据库的缓冲区缓存中刷新日志页,从而最大限度地减少恢复期间必须前滚的修改次数。它会创建一个新的最小恢复日志序列号(lsn)并删除该lsn之前的所有记录,缩小文件。

答案 2 :(得分:0)

“我甚至尝试分离数据库,重命名日志文件并重新连接”:日志不是可选组件!立即运行DBCC CHECKDB以查看是否已导致损坏。如果出于某种原因有未刷新的页面,导致损坏。即使不是你在赌博。

SQL Server日志文件不是信息性文本日志。

如果您不需要日志,请切换到简单模式并收缩日志文件(您已经这样做了)。 TRUNCATE_ONLY is obsolete,我不知道它是否做了什么。

查看 sys.databases 并查看log_reuse_wait_desc列中的值。它会告诉你什么在保持日志。

答案 3 :(得分:0)

首先,您可以将日志文件的初始大小设置得更低吗?如果某人以55GB的速度启动它,它可能不会低于此值。

其次,你可能don't need two transaction logs。第二个将是“活动的”,但在第一个填满之前不会使用。如果您没有受限制的增长并且仍有剩余磁盘空间,则第一个可能永远不会满。

第三,正如@JohnNolan所建议的(正如我将要建议的那样),尝试检查点,因为这应该允许在简单恢复模型下进行日志截断。

此外,建议您avoid using TRUNCATE_ONLY

答案 4 :(得分:0)

这是ms sql服务器的一个问题,但这是解决方案....

强制截断数据库做ff:

  1. 在缩小之前运行完整的数据库备份
  2. 将恢复从完整设置为简单
  3. dbcc shrinkfile
  4. 将恢复设置恢复为完整
  5. 在收缩后运行完整的数据库备份
  6. 这是强制收缩的代码

     use master
     Alter database dbname set Recovery simple; 
    
     use dbname
     DBCC SHRINKFILE (dbname_log, 0, TRUNCATEONLY)
     Alter database dbname set Recovery full;
    

    希望这会有所帮助。

答案 5 :(得分:0)

我如何解决这个问题:

1)从sys.databases中选择log_reuse_wait_desc,其中name ='your_db_name'

这将为您提供阻止VLF重复使用的功能。在慢速期间(即当日志没有被大量使用时,这应该是'无')。如果您看到其他值,则可能需要进行故障排除。

2)看一下dbcc loginfo的输出。它为您的日志文件中的每个VLF返回一行。状态列告诉您VLF是否正在使用中。为了缩小日志,您需要将未使用的VLF放在文件的末尾。您可能必须等待自然活动才能执行此操作。由于VLF在一种环中使用,未使用的一个(s)最终应该在文件的末尾。

答案 6 :(得分:0)

使用以下查询:

backup log [dbname] with truncate_only
go
DBCC SHRINKDATABASE ([dbname], 10, TRUNCATEONLY)
go