LDF 檔案暴增佔滿磁碟是常見營運災難。提供兩種清理法:**圖形介面收縮 (簡單、適合維護窗口)** 與 **T-SQL 手動截斷 (精確控制、無維護窗口)**。
優點:操作直觀、自動處理 VLF。
缺點:需切換復原模式、中斷記錄鏈、大 LDF 耗時久。
SET NOCOUNT ON;
DECLARE @LogicalFileName SYSNAME = 'YourDB_log', -- 邏輯檔名 (非物理路徑)
@MaxMinutes INT = 10, -- 最大允許包裝時間
@NewSizeMB INT = 100; -- 目標大小 (MB)
USE YourDB;
-- 1. 記錄原始大小
DECLARE @OriginalSize INT = (SELECT size FROM sys.database_files WHERE name = @LogicalFileName);
PRINT 'Original Log Size: ' + CAST(@OriginalSize * 8 / 1024.0 AS VARCHAR(20)) + ' MB';
-- 2. 建立虛擬表填充記錄強制包裝
CREATE TABLE #DummyTrans (DummyColumn CHAR(8000) NOT NULL);
DECLARE @Counter INT, @StartTime DATETIME = GETDATE();
DECLARE @TruncLog NVARCHAR(MAX) = 'BACKUP LOG [' + DB_NAME() + '] WITH TRUNCATE_ONLY'; -- 2008 以前
-- SQL 2008+ 簡單模式下用: BACKUP LOG [DB] WITH NO_LOG; (已移除)
-- 完整模式下必須先備份記錄再收縮
-- 3. 簡單模式下直接收縮
DBCC SHRINKFILE (@LogicalFileName, @NewSizeMB);
-- 4. 完整模式下: 備份記錄 → 收縮
-- BACKUP LOG YourDB TO DISK = 'NUL:'; -- 丟棄備份 (極度不推薦,僅緊急)
-- DBCC SHRINKFILE (@LogicalFileName, @NewSizeMB);
-- 5. 若未達目標,迴圈寫入虛擬資料強制 VLF 包裝
WHILE @MaxMinutes > DATEDIFF(MI, @StartTime, GETDATE())
AND @OriginalSize = (SELECT size FROM sys.database_files WHERE name = @LogicalFileName)
AND (@OriginalSize * 8 / 1024) > @NewSize
BEGIN
SET @Counter = 0;
WHILE @Counter < @OriginalSize / 16 AND @Counter < 50000
BEGIN
INSERT #DummyTrans VALUES ('Fill Log');
DELETE #DummyTrans;
SET @Counter += 1;
END
-- 簡單模式無需 BACKUP LOG TRUNCATE_ONLY
DBCC SHRINKFILE (@LogicalFileName, @NewSizeMB);
END
PRINT 'Final Log Size: ' + CAST((SELECT size FROM sys.database_files WHERE name = @LogicalFileName) * 8 / 1024.0 AS VARCHAR(20)) + ' MB';
DROP TABLE #DummyTrans;
SET NOCOUNT OFF;
| 版本 | 截斷指令 | 備註 |
|---|---|---|
| SQL 2000/2005 | BACKUP LOG db WITH TRUNCATE_ONLY | 已棄用 |
| SQL 2008+ | 簡單模式下自動截斷 / 完整模式需 BACKUP LOG TO DISK | TRUNCATE_ONLY/NO_LOG 已移除 |
DBCC LOGINFO,VLF > 1000 影響啟動/還原/備份速度DBCC OPENTRAN 找出 → KILL 或等待提交