用ORACLE8i修復數據庫壞塊的三種方法
2024-08-29 13:29:15
供稿:網友
 
 
在進行sun cluster雙機切換、意外斷電或其它情況下,有時會發生共享盤mount不上的情況,需要使用fsck對共享盤進行修復。修復完成后,在數據庫啟動過程中,卻又出現"數據塊損壞,無法啟動數據庫"的現象,此時,可以根據不同的數據塊損壞類型,檢測并修復錯誤。在此介紹三種使用oracle8i修復損壞數據塊的方法。 
一、數據塊損壞,錯誤代碼為ora-01578 
ora-1115 i/o error reading block 
通常后跟ora-737x錯誤與操作系統錯誤(如unix中的錯誤號5) 
產生原因: 
1. 硬件問題(磁盤控制器問題或磁盤問題) 
2. 物理級的數據塊損壞(通常由前一原因造成) 
3. 處理巨型文件時,后跟錯誤代碼ora-7371 
確定故障原因與恢復的方法: 
1. 查看alert.log文件中其它ora-1115錯誤的發生情況: 
1) 如果指向不同磁盤的文件,則是磁盤控制器的問題,查看v$datafile,有哪些文件位于該控制器下,轉到第二步。 
2) 如果指向相同磁盤的不同文件,則是磁盤的問題,轉到第二步。 
3) 如果指向同一個文件,執行以下語句查找文件名: 
select segment_name,segment_type from dba_extents where file_id=<文件號> and <塊號> between block_id 
and block_id+blocks-1;
其中,文件號與塊號是ora-1115中指出的,如果該查詢持續指向某表或索引,則重建它們即可。 
2. 如果文件是system表空間,或處于noarchivelog模式,關閉數據庫,轉到第四步。 
3. 如果數據庫處于archivelog模式,仍應關閉數據庫,如果不能關閉數據庫,則將相應的數據文件脫機:alter database datafile '文件名' offline; 
4. 試著將數據文件拷貝到別的磁盤。 
5. 如果拷貝失敗,則文件將丟失。 
6. startup mount; 
7. 將數據文件重命名為成功拷貝到別的磁盤的文件名: 
alter database rename file '老路徑文件名' to '新路徑文件名'; 
8. alter database open;
9. recover datafile 文件名; 
alter database datafile '文件名' online; 
二、回滾段需要恢復
如果回滾段處于need recovery狀態,需要執行以下步驟進行恢復: 
1. 查看所有聯機的表空間與數據文件 
2. 在init.ora文件中加入event = "10015 trace name context forever,level 10",這將生成一個追蹤文件,其中含有事務與回滾的信息。 
3. 關閉并重新打開數據庫。 
4. 查看trace文件,應有error recovery tx(#,#) object #.tx(#,#),指出事務信息,其中object #與sys.dba_objects中的object_id相同。 
5. 使用以下查詢找出正在進行恢復的對象: 
select owner,object_name,object_type,status from dba_objects where  object_id=<object #>; 
6. 必須刪除該對象以釋放回滾塊。 
三、檢測與修復損壞塊的常用方法:
(一)使用初始化參數db_block_checking與db_block_checksum。 
當塊改變時,db_block_checking對塊進行邏輯校驗。將防止發生10210 與10211錯誤。 
(二)使用dbms_repair包,由dbmsrpr.sql與prvtrpr.plb生成該包在特定表中生成損壞塊的信息。 
1.dbms_repair.admin_tables用于創建與刪除存儲損壞塊的表。其中table_type為:repair_table(表),orphan_table(索引);action為:create_action(創建表),purge_action(刪除無關數據),drop_action(刪除表)。例: 
dbms_repair.admin_tables('repair_table',dbms_repair.repair_table,dbms_repair.create_action,'temp_data'); 
2.dbms_repair.check_object檢查表、索引、分區中的塊損壞。其中object_type為:table_object(表),index_object(索引), repair_table_name(用于存儲損壞塊信息的表)。例: 
dbms_repair.check_object('oratrain','locations',corrupt_count=>:cc); 
3.使用以下語句查詢塊損壞信息: 
select object_name, relative_file_no, block_id, marked_corrupt, corrupt_description, repair_description from repair_table; 
4.將塊標志為損壞的:dbms_repair.fix_corrupt_blocks('oratrain','locations',fix_count=>:fc); 
5.跳過損壞塊:dbms_repair.skip_corrupt_blocks('oratrain', 'locations'); 
其中object_type為 :table_object(表),cluster_object(索引)。 
6.使用rebuild_freelists重建損壞的空閑列表:dbms_repair.rebuild_freelists 
7.使用以下方法查找指向損壞塊的索引: 
(1) 創建存放指向壞塊索引的表 
(2) dbms_repair.dump_orphan_keys('oratrain','loc_pk', 
orphan_table_name=>'orphan_tab1',key_count=>:kc); 
(3) select index_name, count(*) from orphan_key_table where table_name = 'classes' group by index_name; 
(4) 重建具有orphan keys的索引 
限制:不能分析index-organized tables 與 lob indexes,dump_orphan_keys不能對bitmap與 function-based indexes操作。 
(三)使用sql命令analyze table|index … validate structure 
utlvalid.sql.創建含有損壞塊信息的invalid_rows表,analyze table validate structure cascade同時校驗表與索引。 
(四)使用dbverify 
dbverify是一個外部工具,所以對數據庫影響很小??捎糜谠趯浞菸募截惢卦恢们皺z驗備份文件的完好性,并定位數據塊損壞。命令如下: 
dbv /opt/oracle/db02/oradata/data01.dbf start=1 end=500 logfile=dbv.log