代码之家  ›  专栏  ›  技术社区  ›  Simon Hughes

SQL Server 2008日志将不会截断

  •  21
  • Simon Hughes  · 技术社区  · 15 年前

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

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

      DBCC sqlperf(日志空间)

    返回:

    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')
    

    不管我怎么做,日志仍保持在1964.25MB,使用率为30%,而且还在增长。

    我希望日志恢复到接近0%,并将日志文件大小减少到100MB,这就足够了。我的数据库一定恨我;它只是忽略了我要求它做的关于日志的所有事情。

    另请注意。生产数据库有相当多的复制表,当我使用以下方法在开发箱上执行恢复时,我会关闭这些复制表:

    -- 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 将恢复模式设置为“完全”,我尝试了以下方法:

    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
    

    我想我可能不得不承认SQL Server 2008中很可能存在漏洞,或者我的日志文件已以某种方式损坏。然而,我的数据库工作状态良好,这让我觉得有一个bug (一想到这里就不寒而栗) .

    15 回复  |  直到 9 年前
        1
  •  36
  •   Peter Mortensen Len Greski    9 年前

    在我的情况下,我有一个650MB的数据库,在SQLServer2008中有一个370GB的日志文件。不管我怎么做,我都无法让它缩小。我尝试了这里列出的所有答案,但仍然没有任何效果。

    最后,我在其他地方找到了一条非常简短的评论,它确实有效。要运行此命令,请执行以下操作:

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

        2
  •  12
  •   Peter Mortensen Len Greski    9 年前

    我发现 DBCC SHRINKFILE (Transact-SQL) (MSDN)。

    以下示例将AdventureWorks数据库中的日志文件压缩为1MB。允许 DBCC SHRINKFILE

    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
    
        3
  •  9
  •   Peter Mortensen Len Greski    9 年前

    请注意更改恢复模式的影响!!

    现在让我们为你们大家再作一次清醒的思考 生产 DBAs 考虑使用脚本:

    在将恢复模式从完全更改为简单之前。。。如果您处于开发阶段,则无需担心/ QA 环境但是,如果您所处的生产环境中有责任确保在发生问题时完全恢复数据,您可能需要仔细了解BOL对此的看法(请参阅“管理数据库”->“事务日志管理”->“恢复模型和事务日志管理”下的BOL):

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

    从简单恢复模式切换后

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

    切换到简单恢复模式后

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

    我们强烈建议您在切换之前立即备份日志,这样可以将数据库恢复到该点。 “我不明白为什么会这样 小的 一个名为“切换到简单恢复模式后”的部分隐藏了一些信息,这让大多数“普通人”认为他们可以继续切换,然后继续,或者在更改后回来阅读。

    微软:所以,如果我错了,请纠正我,如果我在从完整变为简单之前没有做t-log备份,你会发现我的数据库不知何故被破坏了(听说过吗 Murphy's law ?)就在我能够接受备份之前。。。那我就完蛋了,对吧?如果将我的****生产****数据库的恢复模式从完整切换到简单,可能会破坏备份日志链,因此如果我在备份之前没有进行事务日志备份(如上所示) 我可能会丢失数据 那你为什么不在一个闪烁的大屏幕上突出它,使它比你看起来更大呢??!你真的应该抓住我的衬衫,拍打我以引起我的注意(可以这么说),并预先警告我这件事的重要性!!

        4
  •  8
  •   Peter Mortensen Len Greski    9 年前

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

    这样,您不必修改任何数据库参数,日志文件大小为1MB。

        5
  •  5
  •   HardCode    15 年前

    我一直讨厌SQL Server处理日志文件物理收缩的方式。请注意,我一直都是通过Enterprise Manager/SQL Server Management Studio来完成这项工作的,但似乎在收缩/截断日志文件时,日志文件的物理大小不会减小,直到对数据库的数据文件进行完全备份,然后再次备份日志文件。我无法确定确切的模式,但你可以试着看看确切的顺序是什么。但是,它始终涉及对数据文件进行完整备份。

        6
  •  5
  •   Simon Hughes    15 年前

    找到了解决办法!

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

    因此,解决方案是使日志展开。

        7
  •  4
  •   Mitch Wheat    15 年前

    试着跑步

    DBCC OPENTRAN
    

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

        8
  •  4
  •   Peter Mortensen Len Greski    9 年前

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

    使用时 SQL Server Management Studio

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

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

    所以,试试下面的方法。

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

    2. 在日志文件上运行收缩工具,如果运气好的话,日志文件的大小应该会减小。上次我这样做时,它从180GB减少到12MB,而收缩工具表示文件中仍然有10MB的可用空间。

        9
  •  4
  •   Peter Mortensen Len Greski    9 年前

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

    • 备份数据库
    • 将恢复模式设置为“简单”
    • 使用分离数据库 SQL Server Management Studio
    • 删除日志文件
    • 附加不带日志文件的数据库。在“添加屏幕”的下半部分,有一行显示日志文件丢失
    • 单击此行的“删除”和“附加”的“确定”
    • 将恢复模式设置回完全模式
        10
  •  2
  •   jhale    15 年前

    这可能是一种痛苦,可能有很多事情。您应该确保的第一件事是没有“卡住”的交易。如果事务从未关闭,则无法收缩日志。运行“DBCC OPENTRAN”以查找运行时间最长的事务。

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

        11
  •  2
  •   Mark Brittingham    15 年前

    我知道你的意思-SQL server可能会有点疯狂。下面是一些要尝试的示例代码。本质上,它会截断日志文件并 然后 尝试缩小文件。让我知道它是如何工作的。还有一件事……你不会有未提交的交易,是吗?

    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注意到备份命令出现错误。当我早些时候回答时,我没有意识到SQL Server 2008中已经停止了“仅截断”。经过一番研究后,收缩日志文件的建议步骤是:(a)将恢复模型更改为Simple,然后(b)如上所述使用DBCC ShrinkFile收缩文件。不幸的是,您提到您已经尝试将恢复模型设置为Simple,因此我假设您随后也运行了DBCC Shrinkfile。这是正确的吗?请让我知道。

        12
  •  2
  •   Peter Mortensen Len Greski    9 年前

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

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

    2. 维护的持续时间。如有必要,暂停 非必要应用。永远记住,健康的人 数据库是任何与之交互的应用程序的灵魂。

    在所有这些之后,以下用于收缩数据库事务日志的命令在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
    
        13
  •  1
  •   Simon Hughes    15 年前

    我终于得出结论,SQLServer2008中存在一个bug。

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

    我还跑了:

    DBCC CHECKDB
    DBCC UPDATEUSAGE (bybox)
    

    一切正常。

    我只能说下一个服务包。

        14
  •  1
  •   Peter Mortensen Len Greski    9 年前

    SQL Server 2012 :我遇到了一个问题,没有任何日志文件(所有日志文件都已处于简单恢复中)会收缩。

    这对我有用。。。我重新启动了SQLServer实例(因为我可以),所有这些坏家伙都缩小了。

    无论是什么阻碍了它的收缩,都会随着重启而释放。这只适用于紧急情况(或者是服务器),而不是常规的长期解决方案。

        15
  •  -1
  •   K.Dᴀᴠɪs    6 年前

    请运行:

    SELECT name, log_reuse_wait, log_reuse_wait_desc FROM sys.databases
    

    看看这是什么 log_reuse_wait 为了你的问题db 如果这是复制错误,则需要该值0、2或4