INF: 如何將 SQL Server 交易記錄檔壓縮

文章翻譯 文章翻譯
文章編號: 256650
本文曾發行於 CHT256650
全部展開 | 全部摺疊

在此頁中

結論

這裡有一些常見的原因,解釋當您使用 DBCC SHRINKFILE 或 DBCC SHRINKDATABASE 命令時,為何無法壓縮交易記錄檔。 在《SQL Server 線上叢書》的 DBCC SHRINKFILE 及 DBCC SHRINKDATABASE 主題裡提供了詳細的資訊,此處只是簡略的摘要。

其他相關資訊

  • 在 Microsoft SQL Server 7.0 裡,SHRINKFILE 及 SHRINKDATABASE 命令設定了壓縮的目標大小。 每一個記錄檔案都由這些命令所標示,但是實際上壓縮檔案的卻是記錄檔備份或記錄檔截斷。 所以,在使用 SHRINKFILE 或 SHRINKDATABASE 命令後,還必須在記錄檔有機會壓縮前,發出命令來截斷記錄檔。
  • 您無法將記錄檔的大小壓縮成小於這些條件允許的大小:

    • 若要將記錄檔壓縮為小於原始大小,就必須使用 DBCC SHRINKFILE 來壓縮個別的檔案。 您無法使用 DBCC SHRINKDATABASE 來將記錄檔壓縮為小於其原始或要求的自訂大小。 其原始大小的定義是由 CREATE DATABASE 加上任何明確的 ALTER DATABASE 命令所產生的記錄檔大小。 此原始大小並不包括記錄檔的自動成長。

    • 實體記錄檔案絕不能小於目前記錄檔案所使用的空間總數。您可以使用 DBCC SQLPERF (LOGSPACE) 命令來監視使用的空間總數。

    • 目前Model資料庫記錄檔的大小,為該伺服器上任何資料庫記錄檔中最小的。根據預設值,Model資料庫記錄檔會小於 1 MB。

    • 因為記錄檔只可能在虛擬記錄檔案 (VLF) 界限裡被壓縮,即使空間未被使用,也不可能將記錄檔案壓縮成小於 VLF 的大小。 同樣地,如果正在使用部份的 VLF,您將無法壓縮 VLF 的任何空間。如需更多詳細資訊,請參閱《SQL Server 線上叢書》中的 「虛擬記錄檔案」及 「交易記錄檔實體結構」主題。


  • 交易記錄檔為一「換行」的記錄檔。這表示在任何時間裡,無論在記錄檔的開始、中間及/或結尾, VLF 均擁有「可使用」或「可重新使用」的空間。若要將記錄檔壓縮,則在記錄檔的結尾必須有「可使用」的空間,而 不只是在記錄檔中任何其他地方有可用空間。此外,您也只可以壓縮整個 VLF。若要將交易記錄檔壓縮,VLF 記錄檔案的結尾必須為非使用中及被截斷的狀態。 如需更多詳細資訊,請參閱《SQL Server 線上叢書》中的「截斷交易記錄檔」主題。
這裡有幾件事情請注意:
  • 在做了會影響系統的變更前後,一定要執行系統資料庫及使用者資料庫的備份。 DBCC SHRINKFILE 及 DBCC SHRINKDATABASE 是非記錄式的作業,且執行它們會使進一步的交易記錄檔備份無效。 在您執行 DBCC SHRINKFILE 或 DBCC SHRINKDATABASE 兩者之一的命令後,一定要製作一個完整的資料庫備份。

  • 請確認在應該發生壓縮的期間,沒有排定進行備份。

  • 請確認沒有舊有、長期執行,或未複製的交易。若要執行這項作業,請使用類似下列的程式碼:
    DBCC OPENTRAN (database_name)
  • 執行 DBCC SHRINKFILE 或 DBCC SHRINKDATABASE 命令以標示壓縮點。DBCC SHRINKFILE 及 DBCC SHRINKDATABASE 的權限預設為 sysadmin 固定伺服器角色或 db_owner 固定資料庫角色的成員,並且不能轉移。如需有關這些命令之間差異的詳細資訊, 請參閱《SQL 線上叢書》中的下列主題 (請注意不同的參數):

    DBCC SHRINKFILE     (file_name, target_size)
    DBCC SHRINKDATABASE (database_name, target_percent)
  • 建立一些虛擬的交易,使記錄檔換行,然後再使用 BACKUP 命令來截斷記錄檔。 實際上將記錄檔壓縮成所標示目標大小記錄檔的是 BACKUP 陳述式。

    下列範例說明如何建立虛擬交易,使記錄檔換行成單一邏輯記錄檔並使其截斷以進行壓縮。 請依您的環境需要來修改範例。
    SET NOCOUNT ON
    DECLARE @LogicalFileName sysname,
            @MaxMinutes INT,
            @NewSize INT
    
    -- Your criteria here.
    USE     Your_Database_Name              -- This is the name of the database 
    for which the log will be shrunk.
    SELECT  @LogicalFileName = 'Your_log',  -- Use sp_helpfile to identify the logical file name that you want to shrink.
            @MaxMinutes = 10,               -- Limit on time allowed to wrap log.
            @NewSize = 100                  -- in MB
    
    -- Setup / initialize
    DECLARE @OriginalSize int
    SELECT @OriginalSize = size -- in 8K pages
      FROM sysfiles
      WHERE name = @LogicalFileName
    SELECT 'Original Size of ' + db_name() + ' LOG is ' + 
            CONVERT(VARCHAR(30),@OriginalSize) + ' 8K pages or ' + 
            CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + 'MB'
      FROM sysfiles
      WHERE name = @LogicalFileName
    CREATE TABLE DummyTrans
      (DummyColumn char (8000) not null)
    
    
    -- Wrap log and truncate it.
    DECLARE @Counter   INT,
            @StartTime DATETIME,
            @TruncLog  VARCHAR(255)
    SELECT  @StartTime = GETDATE(),
            @TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY'
    -- Try an initial shrink.
    DBCC SHRINKFILE (@LogicalFileName, @NewSize)
    EXEC (@TruncLog)
    -- Wrap the log if necessary.
    WHILE     @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) -- time has not expired
          AND @OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName)  -- the log has not shrunk    
          AND (@OriginalSize * 8 /1024) > @NewSize  -- The value passed in for new size is smaller than the current size.
      BEGIN -- Outer loop.
        SELECT @Counter = 0
        WHILE  ((@Counter < @OriginalSize / 16) AND (@Counter < 50000))
          BEGIN -- update
            INSERT DummyTrans VALUES ('Fill Log')  -- Because it is a char field it inserts 8000 bytes.
            DELETE DummyTrans
            SELECT @Counter = @Counter + 1
          END   -- update
        EXEC (@TruncLog)  -- See if a trunc of the log shrinks it.
      END   -- outer loop
    SELECT 'Final Size of ' + db_name() + ' LOG is ' +
            CONVERT(VARCHAR(30),size) + ' 8K pages or ' + 
            CONVERT(VARCHAR(30),(size*8/1024)) + 'MB'
      FROM sysfiles 
      WHERE name = @LogicalFileName
    DROP TABLE DummyTrans
    PRINT '*** Perform a full database backup ***'
    SET NOCOUNT OFF
    檢查記錄檔是否已經從原始大小進行壓縮。 如果有需要的話,請重複之前的步驟。如果記錄檔並未壓縮,請重新檢查文件最上方的摘要,查看是否遇到了壓縮記錄檔的常見問題。
在記錄檔壓縮後:
  1. 請執行主要資料庫的完整資料庫備份。
  2. 再執行使用者資料庫的完整資料庫備份。這是有必要的,因為除非完成完整的資料庫備份,否則 SHRINK 命令將不會有記錄,而未來的交易記錄檔備份將變成無效。
若要判斷記錄檔究竟為何變得如此之大,可以檢查開啟的交易、長時間執行的交易、未複製的交易,或碰觸很多資料的交易,以尋求原因。

參考



如需其他詳細資訊,請按一下下列的文件編號,參閱 Microsoft Knowledge Base 中的文件:
110139INF:SQL 交易記錄檔滿溢的原因
62866 INFO: Reasons Why SQL Transaction Log Is Not Being Truncated
66057 PRB: Running Out of Log Space When Running Large Bulk Loads
80629 PRB: Transaction Log Partially Truncated
SQL Server 線上叢書;主題:「交易記錄檔實體結構」;「提昇交易記錄檔效能」

?考

本文件是根據 Microsoft Knowledgebase 文件編號 Q256650 翻譯的. 若要參考原始英文文件內容, 請至以下網址:

http://support.microsoft.com/support/kb/articles/Q256/6/50.asp

屬性

文章編號: 256650 - 上次校閱: 2011年2月16日 - 版次: 1.1
關鍵字:?
kbsqldeveloper kbinfo kbsqlserv kbsqlserv700 KB256650
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com