[SQL][Troubleshooting]資料庫還原失敗的案例分享
這幾天剛好有個同事提供一個特別的案例,整個處理經驗有點特別,因此整理一下當成以後內部 DBA 訓練課程的案例分享。狀況是這樣的,某客戶 S 是使用 SQL Server 2005 Server Pack 3的環境,需要將既有的備份檔做還原,要用新的資料庫來做一些新功能的測試。但是資料庫就是沒有正常還原,原是就請同事 H 協助處理囉。於是我們按照客戶的方式,在有異常的環境上重新做了一次,出現以下的訊息:
於是當下我們就先透過以下兩個方式來進行處理:
- 使用 DBCC CHECKDB 檢查原有的資料庫
- 使用 RESTORE VERIFYONLY 檢查備份檔案
這兩個方式檢查都沒有任何異常,但該資料庫備份檔案不論在 SQL Server 2005, 2008 , 2008R2 , 2012 上,還原該資料庫的備份檔都會出現相同的錯誤訊息。因此我們決定利用手動下指令來看完整的錯誤訊息:
RESTORE DATABASE [Z] FROM DISK = N'D:\Temp\E.BAK' WITH FILE = 1,
MOVE N'E_Data' TO N'D:\Temp\Z.mdf',
MOVE N'E_Log' TO N'D:\Temp\Z.ldf'
GO
顯示訊息
已處理資料庫 'Z' 的 189280 頁,檔案 1 上的檔案 'Leader_Data'。
已處理資料庫 'Z' 的 2 頁,檔案 1 上的檔案 'Leader_Log'。
訊息 5074,層級 16,狀態 1,程序 sp_vupgrade_publisherdb,行 129
統計資料 'columns' 與 資料行 'columns' 相依。
訊息 4922,層級 16,狀態 9,程序 sp_vupgrade_publisherdb,行 129
ALTER TABLE DROP COLUMN columns 失敗,因為有一個或多個物件存取這個資料行。
訊息 3165,層級 16,狀態 1,行 1
資料庫 'Z' 已還原,不過在還原/移除複寫時發現錯誤。資料庫處於離線狀態。請參閱《SQL Server 線上叢書》中的主題 MSSQL_ENG003165。
訊息 3167,層級 16,狀態 1,行 1
RESTORE 無法啟動資料庫 'Z'。
訊息 3013,層級 16,狀態 1,行 1
RESTORE DATABASE 正在異常結束。
從上述的錯誤訊息中看起來就比較明朗一點了,至少可以得到幾個比較明確的資訊:
- 資料庫看起來在 RESTORE 的時候主要部分有完成,但是在後續進行一些 Stored Procedure 進行處理的時候才出問題的。
- 有問題的是因為有個 columns 的欄位要刪除的時候因為有統計資訊造成無法刪除。
- 從名稱上看起來應該是在檢查 Replication 相關的系統資料表上做調整才有的問題,此部分若資料庫沒有設定 Replication 的話,那麼應該影響不大。
既然這樣那就比較好處理了,於是進入 SSMS 重新 Refresh 後會看到資料庫 Z 的狀況是離線
於是在 Z 資料庫上按下滑鼠右鍵,選擇「工作」→「線上工作」,此時就可以將該資料庫給掛上了,但會是在「單一使用者」的模式,此時可以在 Z 資料庫上按下滑鼠右鍵,選擇「屬性」→「選項」→「限制存取」,更改成為「MULTI_USER」後,就可以暫時來使用了。
但是要如何解決問題呢 ? 從前面還原時候的錯誤訊息,我們可以得知是系統資料表的欄位統計資料所造成的問題,因此我們透過以下的指令來查一下到底問題是誰在誰的身上
select * from sys.tables t
join sys.columns c on t.object_id = c.object_id
where c.name = 'columns'
原來是 sysarticles 這個資料表的問題,而看起來當還原的時候是會去檢查是否有 columns 的欄位,要針對這個欄位去做刪除的處理,既然這樣,那我們就可以去原始的資料庫上面,將 columns 的統計資訊給刪除,可別去刪除欄位喔。於是再重新備份和還原,就不會有問題了。
後記:關於這個案例個人覺得有幾點可以跟大家分享一下
- 備份的時候要記得檢查,有些時候遇到一些朋友當資料庫有異常的時候,當去找備份檔的時候才發覺備份是壞掉或者是沒有完成的,那就真的是悲劇了。
- 當還原失敗的時候不要急的刪除,否則你可以只是刪除了設定,但並沒有實際把還原產生的檔案給刪除。
- 不要太依賴 SSMS,很多時候透過 SSMS 是可以讓我們管理上很方便,但有些時候會把一些重要的訊息給隱藏了,因此能多了解一些指令和系統資料表會對管理資料庫有不少的幫助。