誤刪 .ldf 交易記錄檔、記錄檔損壞或磁碟故障導致資料庫進入 SUSPECT(置疑)狀態,是 DBA 面臨的最高壓情境之一。本文整理兩套經實戰驗證的恢復方案:方案一「緊急模式 + 系統表修改」適用於輕度不一致;方案二「重建資料庫 + 單一檔案附加」適用於記錄檔完全遺失且資料檔完整。全程附帶 T-SQL 腳本與關鍵決策點說明。
EMERGENCY 模式:僅讀、單一使用者、繞過復原流程,允許 DBCC 修復與資料導出。sp_attach_single_file_db:僅以 MDF 建立資料庫,SQL Server 自動建立新的空白 LDF(原記錄內容永久遺失)。CREATE DATABASE [RecoverDB] ON PRIMARY (NAME='RecoverDB', FILENAME='D:\MSSQL\Data\RecoverDB.mdf') LOG ON (NAME='RecoverDB_Log', FILENAME='D:\MSSQL\Log\RecoverDB_Log.ldf');net stop MSSQLSERVER),不要 執行 sp_detach_db。USE master;
GO
EXEC sp_configure 'allow updates', 1; RECONFIGURE WITH OVERRIDE;
GO
UPDATE sysdatabases SET status = 32768 WHERE name = 'RecoverDB'; -- 32768 = EMERGENCY
GO
EXEC sp_dboption 'RecoverDB', 'single user', 'true';
GO
REPAIR_ALLOW_DATA_LOSS 為最後手段):DBCC CHECKDB ('RecoverDB') WITH NO_INFOMSGS, ALL_ERRORMSGS; -- 僅檢查
-- 若需修復(謹慎!可能遺失資料):
-- DBCC CHECKDB ('RecoverDB', REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS, ALL_ERRORMSGS;
GO
UPDATE sysdatabases SET status = 28 WHERE name = 'RecoverDB'; -- 28 = 正常
GO
EXEC sp_configure 'allow updates', 0; RECONFIGURE WITH OVERRIDE;
GO
EXEC sp_dboption 'RecoverDB', 'single user', 'false';
GO
SELECT * FROM RecoverDB..KeyTable 確認資料可讀。此法核心在於欺騙 SQL Server:以一個乾淨的同名資料庫為殼,植入原始 MDF,最後僅附加 MDF。
RecoverDB.mdf 移至備份資料夾(暫存)。USE master;
GO
EXEC sp_dboption 'RecoverDB', 'single user', 'true';
GO
EXEC sp_detach_db 'RecoverDB'; -- 分離(會保留 MDF)
GO
EXEC sp_attach_single_file_db @dbname = 'RecoverDB',
@physname = 'D:\MSSQL\Data\RecoverDB.mdf'; -- 僅附加 MDF,自動建新 LDF
GO
EXEC sp_dboption 'RecoverDB', 'single user', 'false';
GO
DBCC CHECKDB 並導出資料重建生產庫。| 條件 | 方案一 (EMERGENCY+REPAIR) | 方案二 (重建+單檔附加) |
|---|---|---|
| LDF 狀態 | 損壞但檔案存在 | 完全遺失或極度損壞 |
| 可容忍資料遺失 | 極低(REPAIR_ALLOW_DATA_LOSS 仍可能遺失) | 接受「未提交交易回滾」導致的邏輯不一致 |
| 業務停機窗口 | 較長(需 DBCC 修復時間) | 極短(秒級附加) |
| 後續維運 | 建議立即重建新庫導入 | 同上,新 LDF 無歷史記錄,建議重建 |
ALTER DATABASE [DB] SET PAGE_VERIFY CHECKSUM;「無日誌恢復」本質是以資料一致性換取可用性的妥協方案。唯有建立完善的備份策略與變更管理流程,才能從根本上消除此類風險。