資料庫崩潰是所有 DBA 的噩夢。本文將崩潰恢復分為四個層次:理想態(檔案完好)、標準備份還原、單一 MDF 附加、緊急模式強制重建,提供決策樹與逐步操作腳本,助您在災難中最大程度挽回數據。
崩潰發生
│
├─ 資料檔 + 記錄檔完好? → sp_attach_db 附加 → 完成
│
├─ 有可用備份(完整+差異+記錄)? → 還原鏈恢復 → 若活動記錄可讀 → 恢復到崩潰點
│
├─ 無備份/備份過舊,但 MDF 存在? → 嘗試 sp_attach_single_file_db
│ │
│ └─ 失敗? → 進入緊急模式重建記錄檔 (REBUILD_LOG)
│
└─ MDF 也遺失/損壞? → 尋求專業數據恢復服務 / 向老闆請辭
EXEC sp_attach_db 'MyDB',
'D:\Data\MyDB.mdf',
'D:\Log\MyDB_log.ldf';
或停止服務複製所有系統/使用者資料庫檔案到原路徑(不推薦,sp_attach_db 更安全)。
WITH NORECOVERY。WITH NORECOVERY。WITH NORECOVERY。BACKUP LOG ... WITH NORECOVERY,最後 RESTORE DATABASE ... WITH RECOVERY。前提:備份策略完善、備份檔案完整、記錄檔未損壞。
EXEC sp_attach_single_file_db 'MyDB', 'D:\Data\MyDB.mdf';
若資料庫近期執行過 CHECKPOINT,成功機率較高;否則進入層次四。
適用場景:無備份、無 LDF、MDF 存在但無法正常附加。
USE master; GO
EXEC sp_configure 'allow updates', 1; RECONFIGURE WITH OVERRIDE; GO
UPDATE sysdatabases SET status = 32768 WHERE name = 'MyDB';
狀態碼對照:32768 = EMERGENCY MODE(唯讀、置疑、離線、緊急)。
DBCC REBUILD_LOG('MyDB', 'D:\Log\MyDB_log.ldf');
成功訊息:警告: 資料庫 'MyDB' 的記錄已重建。已失去交易的一致性。應執行 DBCC CHECKDB...
若報 Msg 5030: 未能排它地鎖定資料庫,關閉所有連線(含 SSMS 物件瀏覽器)重試。
-- 重啟 SQL Server 服務
-- 設為單用戶模式
EXEC sp_dboption 'MyDB', 'single user', 'true';
-- 執行一致性檢查與修復
DBCC CHECKDB('MyDB');
-- 若有錯誤,依序嘗試
DBCC CHECKDB('MyDB', REPAIR_REBUILD);
DBCC CHECKDB('MyDB', REPAIR_ALLOW_DATA_LOSS); -- 最後手段,會遺失數據
-- 取得所有使用者資料表
SELECT name FROM sysobjects WHERE xtype = 'U' AND OBJECTPROPERTY(id, 'IsTable') = 1;
-- 對每張表執行
DBCC CHECKTABLE('table_name', REPAIR_ALLOW_DATA_LOSS);
-- 重建所有索引
DBCC DBREINDEX('MyDB'); -- 或逐表 ALTER INDEX ALL ON table REBUILD
-- 重新編譯預存程序
EXEC sp_recompile 'MyDB';
-- 設定正常狀態(28 為正常,或用 sp_resetstatus)
UPDATE sysdatabases SET status = 28 WHERE name = 'MyDB';
-- 或 EXEC sp_resetstatus 'MyDB';
EXEC sp_configure 'allow updates', 0; RECONFIGURE WITH OVERRIDE; GO
| 階段 | 可能遺失 | 業務影響 |
|---|---|---|
| REBUILD_LOG | 進行中交易、邏輯一致性 | 高 |
| REPAIR_ALLOW_DATA_LOSS | 損壞頁面上的數據行 | 中高 |
| CHECKTABLE 修復 | 索引不一致、統計資訊 | 低 |
DBCC CHECKDB 確認零錯誤。災難恢復的核心是備份策略的事前建立與分層恢復流程的事前演練。緊急模式 REBUILD_LOG 是最後防線,而非常規手段。請立即檢視您的備份保留週期、記錄備份頻率、異地備份可用性,並安排季度恢復演練——這才是 DBA 最大的價值所在。