-- 1. 記錄備份
BACKUP LOG [DBName] TO DISK = 'D:\Backup\DBName_LOG_Tail.trn' WITH COMPRESSION, CHECKSUM;
-- 2. 縮減記錄檔至 500 MB (視實際負載調整)
DBCC SHRINKFILE ([DBName]_Log, 500);
-- 3. 檢查 VLF
DBCC LOGINFO ([DBName]);
-- 理想:VLF 數量 < 100,大小均勻 (如 512MB 檔案 → 16 個 32MB VLF)
ALTER DATABASE [DBName] SET RECOVERY SIMPLE;
-- CHECKPOINT 時自動截斷非作用中 VLF
-- 可搭配 DBCC SHRINKFILE 釋放空間
DBCC SHRINKFILE ([DBName]_Log, 100);
-- 生產庫切回完整模式並立即完整備份
ALTER DATABASE [DBName] SET RECOVERY FULL;
BACKUP DATABASE [DBName] TO DISK = '...' WITH INIT, COMPRESSION, CHECKSUM;
⚠️ 生產庫嚴禁長期保持 SIMPLE 模式,將失去時間點還原能力。
-- 一次預配足夠空間,避免頻繁自動成長 (預設 10% 會導致 VLF 碎片化)
ALTER DATABASE [DBName] MODIFY FILE (NAME = [DBName]_Log, SIZE = 4GB, FILEGROWTH = 512MB);
建議:FILEGROWTH 固定 MB (512MB~1GB),**禁止百分比成長**。
-- 每 15 分鐘
BACKUP LOG [DBName] TO DISK = 'D:\Backup\DBName_LOG_.trn'
WITH COMPRESSION, CHECKSUM, INIT;
-- 保留 48 小時檔案
-- 檢查 VLF 過多 (> 1000) 或過小 (< 1MB) 的資料庫
SELECT name, COUNT(*) AS VLF_Count,
AVG(size_mb) AS Avg_VLF_MB
FROM sys.databases d
CROSS APPLY sys.dm_db_log_info(d.database_id) li
GROUP BY name
HAVING COUNT(*) > 500 OR AVG(size_mb) < 10;
SELECT session_id, transaction_id, database_id,
DATEDIFF(SECOND, start_time, GETDATE()) AS DurationSec
FROM sys.dm_tran_active_transactions
WHERE DATEDIFF(SECOND, start_time, GETDATE()) > 300; -- 5 分鐘
| 誤區 | 後果 | 正確做法 |
|---|---|---|
| 定期排程 SHRINKFILE (每晚) | 記錄檔反覆成長/縮減 → VLF 碎片化 → 效能抖動 | 固定適當大小、僅在異常膨脹時一次性縮減 |
| 生產庫設 SIMPLE 模式省事 | 無法時間點還原、RPO = 上次完整備份 | 完整模式 + 定期記錄備份 |
| 直接刪除 LDF 檔案 | 資料遺失、資料庫損壞、違規 | 嚴禁 |
| SHRINKDATABASE (整庫縮減) | 資料檔也縮減 → 大量頁分裂、索引碎片 | 精準用 SHRINKFILE 針對記錄檔 |