資料庫壞塊處理

yantaicuiwei發表於2011-07-05
前不久維護的資料庫出現壞塊情況,由於磁碟陣列掉電造成資料庫無法啟動,接到任務以後首先進行了啟動,發現在mount至open階段時出現壞塊錯誤,進入alert log進行檢視,發現如下錯誤:

ORA-00604: error occurred at recursive SQL level 1
ORA-01578: ORACLE data block corrupted (file # 1024, block # 39177)
ORA-01110: data file 1: '/dev/rvsopsystem'
這個資料庫由於是屬於生產庫的IP段,但是在遇到故障時僅僅屬於待上線的狀態,也就是測試階段,也正是因為如此,不是歸檔模式,也沒有任何備份,但是這個資料庫已經在測試階段經歷了小半年,如果不能解決這個問題的話,將會造成開發人員這半年的幸苦工作化為泡影,這也意味這責任重大,因此網上隨意搜尋到的文章是不敢隨便進行嘗試的,要是因此使問題擴大就不好了。這個時候求助於support.oracle.com 是一個不錯的選擇,畢竟是交了錢的,不用浪費阿。
support.oracle.com 提交了SR,由於夠格,所以緊迫度是1級,因此印度佬回覆的速度還算不錯。剛開始印度佬一再表示,最好也最簡單最妥善的辦法就是restore 然後 recovery。但是沒有備份這條路肯定是走不通阿。於是我就詢問是否有其他內部的方式。第一個印度佬給了一種解決辦法 如下:
1.set ORACLE_SID
2.rman target / nocatalog
3.run {
allocate channel d1 type disk;
backup check logical validate database;
release channel d1;
}
4.Execute the script
create table segment_corrupted (owner varchar2(10), segment_name varchar2(50), segment_type varchar(20));
truncate table segment_corrupted;
set serveroutput on

declare
nrows number;
badsegs number;
begin
badsegs:=0;
nrows:=0;
for i in (select file#,block# from v$database_block_corruption) loop
begin
insert into segment_corrupted select owner, segment_name, segment_type from dba_extents where file_id=i.file# and i.block# between block_id and block_id + blocks -1;
end;
nrows:=nrows+1;
end loop;
commit;
if nrows>0 then
dbms_output.put_line('List of segments affected by corruption');
end if;
for i in (select distinct owner, segment_name, segment_type from segment_corrupted) loop
dbms_output.put_line(i.segment_type||' '||i.owner||'.'||i.segment_name);
badsegs:=badsegs+1;
end loop;
dbms_output.put_line('Total blocks corrupted: '||to_char(nrows)||'. Total segments affected: '||to_char(badsegs));
end;
/
5.select * from v$database_block_corruption;
但是因為資料庫無法open,因此第四步驟就無法進行下去了。
繼續問吧,印度佬換了一個人叫做Miguel 他給出瞭如下方法:
Please do the following:
1. Shutdown the instance
2. set the the following in the pfile
event="10513 trace name context forever, level 2"
3. startup restrict
4. Please find the object belonging the file block
SELECT tablespace_name, segment_type, owner, segment_name, partition_name FROM dba_extents WHERE file_id = 1 and 39177 between block_id AND block_id + blocks - 1;

2- Analyze the failing object
If the object is a table
ANALYZE TABLE . VALIDATE STRUCTURE CASCADE;
if that gives errors, please execute the following too:
ANALYZE TABLE . VALIDATE STRUCTURE;
可惜的是,還是在open時出現問題,無法open:
SQL> startup restrict
ORACLE instance started.

Total System Global Area 3.1457E+10 bytes
Fixed Size 2141552 bytes
Variable Size 3003122320 bytes
Database Buffers 2.8437E+10 bytes
Redo Buffers 14635008 bytes
Database mounted.
ORA-00604: error occurred at recursive SQL level 1
ORA-01578: ORACLE data block corrupted (file # 1024, block # 39177)
ORA-01110: data file 1: '/dev/rvsopsystem'
}
繼續反饋結果,印度佬以為我沒有設定10513 events,要求我提交alert log,於是我馬上upload alert log,這次回覆的人又換成了 Rodica ,貌似這個人經驗要豐富些。最後按照他給出的方式 成功open資料庫:
1. startup mount
2. alter system set events '10231 trace name context forever, level 10';
3. alter system set db_block_checking=medium;
4. alter database open
資料庫open之後,進行了檢查,發現只有system表空間出現了壞塊,其他的表空間都沒有問題,於是exp所有非oracle使用者的資料,問題告一段落。接下來想必大家也都知道,重新建一個庫 然後把資料匯入到新庫,刪除這個問題庫就可以了。至此問題得到解決。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21601207/viewspace-701374/,如需轉載,請註明出處,否則將追究法律責任。

相關文章