SQLSERVERUndelete可能性探索(一)ClusteredTable

SQLSERVER中,如果數(shù)據(jù)被誤刪了,依照官方的說(shuō)法,SQLSERVER是沒(méi)有undelete的。要想救回被刪除的數(shù)據(jù),最典型的方法就是透過(guò)將備份檔還原成另一DB,將數(shù)據(jù)從另一DB找回來(lái)后,再新增回正式的DB。

創(chuàng)新互聯(lián)是專業(yè)的古塔網(wǎng)站建設(shè)公司,古塔接單;提供成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行古塔網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

不過(guò),如果對(duì)于SQLSERVER的transaction log結(jié)構(gòu)了解的人,只要交易紀(jì)錄還在,就可以透過(guò)解析交易紀(jì)錄來(lái)取得被刪除的數(shù)據(jù),再將數(shù)據(jù)Insert回DB。只是transaction log的解析有點(diǎn)復(fù)雜。這也是個(gè)值得探討且有趣的主題。如果可以,或許可以找時(shí)間來(lái)談?wù)勥@個(gè)。

其實(shí)還有一種方法….

SQLSERVER在執(zhí)行delete的時(shí)候,它并不是真正立即將數(shù)據(jù)從page中抹除。它只是先將它「標(biāo)記」為刪除,這時(shí)候從邏輯上來(lái)看是已刪除了(查不到了),但實(shí)際上數(shù)據(jù)還存在,這時(shí)我們稱此筆紀(jì)錄為 Ghost record。

注:

SQLSERVER的「標(biāo)記」刪除,在clustered table及heap table標(biāo)記方法是不一樣的。

真正的將數(shù)據(jù)清除(purge),是由GhostCleanuptask這支系統(tǒng)線程來(lái)做,它大約每5~10秒鐘會(huì)被喚醒一次,去真正地清除Ghost record。不過(guò),為避免造成系統(tǒng)忙碌,它每次只會(huì)檢查或清除有限數(shù)量的頁(yè)面(應(yīng)該是10 pages)。

所以從delete commit,到數(shù)據(jù)真正被清除。中間是有一個(gè)緩沖期的。

有了這樣的一個(gè)緩沖期,就給了我們一個(gè)可以Undelete的機(jī)會(huì)。

首先,最要緊的是,當(dāng)發(fā)生誤刪的時(shí)候,必需盡速執(zhí)行下列指令,停用Ghostcleanuptask。以免資料被真的清除。

dbcc traceon(661,-1)   --暫停Ghostcleanuptask

以下我們做一個(gè)簡(jiǎn)單的Undelete測(cè)試

Clustered Table undelete Testing

建立一個(gè)測(cè)試數(shù)據(jù)庫(kù),一并建立clustered index及non clustered index,并新增10筆數(shù)據(jù)

create database testghost

go

use testghost

go

create table testtbl(c1 int identity primary key,c2 int ,c3 varchar(10))

go

create index idx1 on testtbl(c2)

go

insert into testtbl values

(1,'aaaa'),(2,'aaaa'),(3,'aaaa'),(4,'aaaa'),(5,'aaaa'),

(6,'aaaa'),(7,'aaaa'),(8,'aaaa'),(9,'aaaa'),(10,'aaaa')

檢查該table的page情況

exec master.dbo.[GetPagRowCount] 'testghost','testtbl',-1

注:GetPagRowCount是我自寫(xiě)的proc,只是方便查閱各page的數(shù)據(jù),也可以用dbcc page去查.

SQL SERVER Undelete 可能性探索(一)Clustered Table

接著刪除 c1=5 的數(shù)據(jù)

delete from testtbl where c1=5

執(zhí)行select查詢,已經(jīng)查不到數(shù)據(jù)了

SQL SERVER Undelete 可能性探索(一)Clustered Table

假設(shè)C1=5為誤刪數(shù)據(jù),我們開(kāi)始做undelete...

暫停  Ghost cleanup task

dbcc traceon(661,-1)

使用procedure去檢查testtbl的page信息??梢钥吹?clustered頁(yè)面跟index頁(yè)面有Ghost record產(chǎn)生了。由于這里只有一筆Ghsot record,所以我們幾乎可以確定被誤刪的數(shù)據(jù)存放的位置為pageid 78,這也是要undelete的目標(biāo)頁(yè)面。(這樣的定位方式,可能會(huì)有不準(zhǔn)確的問(wèn)題,最好的方法是透過(guò)fn_dblog()去取得誤刪的PageID,再用這個(gè)procedure,兩者結(jié)果比對(duì),就不會(huì)錯(cuò)了)

SQL SERVER Undelete 可能性探索(一)Clustered Table

PageID確定后,接下來(lái)要確定出該筆數(shù)據(jù)所在的SlotID,

我們透過(guò)dbcc page,看它的實(shí)體紀(jì)錄,從record_type可以看出來(lái)。Slot 4是Ghost record

SQL SERVER Undelete 可能性探索(一)Clustered Table

至此我們可以確定 PageID 78,SlotID 4,是我們要Undelete的目標(biāo)。

這是一個(gè) Clustered table,它的標(biāo)記刪除的方法,是在那筆Row 的第一個(gè)byte中加入識(shí)別的bits,以標(biāo)記是Ghost record(heap table則不一樣)。

------------------------------------------------------------------------------------------------

Row的第一個(gè)Byte,由0開(kāi)始從右邊數(shù)來(lái)第1~3的位,換算成十進(jìn)制,代表的意義如下:

0(data record)

1(Forwarded record)

2(a forwarding stub)

3(Index record)

4(blob fragment or row overflow data)

5(ghost index record)

6(ghost data record)

7(ghost version record)

-------------------------------------------------------------------------------------------------

最后利用二進(jìn)制編輯器,去找到DB的PageID 78,SlotID 4,將第一個(gè)byte的Ghost record識(shí)別位(十進(jìn)制6),改成正常的數(shù)據(jù)位(十進(jìn)制0)。

改完之后,再次執(zhí)行select 查詢,資料已經(jīng)可以查詢的到了...

SQL SERVER Undelete 可能性探索(一)Clustered Table

我再檢查page信息,發(fā)現(xiàn)它仍然被標(biāo)示成Ghost record

SQL SERVER Undelete 可能性探索(一)Clustered Table

重建所有index...

alter index ALL on testtbl rebuild

再檢查page信息,已經(jīng)正常了

SQL SERVER Undelete 可能性探索(一)Clustered Table

不過(guò),這樣的改法會(huì)造成系統(tǒng)基底表的紀(jì)錄跟data page的紀(jì)錄不符,因此在執(zhí)行dbcc checktable時(shí)會(huì)有錯(cuò)誤。

整個(gè)Clustered Table Undelete的過(guò)程,最后必需執(zhí)行

dbcc checktable(testtbl,repair_allow_data_loss)

修復(fù)數(shù)據(jù)表,雖然是用repair_allow_data_loss但它不會(huì)造成數(shù)據(jù)漏失。

最后別忘了將flag 661關(guān)閉

dbcc traceoff(661,-1)

SQL SERVER Undelete 測(cè)試成功~~

以上的測(cè)試,主要在探索Undelete的可能性,這個(gè)測(cè)試證明了Undelete是可能的。不過(guò)要真正運(yùn)用在OLTP的作業(yè)環(huán)境上,還有一段路要走。(異動(dòng)量大、快速定位目標(biāo)pageid/slotid、Downtime的問(wèn)題)。

分享名稱:SQLSERVERUndelete可能性探索(一)ClusteredTable
瀏覽地址:http://bm7419.com/article8/jjdhip.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作自適應(yīng)網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、App開(kāi)發(fā)服務(wù)器托管、軟件開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)