SQL Server2000中,如果數(shù)據(jù)庫(kù)文件(非系統(tǒng)數(shù)據(jù)庫(kù)文件)遇到錯(cuò)誤的時(shí)候,我們?cè)撛趺崔k。以下是筆者以前的筆記。僅適用于非master,msdb的數(shù)據(jù)庫(kù)。
說(shuō)明如下:
1 建一個(gè)測(cè)試數(shù)據(jù)庫(kù)test(數(shù)據(jù)庫(kù)類型為完全)
2 建一個(gè)表,插入點(diǎn)記錄
create table a(c1 varchar(2))
go
insert into a values(#39;aa#39;)
go
insert into a values(#39;bb#39;)
go
3 作完全備份,到文件test_1.bak
4 在作一點(diǎn)修改
insert into a values(#39;cc#39;)
go
create table b(c1 int)
go
insert into b values(1)
go
insert into b values(2)
go
5 shutdown 數(shù)據(jù)庫(kù)服務(wù)器
6 用ultraedit編輯數(shù)據(jù)庫(kù)文件test_data.mdf,隨便修改點(diǎn)字節(jié)內(nèi)容,相當(dāng)于數(shù)據(jù)庫(kù)遭到致命的損壞。
7 啟動(dòng)數(shù)據(jù)庫(kù),并且運(yùn)行企業(yè)管理器,點(diǎn)開(kāi)數(shù)據(jù)庫(kù),看到test變成灰色,而且顯示置疑。
8 運(yùn)行isql -SLocalhost -Usa -P
1> backup log test TO DISK=#39;D:Program FilesMicrosoft SQL ServerMSSQLBACKUP
est_2.bak#39; WITH NO_TRUNCATE
2>go
已處理 2 頁(yè),這些頁(yè)屬于數(shù)據(jù)庫(kù) #39;test#39; 的文件 #39;TEST_Log#39;(位于文件 1 上)。
BACKUP LOG 操作成功地處理了 2 頁(yè),花費(fèi)了 0.111 秒(0.087 MB/秒)。
9 進(jìn)行恢復(fù)最老的完全備份
1> RESTORE DATABASE test FROM DISK=#39;D:Program FilesMicrosoft SQL ServerMSSQL
BACKUP est_1.bak#39; WITH NORECOVERY
2> go
已處理 96 頁(yè),這些頁(yè)屬于數(shù)據(jù)庫(kù) #39;test#39; 的文件 #39;TEST_Data#39;(位于文件 1 上)。
已處理 1 頁(yè),這些頁(yè)屬于數(shù)據(jù)庫(kù) #39;test#39; 的文件 #39;TEST_Log#39;(位于文件 1 上)。
RESTORE DATABASE 操作成功地處理了 97 頁(yè),花費(fèi)了 0.107 秒(7.368 MB/秒)。
10 恢復(fù)最近的日志
1> RESTORE LOG test FROM DISK=#39;D:Program FilesMicrosoft SQL ServerMSSQLBACKU
P est_2.bak#39; WITH RECOVERY
2> go
已處理 2 頁(yè),這些頁(yè)屬于數(shù)據(jù)庫(kù) #39;test#39; 的文件 #39;TEST_Log#39;(位于文件 1 上)。
RESTORE LOG 操作成功地處理了 2 頁(yè),花費(fèi)了 0.056 秒(0.173 MB/秒)。
數(shù)據(jù)已經(jīng)完全恢復(fù)了,可以使用了。
select * from a
go
總結(jié),DBA應(yīng)該有一個(gè)完善的數(shù)據(jù)庫(kù)備份計(jì)劃。本例中,如果沒(méi)有一個(gè)完全備份的話,數(shù)據(jù)庫(kù)的恢復(fù)就不可能
當(dāng)sql server數(shù)據(jù)庫(kù)崩潰時(shí)如何恢復(fù)?
任何數(shù)據(jù)庫(kù)系統(tǒng)都無(wú)法避免崩潰的狀況,即使你使用了clustered,雙機(jī)熱備……仍然無(wú)法完全根除系統(tǒng)中的單點(diǎn)故障,何況對(duì)于大部分用戶來(lái)說(shuō),無(wú)法承受這樣昂貴的硬件投資。所以,在系統(tǒng)崩潰的時(shí)候,如何恢復(fù)原有的寶貴數(shù)據(jù)就成為一個(gè)極其重要的問(wèn)題了。
在恢復(fù)的時(shí)候,最理想的情況就是你的數(shù)據(jù)文件和日志文件都完好無(wú)損了,這樣只需要sp_attach_db,把數(shù)據(jù)文件附加到新的數(shù)據(jù)庫(kù)上即可,或者在停機(jī)的時(shí)候把所有數(shù)據(jù)文件(一定要有master等)都copy到原有路徑下也行,不過(guò)一般不推薦這樣的做法,sp_attach_db比較好,雖然麻煩許多。
但是呢,一般數(shù)據(jù)庫(kù)崩潰的時(shí)候系統(tǒng)是未必能有時(shí)間把未完成的事務(wù)和臟頁(yè)等寫(xiě)入磁盤(pán)的,這樣的情況sp_attach_db就會(huì)失敗。那么,寄期望于dba制定了一個(gè)良好的災(zāi)難恢復(fù)計(jì)劃吧。按照你的恢復(fù)計(jì)劃,還原最新的完全備份,增量備份或者事務(wù)日志備份,然后如果你的活動(dòng)事務(wù)日志還能讀得出來(lái)的話,恭喜你!你可以還原到崩潰前的狀態(tài)。
一般的單位都是沒(méi)有專職的dba的,如果沒(méi)有可用的備份,更可能是最近一次備份的時(shí)間過(guò)于久遠(yuǎn)而導(dǎo)致不可接受的數(shù)據(jù)損失,而且你的活動(dòng)事務(wù)日志也處于不可用的狀態(tài),那就是最麻煩的情況了。
不幸的很的是,一般數(shù)據(jù)庫(kù)崩潰都是由于存儲(chǔ)子系統(tǒng)引起的,而這樣的情況是幾乎不可能有可用的日志用于恢復(fù)的。那么就只好試一下這些方案了。當(dāng)然,是要求至少你的數(shù)據(jù)文件是存在的,要是數(shù)據(jù)文件、日志文件和備份都沒(méi)有了的話,別找我,你可以到樓頂上去唱“神啊,救救我吧”。
首先,你可以試一下sp_attach_single_file_db,試著恢復(fù)一下你的數(shù)據(jù)文件,雖然能恢復(fù)的可能性不大,不過(guò)假如這個(gè)數(shù)據(jù)庫(kù)剛好執(zhí)行了一個(gè)checkpoint的話,還是有可能成功的。
如果你沒(méi)有好到有摸彩票的手氣,最重要的數(shù)據(jù)庫(kù)沒(méi)有像你期盼的那樣attach上去,不要?dú)怵H,還是有別的方案的。
我們可以試著重新建立一個(gè)log,先把數(shù)據(jù)庫(kù)設(shè)置為emergency mode,sysdatabases的status為32768 就表示數(shù)據(jù)庫(kù)處于此狀態(tài)。
不過(guò)系統(tǒng)表是不能隨便改的,設(shè)置一下先
use master
go
sp_configure #39;allow updates#39;, 1
reconfigure with override
go
然后
update sysdatabases set status = 32768 where name = #39;#39;
現(xiàn)在,祈求滿天神佛的保佑吧,重新建立一個(gè)log文件。成功的機(jī)會(huì)還是相當(dāng)大的,系統(tǒng)一般都會(huì)認(rèn)可你新建立的日志。如果沒(méi)有報(bào)告什么錯(cuò)誤,現(xiàn)在就可以松一口氣了。
雖然數(shù)據(jù)是恢復(fù)了,可是別以為事情就算完成了,正在進(jìn)行的事務(wù)肯定是丟失了,原來(lái)的數(shù)據(jù)也可能受到一些損壞。
先把sql server 重新啟動(dòng)一下,然后檢查你的數(shù)據(jù)庫(kù)吧。
先設(shè)置成單用戶模式,然后做dbcc
sp_dboption #39;#39;, #39;single user#39;, #39;true#39;
dbcc checkdb(#39;#39;)
如果沒(méi)有什么大問(wèn)題就可以把數(shù)據(jù)庫(kù)狀態(tài)改回去了,記得別忘了把系統(tǒng)表的修改選項(xiàng)關(guān)掉。
update sysdatabases set status = 28 where name = #39;#39; --當(dāng)然你的數(shù)據(jù)庫(kù)狀態(tài)可能不是這個(gè),自己改為合適的值吧。也可以用sp_resetstatus
go
sp_configure #39;allow updates#39;, 0
reconfigure with override
go
checkdb的時(shí)候可能報(bào)告有一些錯(cuò)誤,這些錯(cuò)誤的數(shù)據(jù)你可能就只好丟棄了。
checkdb有幾種修復(fù)選項(xiàng),自己看著用吧,不過(guò)最后你可能還是得用repair_allow_data_loss,完成所有修復(fù)。
chekcdb并不能完成所有的修復(fù),我們需要更進(jìn)一步的修復(fù),用dbcc checktable對(duì)每一個(gè)表做檢查吧。
表的列表可以用sysobjects里面得到,把objectproperty是istable的全部找出來(lái)檢查一下吧,這樣能夠基本上解決問(wèn)題了,如果還報(bào)告錯(cuò)誤,試著把數(shù)據(jù)select into到另一張表檢查一下。
這些都做完了之后,把所有索引、視圖、存儲(chǔ)過(guò)程、觸發(fā)器等重新建立一下。dbcc dbreindex也許可以幫你一些忙。
數(shù)據(jù)庫(kù)日志文件丟失時(shí)的恢復(fù)步驟,描述我誤刪除了數(shù)據(jù)庫(kù)的事務(wù)日志文件(.ldf)之后,如何經(jīng)過(guò)各種嘗試恢復(fù)數(shù)據(jù)庫(kù)的。
但是不少網(wǎng)友在處理“數(shù)據(jù)庫(kù)置疑”的實(shí)踐過(guò)程中,又產(chǎn)生了許多新的疑問(wèn)。
我還是總結(jié)一下出現(xiàn)的幾種情況,以供參考。
2.Zach的靈驗(yàn)?zāi)_本
Zach說(shuō)他每次遇到這種數(shù)據(jù)庫(kù)置疑情況,就運(yùn)行下面這個(gè)腳本,屢試不爽:
======================================================
--before running any script, run the following to set the
master database to allow updates
USE master
GO
sp_configure #39;allow updates#39;, 1
GO
RECONFIGURE WITH OVERRIDE
GO
--Run the following script
UPDATE master..sysdatabases SET status = status ^ 256
WHERE name = #39;Database_Name#39;
--Run the following script
exec SP_resetstatus Database_Name
--stop and start the MSDTC at this stage
--After the procedure is created, immediately disable
updates to the system tables:
exec sp_configure #39;allow updates#39;, 0
GO
RECONFIGURE WITH OVERRIDE
GO
=====================================
從上面可以看出,處理置疑的基本步驟還是我那篇文章中說(shuō)的(注意我使用的字體顏色):
執(zhí)行 sp_configure 以允許對(duì)系統(tǒng)表進(jìn)行更新,然后用 RECONFIGURE WITH OVERRIDE 語(yǔ)句強(qiáng)制實(shí)施該配置;
數(shù)據(jù)庫(kù)重置緊急模式;
執(zhí)行sp_resetstatus關(guān)閉數(shù)據(jù)庫(kù)的置疑標(biāo)志,但是原封不動(dòng)地保持?jǐn)?shù)據(jù)庫(kù)的其它選項(xiàng)(只有系統(tǒng)管理員才能執(zhí)行)。執(zhí)行該過(guò)程后,立即重啟 SQL Server服務(wù);
執(zhí)行 sp_configure 以禁止對(duì)系統(tǒng)表進(jìn)行更新,然后用 RECONFIGURE WITH OVERRIDE 語(yǔ)句強(qiáng)制實(shí)施該配置。
status ^ 256的意思就是:
Constant Value Description
SQLDMODBStat_Suspect 256 Database integrity is suspect for the referenced database.
不同的是,有時(shí)候丟失了數(shù)據(jù)庫(kù)日志文件,額外需要以下步驟:
把應(yīng)用數(shù)據(jù)庫(kù)設(shè)置為Single User模式;
做DBCC CHECKDB;
才可以。
但是幾位網(wǎng)友的實(shí)踐結(jié)果就是這個(gè)DBCC CHECKDB執(zhí)行失敗。一位網(wǎng)友yang說(shuō):“但是 DBCC CHECKDB就是執(zhí)行不了,總是說(shuō)“該數(shù)據(jù)庫(kù)處于回避恢復(fù)模式”。我已經(jīng)試了很多次了,就是改變不了這個(gè)狀態(tài)。”
還有一位Rui執(zhí)行DBCC CHECKDB時(shí)報(bào)錯(cuò):“Server: Msg 943, Level 14, State 1, Line 1 Database #39;his_yb#39; cannot be opened because its version (539) is later than the current server version (515).”
對(duì)于Yang,可能他沒(méi)有一步一步做,。我的切身體會(huì)是,把應(yīng)用數(shù)據(jù)庫(kù)設(shè)置為Single User模式后就可以做DBCC CHECKDB。之后呢,也許SQL Server重啟后自動(dòng)檢查數(shù)據(jù)庫(kù)是否正常。但是數(shù)據(jù)應(yīng)該是可以讀出來(lái)的,至少可以被DTS Wizard讀出來(lái)的。這時(shí)候的數(shù)據(jù)庫(kù)還存在問(wèn)題,比如我的組件使用數(shù)據(jù)庫(kù)時(shí),報(bào)告說(shuō):“發(fā)生錯(cuò)誤:-2147467259,未能在數(shù)據(jù)庫(kù) #39;XXX#39; 中運(yùn)行 BEGIN TRANSACTION,因?yàn)樵摂?shù)據(jù)庫(kù)處于回避恢復(fù)模式?!?/P>
對(duì)于Rui,他碰到的那個(gè)錯(cuò)誤
Server: Msg 943, Level 14, State 1, Line 2
Database #39;XXXX#39; cannot be opened because its version (536) is later than
the current server version (515).
這表明Rui正試圖:
從一個(gè)SQL Server 2000(version 539,536之類的)的數(shù)據(jù)庫(kù)備份恢復(fù)到一個(gè)SQL Server 7.0中
或者
把一個(gè)SQL Server 2000(version 539,536之類的)的數(shù)據(jù)庫(kù)attach到一個(gè)SQL Server 7.0中,
這是不允許的。如果你必須使用這個(gè)SQL Server 2000的數(shù)據(jù)備份,那么請(qǐng)您首先把這個(gè)備份倒入SQL Server 2000,最后用DTS把數(shù)據(jù)庫(kù)從SQL Server 2000上transfer到SQL Server 7.0上。
您可能感興趣的文章:- 修復(fù)斷電等損壞的SQL 數(shù)據(jù)庫(kù)
- 快速修復(fù)損壞的MySQL數(shù)據(jù)庫(kù)
- MySQL數(shù)據(jù)庫(kù)INNODB表?yè)p壞修復(fù)處理過(guò)程分享
- mysql數(shù)據(jù)庫(kù)索引損壞及修復(fù)經(jīng)驗(yàn)分享
- master數(shù)據(jù)庫(kù)損壞的解決辦法有哪些