oracle壞塊修復處理#ocp試驗#


壞塊分為物理壞塊和邏輯壞塊,前者是硬件問題產生,后者是oracle內部數據有問題,本次試驗針對后者。


需要歸檔模式,步驟

1 create tablespace test 1m (table t1, insert)
2 RMAN>backup tablespace test
3 模擬壞塊
4 DBV
5 ANALYZE TABLE
6 RMAN BACKUP
7 EXP
8 DBMS_REPAIR
9 BLOCKRECOVER

1,sys用戶下創建表空間

SYS@jsce>create tablespace tbs1 datafile 'e:\tbs1.dbf' size 1m; --大小1M,容易填滿(現在突然有疑惑:為什么要填滿,才能制造壞塊?)

在tbs1中創建表tb1,數據來源是scott.emp

SYS@jsce>create table tb1 tablespace tbs1 as select * from scott.emp;

雙倍遞增插入表tb1,來源也是其自己

SYS@jsce>insert into tb1 select * from tb1; --這里是select出來的東西插入到表,沒有關鍵字values

已創建15行。

SYS@jsce>insert into tb1 select * from tb1;

已創建30行。

SYS@jsce>insert into tb1 select * from tb1;

已創建60行。

 

 

 

在插滿之后,不要忘記commit,否則oracle不能shutdown,最后確認一下插入的數據量“15360”

》給表增加索引,后面查詢有壞塊之后,壞塊帶來損失的數據ORPHAN_TABLE;

SYS@jsce>create index i1 on tb1(ename);

索引已創建。

SYS@jsce>alter system checkpoint; --這一步是將插入的數據作檢查點寫入數據文件,下一步就要通過ultraedit修改數據文件,制造壞塊。

系統已更改。

備注:如果表字段沒有設置not null必輸項,並且表字段很多,那么可以指定字段來插入一部分,比如emp表

insert into emp(empno,ename,sal) values(22,'sumsen',8900);

2,rman備份表空間tbs1,得到優良備份(下面還原使用)

RMAN> backup tablespace tbs1 tag=ok;--增加tag

3,shutdown之后,通過ultraedit修改數據文件 --修改的時候不要開頭部,那里是數據文件名稱,有可能導致oracle啟動失敗

修改,保存之后,數據文件目錄會多出一個TBS1.DBF.bak,說明修改過了,不知道為何

啟動oracle再次查詢報錯,壞塊產生 --這里的select 是遇到第一個壞塊就報錯,因此如果有多個壞塊,也是報出一個錯誤信息,需要用下面的REPAIR_TABLE查詢所有的壞塊。

4,用dbv檢測

這里僅僅給出壞塊數,沒有給出壞塊號和文件號

5,使用 ANALYZE TABLE

SYS@jsce>analyze table tb1 validate structure;

6,rman的備份和exp導出有壞塊的表空間

exp導出sys下的

E:\Documents and Settings\xs>exp userid='sys/sys as sysdba' file=e:\exptbs1.dmp tablespaces=tbs1

導出表空間沒有問題 

導出表有壞塊報錯

rman提示超過壞塊限制

 

通過設置壞塊最大數來繼續備份

RMAN> run{set maxcorrupt for datafile 3 to 10;backup tablespace tbs1 tag=bad;} 要寫在一塊,讓rman知道是一個事務

因為最大壞塊設置為了10,tbs1有兩個壞塊,可以通過備份

7,包DBMS_REPAIR

exec DBMS_REPAIR.ADMIN_TABLES('REPAIR_TABLE',1,1,'USERS');--表數據

exec DBMS_REPAIR.ADMIN_TABLES('ORPHAN_TABLE',2,1,'USERS');--索引數據

檢查壞塊:dbms_repair.check_object , 這里的schema_name是用戶,比如我在sys下建立的表空間,這里就是sys,

object_name是表不是表空間(查詢的時候報錯也是通過select * from tb1)

declare
cc number;
begin
dbms_repair.check_object(schema_name => 'SYS',object_name => 'TB1',corrupt_count => cc); 
dbms_output.put_line(a => to_char(cc)); --這里a=>不明不白,可以去掉
end;


看到這里用dbms_repair.check,檢查的結果corrupt_count=2,有2個塊損壞,和dbv的結果一致。
check完之后,在我們剛在創建的REPAIR_TABLE中查看塊損壞詳細信息:
 

SELECT object_name,
       relative_file_id,
       block_id,
       marked_corrupt,
       corrupt_description,
       repair_description,
       CHECK_TIMESTAMP
  from repair_table;

得到4個結果,不過就兩個塊(33,69),只是時間不一樣,不解?

我們注意看MARKED_CORRUPT的值,這里經過check_object后,已經標識為TRUE了。(

》使用包的skip_corrupt_blocks過程來跳過壞塊

exec dbms_repair.skip_corrupt_blocks(schema_name => 'SYS',object_name => 'TB1',flags => 1);

損失了15360-15020=340 條數據

》處理index上的無效鍵值;dump_orphan_keys 

declare
cc number;
begin
dbms_repair.dump_orphan_keys(schema_name => 'SYS',object_name => 'I1',object_type => 2,
repair_table_name => 'REPAIR_TABLE',orphan_table_name => 'ORPHAN_TABLE',key_count => CC);
end;

之后查詢數據,我們根據這個結果來考慮是否需要rebuild index(?)

和上面的損失數目一樣

9  BLOCKRECOVER 恢復壞塊--前提是壞塊事先有備份

RMAN> blockrecover from tag=ok datafile 3 block 33,69;--必須要指定壞塊號

之后查詢tb1,恢復

這時候dbv檢測也為0

 

18:10 更新,使用oracle內部事件

再次破壞了數據文件,可是查詢時候仍然不報錯,想到是前面執行了讓oracle跳過壞塊的過程

exec dbms_repair.skip_corrupt_blocks(schema_name => 'SYS',object_name => 'TB1',flags => 1);

直接將flag=>2

SELECT tablespace_name, segment_type, owner, segment_name
FROM dba_extents
WHERE file_id = 3
and 35 between block_id AND block_id + blocks - 1 --這里 35 between不懂

ALTER SYSTEM SET EVENTS='10231 trace name context forever,level 10' ;

之后

SQL> ALTER SYSTEM SET EVENTS='10231 trace name context off' ;

系統已更改。

刪除表空間

SYS@jsce>drop tablespace tbs1 including contents and datafiles; --表空間物理文件也被刪除

之后導入

演示省略。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM