一個簡單易用的資料庫壞塊處理方案

qing_yun發表於2024-03-01

資料庫出現壞塊在我幹DBA的時候是常見的事情,處理各種各樣壞塊的案例可能經歷過上百個。很多情況下壞塊問題可透過資料庫恢復來完成,像Oracle早就支援塊級恢復,因此現在Oracle出壞塊,只要有備份,透過塊級恢復就可以了。如果有ADG那就更簡單了,透過ADG的檔案恢復就可以了。

今天介紹的一個方法不僅可以在Oracle資料庫上使用,也可以用於其他資料庫。當資料庫缺少可用備份或者不支援塊級恢復,一張表出現一個壞塊要恢復整個資料庫比較麻煩的場景。處理方法比較簡單,就是跳過壞的資料,把其他資料寫入一張臨時性的表,然後將存在壞塊的表rename成old表,再把臨時性的表rename成生產表就可以了。下面我們看這個案例。

因為某種不可言狀的問題,使用者的某張十分重要的表出現了訪問問題。訪問這張表的應用報錯ORA-08103。透過客戶端去訪問這張表也是報同樣的錯誤。

在該表的某個extent中,高水位下有個BLOCK對應的type是錯誤的,當對該表進行掃描或者訪問到某個記錄的時候,訪問到這種塊就會出現ORA-8103報錯,操作無法正常進行。如果存在這種形式的壞塊,無法對錶進行全表掃描,也無法將該表exp出來。

透過對該表的檢查,發現壞塊的rdba是:72/13283,檢查結果如下:

這個壞塊中共有13條記錄,當訪問到這13條記錄的時候就會出現ORA-8103錯誤。遇到這種問題,簡單地透過dbms_repair去修復壞塊是不行的,因為ORA-8103說明在高水位下遇到了一個rdba上看不輸於這個段的塊。透過bbed修改rdba後再來做repair是可行的,不過對於DBA的要求比較高。實際上遇到這樣的問題其實有一種十分通用的簡單解決方法,這個方法不僅對Oracle資料庫有效,對大多數開源國產資料庫同樣有效。該方案有以下幾個步驟:

1)首先建立一張表結構完全一致的表,比如new_temp表。

2)建立一張儲存損壞行行號的臨時表

3)找到一個該表的包含所有行的索引,比如主鍵或者非空欄位上的索引,只要是能包含所有資料行就可以了。如果不存在這樣的索引,那麼就會稍微麻煩一些,要找到一種能夠按照行遍歷整個表的方法。

4)編寫一個儲存過程或者JAVA/PYTHON等程式來完成資料匯出。

set serveroutput on

declare

nrows number;

badrows number;

VYHDABH VARCHAR2(50);

VFGSBH VARCHAR2(50);

VJBH VARCHAR2(50);

begin

badrows:=0;

nrows:=0;

for i in (select /*+ index (tab1) */ rowid,FGSBH from 有故障的表 tab1) loop

begin

insert into newtb select *

from 有故障的表 where rowid=i.rowid;

if (mod(nrows,20000)=0) then

commit;

end if;

exception when others then

badrows:=badrows+1;

//找到所有的該表的索引,儘可能把能找到的列資料都找出來

//寫入BADROWS表裡,儘可能多地恢復資料

select /*+ index(a YH_DNB_IND_2) */ yhdabh,FGSBH,JBH

into VYHDABH,VFGSBH,VJBH

from ld_data.yh_dnb a

where rowid=i.rowid;

insert into bad_rows values (i.Rowid,VFGSBH,VYHDABH,VJBH);

commit;

end;

nrows:=nrows+1;

end loop;

dbms_output.put_line('Total rows: '||to_char(nrows)||' Bad rows: '||to_char(badrows));

Commit;

end;

/

5)將原表rename 為Old

6)將臨時表rename為原表

7)給新表新增索引與授權

在上面的這個案例中,這個壞塊中一共存在13條記錄,把這十三條記錄的使用者檔案號也都找到了,於是恢復後只需要補錄這十三條記錄,整個資料就恢復了。

這個方法可以使用於其他資料庫上,特別是段頁式儲存結構的資料庫,比如達夢、神通Oscar等。PostgreSQL資料庫有一個引數:zero_damaged_pages,用它可以跳過壞塊遍歷某張表。透過這個把資料匯出到一張新表裡。不過這種方式把壞塊中的行全部丟棄了,對於關鍵業務資料來說存在資料丟失的風險。為了儘可能多的匯出資料,可以再輔以上面的方法,透過適當的索引掃描,把壞塊中的資料行找出來,把恢復工作做得更加完善。

來自 “ 白鱔的洞穴 ”, 原文作者:白鱔;原文連結:https://mp.weixin.qq.com/s/VamEnFYe8DjXQxCJhQgsRg,如有侵權,請聯絡管理員刪除。

相關文章