資料庫修復是 DBA 面對介質故障、邏輯錯誤、惡意破壞時的核心技能。本文系統闡述 SQL Server 環境下的三大修復體系:自動重做日誌應用、非歸檔模式 (Simple Recovery) 介質恢復、時間點還原,並提供標準化操作腳本與決策流程圖。
發現資料庫損壞/數據遺失
│
▼
評估復原模式: FULL / BULK_LOGGED / SIMPLE
│
├── FULL / BULK_LOGGED ──→ 是否有完整備份鏈 + 記錄備份鏈 完整?
│ ├─ 是 ──→ 時間點還原 (Point-in-Time Recovery) [首選]
│ └─ 否 ──→ 檢查尾部記錄備份 → 可能需容忍數據遺失
│
└── SIMPLE ──→ 僅能恢復至最近一次完整/差異備份點
(無記錄備份,無法時間點還原)
前提:資料庫檔案完好,僅需將交易記錄重放至一致性狀態
-- 1. 啟動實例並掛載資料庫 (不復原)
STARTUP MOUNT; -- 實際對應: RESTORE DATABASE [DB] WITH NORECOVERY;
-- 2. 啟用自動重做日誌應用
SET AUTORECOVERY ON; -- 實際對應: 資料庫屬性 → 選項 → 自動關閉/自動收縮 相關設定
-- 3. 執行恢復 (重放所有記錄至最新)
RECOVER DATABASE; -- 實際對應: RESTORE DATABASE [DB] WITH RECOVERY;
-- 4. 開啟資料庫供存取
ALTER DATABASE [DB] SET ONLINE; -- 隱含在 WITH RECOVERY 中
STARTUP MOUNT;
RECOVER AUTOMATIC DATABASE; -- 等同於 SET AUTORECOVERY ON + RECOVER DATABASE
ALTER DATABASE [DB] SET ONLINE;
-- 完整恢復流程:完整備份 → 差異備份 → 記錄備份鏈 → 目標時間點
RESTORE DATABASE [TargetDB]
FROM DISK = 'D:\Backup\TargetDB_Full.bak'
WITH NORECOVERY, REPLACE, STATS=5; -- 完整備份
RESTORE DATABASE [TargetDB]
FROM DISK = 'D:\Backup\TargetDB_Diff.bak'
WITH NORECOVERY, STATS=5; -- 最新差異備份 (可選)
RESTORE LOG [TargetDB]
FROM DISK = 'D:\Backup\TargetDB_Log_1.trn'
WITH NORECOVERY, STATS=5; -- 記錄備份 1
RESTORE LOG [TargetDB]
FROM DISK = 'D:\Backup\TargetDB_Log_2.trn'
WITH NORECOVERY, STATS=5; -- 記錄備份 2
-- ... 依序應用所有記錄備份 ...
RESTORE LOG [TargetDB]
FROM DISK = 'D:\Backup\TargetDB_Log_Tail.trn' -- 尾部記錄備份 (關鍵!)
WITH RECOVERY, STOPAT = '2024-01-15 14:30:00', STATS=5; -- 時間點還原
特點:無記錄備份,記錄自動截斷,僅能恢復至備份時間點,RPO = 備份間隔
-- 1. 關閉資料庫 (若仍在線)
ALTER DATABASE [TargetDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
-- 2. 從備份還原 (覆蓋現有檔案)
RESTORE DATABASE [TargetDB]
FROM DISK = 'D:\Backup\TargetDB_Full.bak'
WITH REPLACE, RECOVERY, STATS=5;
-- RECOVERY 參數直接完成重做/回滾並上線
-- 1. 關閉資料庫
ALTER DATABASE [TargetDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
-- 2. 還原至新路徑 (使用 MOVE 指定新檔案位置)
RESTORE DATABASE [TargetDB]
FROM DISK = 'D:\Backup\TargetDB_Full.bak'
WITH REPLACE, RECOVERY, STATS=5,
MOVE 'TargetDB_Data' TO 'E:\NewData\TargetDB.mdf',
MOVE 'TargetDB_Log' TO 'F:\NewLog\TargetDB_Log.ldf';
-- 3. 驗證
DBCC CHECKDB([TargetDB]) WITH NO_INFOMSGS, ALL_ERRORMSGS;
-- 1. 識別損壞頁面 (來自 DBCC CHECKDB 或 錯誤日誌 823/824/825)
-- 假設 FileID=1, PageID=12345 和 FileID=1, PageID=12346 損壞
-- 2. 執行頁面恢復 (Enterprise 版專屬)
RESTORE DATABASE [TargetDB]
PAGE = '1:12345', '1:12346'
FROM DISK = 'D:\Backup\TargetDB_Full.bak'
WITH NORECOVERY;
-- 3. 應用後續記錄備份至最新
RESTORE LOG [TargetDB] FROM DISK = '...' WITH NORECOVERY;
-- ... 所有記錄備份 ...
-- 4. 完成恢復
RESTORE LOG [TargetDB] FROM DISK = '...Tail.trn' WITH RECOVERY;
-- 假設次要檔案群組 FG_Archive 受損,主檔案群組 PRIMARY 正常
RESTORE DATABASE [TargetDB] FILEGROUP = 'FG_Archive'
FROM DISK = 'D:\Backup\TargetDB_FG_Archive.bak'
WITH NORECOVERY;
RESTORE LOG [TargetDB] FROM DISK = '...' WITH NORECOVERY;
-- ... 應用記錄至最新 ...
RESTORE LOG [TargetDB] FROM DISK = '...Tail.trn' WITH RECOVERY;
-- 期間 PRIMARY 檔案群組保持 ONLINE 可存取
| 驗證項目 | 執行指令 | 合格標準 |
|---|---|---|
| 邏輯一致性 | DBCC CHECKDB([TargetDB]) WITH NO_INFOMSGS, ALL_ERRORMSGS; | 無錯誤訊息 |
| 業務關鍵數據 | 核心表行數、關鍵欄位 SUM/COUNT 對比備份前基準 | 差異在可接受範圍 (如 <0.01%) |
| 應用連通性 | 應用服務啟動、健康檢查端點、關鍵 API 冒煙測試 | 全部通過 |
| 備份鏈完整性 | RESTORE VERIFYONLY FROM DISK = '最新完整備份'; RESTORE HEADERONLY | 校驗和正確、LSN 鏈連續 |
| 效能基線 | 關鍵查詢執行時間、等待統計 (sys.dm_os_wait_stats) | 無明顯退化 (<10%) |
BACKUP LOG [DB] TO DISK = '..._Tail.trn' WITH NORECOVERY;SELECT * FROM sys.master_files WHERE database_id = DB_ID('TargetDB') 確認檔案路徑。WITH PARTIAL。DBA 鐵律:「備份未測試,等於沒備份;修復未演練,等於不會修。」每季度必須在非生產環境完整演練:完整恢復、時間點恢復、頁面恢復、檔案群組恢復,記錄 RTO 實測值並優化流程。