SQL Server 2008日志不会截断

时间:2009-03-14 22:23:03

标签: sql sql-server sql-server-2008

我认为自己是一位非常有经验的SQL人。但我没有做这两件事:

  • 减小分配日志的大小。
  • 截断日志。

    DBCC sqlperf(logspace)

返回:

Database Name   Log Size (MB)   Log Space Used (%)  Status
ByBox       1964.25     30.0657         0

以下内容不适用于SQL 2008

DUMP TRANSACTION ByBox WITH TRUNCATE_ONLY

运行以下内容无需任何操作

DBCC SHRINKFILE ('ByBox_1_Log' , 1)
DBCC shrinkdatabase(N'bybox')

我尝试过备份。我也试过设置数据库的属性 - '恢复模型'为'FULL'和'SIMPLE'以及上述所有内容的组合。我也尝试将兼容性设置为SQL Server 2005(我使用此设置,因为我想匹配我们的生产服务器)和SQL Server 2008.

无论我尝试什么,日志仍保持在1964.25 MB,使用率为30%,仍然在增长。

我希望日志在0%附近回落,并将日志文件大小减少到100 MB,这就足够了。我的数据库必须恨我;它只是忽略了我要求它做的关于日志的一切。

进一步说明。生产数据库有很多复制表,当我使用以下内容在开发盒上执行恢复时,我关闭了这些表:

-- Clear out pending replication stuff
exec sp_removedbreplication
go
EXEC sp_repldone @xactid = NULL, @xact_segno = NULL,
     @numtrans = 0, @time = 0, @reset = 1
go

尝试:

SELECT log_reuse_wait, log_reuse_wait_desc
FROM sys.databases
WHERE NAME='bybox'

返回

log_reuse_wait  log_reuse_wait_desc
0   NOTHING

如何解决此问题?


查看this并将恢复模式设置为FULL,我尝试了以下内容:

USE master
GO

EXEC sp_addumpdevice 'disk', 'ByBoxData', N'C:\<path here>\bybox.bak'

-- Create a logical backup device, ByBoxLog.
EXEC sp_addumpdevice 'disk', 'ByBoxLog', N'C:\<path here>\bybox_log.bak'

-- Back up the full bybox database.
BACKUP DATABASE bybox TO ByBoxData

-- Back up the bybox log.
BACKUP LOG bybox TO ByBoxLog

返回:

Processed 151800 pages for database 'bybox', file 'ByBox_Data' on file 3.
Processed 12256 pages for database 'bybox', file 'ByBox_Secondary' on file 3.
Processed 1 pages for database 'bybox', file 'ByBox_1_Log' on file 3.
BACKUP DATABASE successfully processed 164057 pages in 35.456 seconds (36.148 MB/sec).

Processed 2 pages for database 'bybox', file 'ByBox_1_Log' on file 4.
BACKUP LOG successfully processed 2 pages in 0.056 seconds (0.252 MB/sec).

完美!但事实并非如此。

DBCC SHRINKFILE('ByBox_1_Log',1)现在返回

DbId    FileId  CurrentSize MinimumSize UsedPages   EstimatedPages
7   2   251425  251425  251424  251424

和DBCC SQLPERF(LOGSPACE)仍然报告使用率为30%。

我想我可能不得不辞职,因为SQL Server 2008中可能存在错误,或者我的日志文件已经以某种方式损坏。但是,我的数据库处于良好的工作状态,这让我觉得有一个错误(想到的时候不寒而栗)

15 个答案:

答案 0 :(得分:36)

在我的情况下,我有一个650 MB的数据库,在SQL Server 2008中有一个370 GB的日志文件。无论我尝试了什么,我都无法让它缩小。我尝试了所有列出的答案,但仍然没有效果。

最后,我在其他地方找到了一个非常简短的评论。这是运行:

BACKUP LOG DatabaseName TO DISK = N'D:\Backup\DatabaseName_log.bak'
GO
DBCC SHRINKFILE('MyDatabase_Log', 1)
GO

这导致日志文件从37 GB缩小到1 MB。呼!

答案 1 :(得分:12)

我找到了 DBCC SHRINKFILE (Transact-SQL) (MSDN)。

以下示例将AdventureWorks数据库中的日志文件缩小为1 MB。要允许DBCC SHRINKFILE命令收缩文件,首先通过将数据库恢复模型设置为SIMPLE来截断该文件。

USE AdventureWorks;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks
SET RECOVERY FULL;
GO

答案 2 :(得分:9)

谨防改变恢复模式的含义!!

现在,对于所有生产DBAs 考虑使用该脚本的一个更清醒的想法:

在您将恢复模式从简单变为简单之前......如果您处于开发/ QA环境中,则无需担心。但是,如果您处于生产环境中,您有责任确保在出现问题时完全恢复数据,您可能需要仔细研究BOL在执行此操作时所说的内容(请参阅BOL:“管理数据库” “ - &gt;”“事务日志管理” - &gt;“恢复模型和事务日志管理”):

数据库可以随时切换到另一个恢复模型。但是,从简单的恢复模型切换是不寻常的。请注意,如果在批量操作期间切换到完全恢复模型,则批量操作的日志记录会从最小日志记录更改为完全日志记录,反之亦然。

从简单恢复模式切换后

  

如果从完整或大容量日志恢复模型切换到简单恢复模型,则会中断备份日志链。因此,我们强烈建议您在切换之前立即备份日志,这样您就可以恢复数据库。切换后,您需要定期进行数据备份以保护数据并截断事务日志的非活动部分。

     

切换到简单恢复模式后

     

如果从完整或大容量日志恢复模型切换到简单恢复模型,则会中断备份日志链。因此, 我们强烈建议您在切换之前立即备份日志,这样您就可以恢复数据库。 切换后,您需要定期获取数据备份以保护您的数据并截断事务日志的非活动部分。

真的? “ 我们强烈建议您在切换之前立即备份日志,这样您就可以恢复数据库。 ”我无法理解为什么这个很少信息的大小隐藏在名为“切换到简单恢复模式之后”的部分中,使大多数“正常人”认为他们可以继续并切换它然后继续或返回并在更改后阅读。 / p>

咆哮

致Microsoft:所以,如果我错了,请纠正我,如果我在从FULL更改为SIMPLE之前未能执行t-log备份并且看到我的数据库以某种方式损坏(听说过{{3}在我能够备份之前......然后我搞砸了,对吧?如果将我的****生产****数据库的恢复模型从FULL切换到SIMPLE会破坏备份日志链,这样如果我在执行之前未能进行事务日志备份(如上所述) 我可能会丢失数据 ,然后为什么不明白,在一个闪烁的MARQUEE中,它比你看起来更大?你应该真的抓住我的衬衫,抓住我来引起我的注意(可以这么说)并警告我这个UPFRONT的重要性!!

答案 3 :(得分:8)

减少日志文件大小的另一种简单方法是:

  • 备份日志
  • 数据库的完整备份
  • 缩小日志文件
  • 再次备份日志
  • 再次收缩日志文件

通过这种方式,您不必修改任何数据库参数,并且您的日志文件大小为1 MB。

答案 4 :(得分:5)

我总是讨厌SQL Server处理日志文件物理收缩的方式。请注意,我总是通过企业管理器/ SQL Server Management Studio完成此操作,但是当您收缩/截断日志文件时,日志文件的物理大小似乎不会减少,直到对数据库进行完全备份之后数据文件,然后再次备份日志文件。我永远无法确定确切的模式,但你可以试着看看确切的顺序是什么。但是,它始终涉及对数据文件进行完整备份。

答案 5 :(得分:5)

找到了解决方案!

我向数据库添加了大量数据,因此强制日志扩展。然后,我删除了不需要的数据,以使我的数据库恢复原状。

备份和瞧,完美的0%日志。

因此解决方案是扩展日志。

答案 6 :(得分:4)

尝试运行

DBCC OPENTRAN

检查是否有任何未结交易。

答案 7 :(得分:4)

这听起来有些愚蠢,但我发现我必须执行两个完整的数据库和日志文件备份才能收缩数据库。

使用SQL Server Management Studio时,在执行完整数据库备份后执行完整事务日志备份后,缩小文件页面会显示大量可用空间,但不会截断日志文件。

但是,当我运行数据库和日志文件的第二次完整备份时,我发现事务日志的完整备份要小得多,因为它似乎只是备份自上次备份以来的新更改

完成第二次备份后,我在管理工作室内再次运行收缩工具。它仍然显示有足够的​​可用空间,但是这次当我单击OK时,日志文件的大小会减小。

所以,请尝试以下方法。

  1. 对数据库和日志文件进行完整备份。如果在收缩工具中检查,您应该会看到日志文件中现在有足够的可用空间。但是,单击“确定”不会删除可用空间。

  2. 对数据库和日志文件进行第二次完整备份。您应该发现数据库的完整备份与第一次完整备份的大小相似。完整事务日志备份的大小应该小得多。

  3. 在日志文件上运行收缩工具,运气好的话,日志文件的大小应该会减小。我最后一次这样做,它从180 GB减少到12 MB,缩小工具表明文件中仍有10 MB的可用空间。

答案 8 :(得分:4)

我终于找到了日志文件收缩问题的解决方案。所有以前的选项都不适用于我,并没有将日志文件缩小到所需的大小。我找到的解决方案是:

  • 备份数据库
  • 将恢复模式设置为简单
  • 使用SQL Server Management Studio
  • 分离数据库
  • 删除日志文件
  • 在没有日志文件的情况下附加数据库。在“添加屏幕”的下半部分,您会看到一行表示缺少日志文件
  • 单击此行的删除,然后单击确定以附加
  • 将恢复模式设置回完整

答案 9 :(得分:2)

我知道你的意思 - SQL服务器可能会有点令人抓狂。这是一些尝试的示例代码。本质上,它会截断日志文件,然后然后尝试收缩文件。让我知道它是如何工作的。另一件事......你不会有未提交的交易,不是吗?

Use YourDatabase
GO

DBCC sqlperf(logspace)  -- Get a "before" snapshot
GO  

BACKUP LOG BSDIV12Update WITH TRUNCATE_ONLY;  -- Truncate the log file, don't keep a backup
GO

DBCC SHRINKFILE(YourDataBaseFileName_log, 2);  -- Now re-shrink (use the LOG file name as found in Properties / Files.  Note that I didn't quote mine).
GO

DBCC sqlperf(logspace)  -- Get an "after" snapshot
GO

更新: Simon注意到他在BACKUP命令上收到错误。当我之前回答时,我没有意识到SQL Server 2008中已经停止使用“Truncate_only”。经过一些研究后,收缩日志文件的建议步骤是(a)将恢复模型更改为简单,然后(b)使用DBCC ShrinkFile缩小文件,如上所述。不幸的是,你提到你已经尝试将恢复模型设置为Simple,所以我假设你之后也运行了DBCC Shrinkfile。它是否正确?请告诉我。

答案 10 :(得分:2)

这可能是一种痛苦,并且可能有很多事情。你要确定的第一件事是没有“卡住”的交易。如果您的事务永远不会关闭,则无法缩小日志。运行“DBCC OPENTRAN”以查找运行时间最长的事务。

另外,请确保重新组织(我认为这是正确的术语)并在缩小之前将所有内容移动到文件的开头。

答案 11 :(得分:2)

阅读答案我几乎不相信它们是由DBA编写的。基本的黄金法则:

  1. 在执行任何维护之前的任何数据库中,包括 缩小日志,您应该执行完整备份。

  2. 执行任何数据库维护,包括收缩,何时 整个特定数据库上没有其他任何事情发生 维护的持续时间。如果有必要,暂停 非本质的应用程序。始终牢记健康 数据库是与之交互的任何应用程序的灵魂。

  3. 毕竟,以下用于缩小数据库事务日志的命令在SQL Server 2005及更高版本的SQL Server版本上始终可以正常工作:

    USE DatabaseName
    GO
    -- Truncate the Transaction log
    ALTER DATABASE DatabaseName SET RECOVERY SIMPLE
    CHECKPOINT
    ALTER DATABASE DatabaseName SET RECOVERY FULL
    GO
    -- Shrink the Transaction Log as recommended my Microsoft.
    
    DBCC SHRINKFILE ('database_txlogfilelogicalname', [n -size to shrink in MBytes])
    GO
     -- Pass the freed pages back to OS control.
    DBCC SHRINKDATABASE (DatabaseName, TRUNCATEONLY)
    GO
    -- Tidy up the pages after shrink
    DBCC UPDATEUSAGE (0);
    GO
    -- IF Required but not essential
    -- Force to update all tables statistics
    exec sp_updatestats
    GO
    

答案 12 :(得分:1)

我终于得出结论,SQLServer 2008中存在一个错误。

我已经尝试过一切,我能想到的每一个组合。我已备份数据库,删除它,重新创建它,恢复它。完全相同的问题。

我也跑了:

DBCC CHECKDB
DBCC UPDATEUSAGE (bybox)

所有检查都没问题。

我可以说下一个服务包。

答案 13 :(得分:1)

SQL Server 2012:我遇到了一个问题,即没有日志文件(并且所有文件已经在SIMPLE恢复中)都会缩小。

这对我有用......我重新启动了SQL Server实例(因为我可以)并且每个坏男孩都缩小了。

随着重新开始,随着收缩而遏制的是什么。这仅适用于紧急情况(或当它是您的服务器时),而不是常规的长期解决方案。

答案 14 :(得分:-1)

请运行:

SELECT name, log_reuse_wait, log_reuse_wait_desc FROM sys.databases

并查看问题数据库的log_reuse_wait是什么 如果复制这是错误,则需要此值0,2或4