Oracle壞塊故障葵花寶典_第1頁
Oracle壞塊故障葵花寶典_第2頁
Oracle壞塊故障葵花寶典_第3頁
Oracle壞塊故障葵花寶典_第4頁
Oracle壞塊故障葵花寶典_第5頁
已閱讀5頁,還剩62頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、 PAGE 67Oracle壞塊故障總結 最近處理了兩次典型的ora-01578,ora-01115,ora-01110故障,一次是平湖索引塊壞,一次是黃山數據文件壞、blob數據塊壞。平湖的警告日志文件中有以下信息:ORA-12012: error on auto execute of job 21ORA-01578: ORACLE data block corrupted (file # 10, block # 2558610)ORA-01110: data file 10: D:ORACLEORADATABSUSERS04.DBFORA-12012: error on auto exec

2、ute of job 1ORA-01578: ORACLE data block corrupted (file # 16, block # 2624066)ORA-01110: data file 16: D:ORACLEORADATABSUSERS10.DBF應用軟件可以正常使用,偶爾會報錯ora-01578。排錯過程登錄數據庫檢查:select count(*) from ep_table t where ptimetrunc(sysdate)-30 and alarmtype=0784163select count(*) from ep_table t4281062看來全表掃描正常se

3、lect from ep_table t where ptimetrunc(sysdate)-33 and alarmtype=0 and rownum10001索引掃描報錯了,推斷為索引上有壞塊!繼續(xù)查:select owner,file_id,segment_name, segment_type, block_id, blocksfrom dba_extentswhere file_id=16 and block_id= 2624066;OWNERFILE_IDSEGMENT_NAMESEGMENT_TYPEBLOCK_IDBLOCKSBS16VHINOINDEX262406616運氣真好

4、重建相關索引后數據庫就恢復了。黃山壞塊故障就比較復雜了,硬盤壞導致多個數據文件的多個塊故障,其中還有blob對象。Count(*)一張表報錯:查詢某張表系統(tǒng)事件中有報錯:磁盤管理中報錯:Dell的服務器,2塊72G硬盤,沒有做raid,8i數據庫沒有備份。(上圖磁盤3為移動硬盤)初步檢查到這里我感覺這次壞的嚴重了,恢復可能比較麻煩。整理一下思路:不要隨意重啟記錄損壞的數據信息導出可用數據更換故障硬盤重做系統(tǒng)及數據庫恢復數據重傳丟失的數據(我們的系統(tǒng)架構可以這樣做)排錯過程select * from dba_extents where file_id=8 and 1461842 between

5、block_id and block_id+blocks-11BSSYS_LOB0000003770C00017$LOBSEGMENTUSERS3457081461842131072168解釋:block_id+blocks-1=1461842+這個區(qū)有多少個block-1查到故障段為LOBSEGMENT類型,SYS_LOB0000003770C00017$。select dl.table_name,dl.SEGMENT_NAME from dba_lobs dl where dl.owner= BS where dl.SEGMENT_NAME= SYS_LOB0000003770C00017

6、$查到有壞塊的表為EP_PECC。接著查出這張表的lob索引段Select A.TABLE_NAME,A.COLUMN_NAME,B.SEGMENT_NAME,B.SEGMENT_TYPE,B.HEADER_FILE,B.HEADER_BLOCK,B.BYTES from DBA_LOBS A,DBA_SEGMENTS B where A.INDEX_NAME=B.SEGMENT_NAME AND A.TABLE_NAME=EP_PECC當時因為沒有記錄,所以我隨便舉例:1EP_TABLETHIRDPICTSYS_IL0000052738C00018$LOBINDEX7155655362EP_

7、TABLEPANORAMAPICTSYS_IL0000052738C00017$LOBINDEX7139655363EP_TABLEPLATEPICTSYS_IL0000052738C00016$LOBINDEX712365536select rowid from BS.EP_PECC where dbms_rowid.rowid_to_absolute_fno(rowid,BS,EP_PECC)=8 and dbms_rowid.rowid_block_number(rowid)=1461842;這個塊無法找出blob段的rowid。本想找后我可以按照rowid清空故障的blob數據。選擇一

8、個范圍繼續(xù)找:select rowid,T.PTIME,T.PLATEPICT,T.PANORAMAPICT from BS.EP_PECC T where dbms_rowid.rowid_to_absolute_fno(rowid,BS,EP_PECC)=8 and dbms_rowid.rowid_block_number(rowid) BETWEEN 1461840 AND 1461842;還是沒有找到select rowid, dbms_rowid.rowid_object(rowid) obj_id, dbms_rowid.rowid_relative_fno(rowid) df#

9、, dbms_rowid.rowid_block_number(rowid) blknum, dbms_rowid.rowid_row_number(rowid) rowno ,T.PTIME,T.ALARMTYPE,T.PLATEPICT,T.PANORAMAPICTfrom EP_PECC T where dbms_rowid.rowid_to_absolute_fno(rowid,BS,EP_PECC)=8 AND dbms_rowid.rowid_block_number(rowid) BETWEEN 1461842 AND 1461842 +1024;還沒找到select rowid

10、, dbms_rowid.rowid_object(rowid) obj_id, dbms_rowid.rowid_relative_fno(rowid) df#, dbms_rowid.rowid_block_number(rowid) blknum, dbms_rowid.rowid_row_number(rowid) rowno ,T.PTIME,T.ALARMTYPE,T.PLATEPICT,T.PANORAMAPICTfrom EP_PECC T where dbms_rowid.rowid_to_absolute_fno(rowid,BS,EP_PECC)=8 AND dbms_r

11、owid.rowid_block_number(rowid) BETWEEN 1461742 AND 1461842;終于找到了一些AAAA66AAIAAFkrSAAJ37708146094692009-10-26 19:40:080省略一些結果集AAAA66AAIAAFk5JAAG37708146183362009-10-26 19:47:080查到以下記錄時出錯,看來按照rowid清空故障的blob數據不行AAAA66AAIAAFk5JAAGROWID_TYPE: 1OBJECT_NUMBER: 3770RELATIVE_FNO: 8BLOCK_NUMBER: 1461833ROW_NUM

12、BER: 6可以從obj#,rfile#,block#,row#計算得到理論上的rowid Obj# 3770Rfile# 8Block# 1461842Row# 0實際上就是將十進制數轉化成64進制數,當然,從二進制轉化的規(guī)則比較簡單點。將二進制數從右到左,6個bit一組,然后將這6個bit組轉成10進制數,就是AZ az 09 + /這64個字符的位置(從0開始),替換成base64的字符即可。rowid是base64編碼的,用AZ az 09 + /共64個字符表示。A表示0,B表示1,a表示26,0表示52,+表示62,/表示63可以將其看做一個64進制的數。obj#=3770轉換成二

13、進制,補足成6位base64編碼,左邊填0,結果為AAAA66rfile#=8=001000=I,補足成3位,得到AAIblock#=1461842=000101 100100 111001 010010=5 36 57 18,補足成6位,得到AAFk5Srow#=0,3位AAA合起來就是AAAA66AAIAAFk5SAAA但是不要忘了,這次壞的是blob它會跨多個塊的。所以這條理論rowid沒有找到!舉例子補充說明:select * from dba_lobs dl where dl.owner=TEST1TESTT_LOGRZSYS_LOB0000052726C00002$TESTSYS_

14、IL0000052726C00002$8192900NOYESYESNOT APPLICABLE NO2TESTEP_TABLEPLATEPICTSYS_LOB0000052738C00016$TESTSYS_IL0000052738C00016$8192900NOYESYESNOT APPLICABLE NO3TESTEP_TABLEPANORAMAPICTSYS_LOB0000052738C00017$TESTSYS_IL0000052738C00017$8192900NOYESYESNOT APPLICABLE NO4TESTEP_TABLETHIRDPICTSYS_LOB0000052

15、738C00018$TESTSYS_IL0000052738C00018$8192900NOYESYESNOT APPLICABLE NO5TESTEP_PECCPLATEPICTSYS_LOB0000052746C00016$TESTSYS_IL0000052746C00016$8192900NOYESYESNOT APPLICABLE NO6TESTEP_PECCPANORAMAPICTSYS_LOB0000052746C00017$TESTSYS_IL0000052746C00017$8192900NOYESYESNOT APPLICABLE NO7TESTEP_PECCTHIRDPIC

16、TSYS_LOB0000052746C00018$TESTSYS_IL0000052746C00018$8192900NOYESYESNOT APPLICABLE NO沒有任何數據時:select dl.TABLE_NAME,dl.COLUMN_NAME,de.segment_name,de.segment_type,de.FILE_ID,de.BLOCK_ID from dba_extents de,dba_lobs dl where de.owner=TEST and dl.OWNER=TEST and de.segment_name=dl.SEGMENT_NAME1T_LOGRZSYS_

17、LOB0000052726C00002$LOBSEGMENT7172EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT71133EP_TABLEPANORAMAPICTSYS_LOB0000052738C00017$LOBSEGMENT71294EP_TABLETHIRDPICTSYS_LOB0000052738C00018$LOBSEGMENT71455EP_PECCPLATEPICTSYS_LOB0000052746C00016$LOBSEGMENT71776EP_PECCPANORAMAPICTSYS_LOB0000052746C000

18、17$LOBSEGMENT71937EP_PECCTHIRDPICTSYS_LOB0000052746C00018$LOBSEGMENT7209向EP_TABLE表的PLATEPICT字段,插入一張9MB大小的圖片后結果:1T_LOGRZSYS_LOB0000052726C00002$LOBSEGMENT7172EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT71133EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT72734EP_TABLEPLATEPICTSYS_LOB0000052

19、738C00016$LOBSEGMENT72815EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT72896EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT72977EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT73058EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT73139EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT

20、732110EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT732911EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT733712EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT734513EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT735314EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT736115EP_TABLEP

21、LATEPICTSYS_LOB0000052738C00016$LOBSEGMENT736916EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT737717EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT738518EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT6919EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT739320EP_TABLEPLATEPICTSYS_LOB00

22、00052738C00016$LOBSEGMENT613721EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT752122EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT626523EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT764924EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT639325EP_TABLEPLATEPICTSYS_LOB0000052738C00016$

23、LOBSEGMENT777726EP_TABLEPLATEPICTSYS_LOB0000052738C00016$LOBSEGMENT652127EP_TABLEPANORAMAPICTSYS_LOB0000052738C00017$LOBSEGMENT712928EP_TABLETHIRDPICTSYS_LOB0000052738C00018$LOBSEGMENT714529EP_PECCPLATEPICTSYS_LOB0000052746C00016$LOBSEGMENT717730EP_PECCPANORAMAPICTSYS_LOB0000052746C00017$LOBSEGMENT7

24、19331EP_PECCTHIRDPICTSYS_LOB0000052746C00018$LOBSEGMENT7209查test用戶blob容量:select sum(de.BYTES/1024/1024) from dba_extents de,dba_lobs dl where de.owner=TEST AND dl.OWNER=TEST AND de.segment_name=dl.segment_name10.375顯示10MB檢查表建在那個數據文件那個塊上SELECT DISTINCT dbms_rowid.rowid_relative_fno(rowid) AS File, db

25、ms_rowid.rowid_block_number(rowid) AS Block FROM ep_table; FileBlock7110看起來這個表存放在文件號7,塊號110的地方查找存放圖片的blob段:select de.segment_name,de.EXTENT_ID,de.FILE_ID,de.BLOCK_ID,de.BYTES,de.BLOCKS,de.relative_fno from dba_extents de where de.owner=TEST and de.segment_name=SYS_LOB0000052738C00016$我已經往這個段里存放了一張9M

26、B的圖片,占用了以下塊。 SEGMENT_NAME EXTENT_IDFILE_IDBLOCK_IDBYTESBLOCKSRELATIVE_FNO1SYS_LOB0000052738C00016$0711365536872SYS_LOB0000052738C00016$1727365536873SYS_LOB0000052738C00016$2728165536874SYS_LOB0000052738C00016$3728965536875SYS_LOB0000052738C00016$4729765536876SYS_LOB0000052738C00016$5730565536877SYS_

27、LOB0000052738C00016$6731365536878SYS_LOB0000052738C00016$7732165536879SYS_LOB0000052738C00016$87329655368710SYS_LOB0000052738C00016$97337655368711SYS_LOB0000052738C00016$107345655368712SYS_LOB0000052738C00016$117353655368713SYS_LOB0000052738C00016$127361655368714SYS_LOB0000052738C00016$1373696553687

28、15SYS_LOB0000052738C00016$147377655368716SYS_LOB0000052738C00016$157385655368717SYS_LOB0000052738C00016$16691048576128618SYS_LOB0000052738C00016$1773931048576128719SYS_LOB0000052738C00016$1861371048576128620SYS_LOB0000052738C00016$1975211048576128721SYS_LOB0000052738C00016$2062651048576128622SYS_LOB

29、0000052738C00016$2176491048576128723SYS_LOB0000052738C00016$2263931048576128624SYS_LOB0000052738C00016$2377771048576128725SYS_LOB0000052738C00016$24652110485761286根據上一步查出來的BLOCK_ID一陣狂找,終于找到了select rowid, dbms_rowid.rowid_object(rowid) obj_id, dbms_rowid.rowid_relative_fno(rowid) df#, dbms_rowid.rowi

30、d_block_number(rowid) blknum, dbms_rowid.rowid_row_number(rowid) rowno ,T.PTIME,T.ALARMTYPE,T.PLATEPICT,T.PANORAMAPICTfrom ep_table T where dbms_rowid.rowid_to_absolute_fno(rowid,TEST,EP_TABLE)=7 AND dbms_rowid.rowid_block_number(rowid) BETWEEN 1 AND 113; ROWIDOBJ_IDDF#BLKNUMROWNOPTIMEALARMTYPEPLATE

31、PICTPANORAMAPICT1AAAM4CAAHAAAABuAAA52738711002009-11-29 22:51:580看來它跨越了6號數據文件的9號塊到7號數據文件的777號塊根據rowid反過來驗證一下塊信息:declarev_rowid_type number;v_OBJECT_NUMBER number;v_RELATIVE_FNO number;v_BLOCK_NUMBERE_FNO number;v_ROW_NUMBER number;begindbms_rowid.rowid_info(rowid_in = AAAM4CAAHAAAABuAAA,rowid_type =

32、 v_rowid_type,object_number = v_OBJECT_NUMBER,relative_fno = v_RELATIVE_FNO,block_number = v_BLOCK_NUMBERE_FNO,row_number = v_ROW_NUMBER);dbms_output.put_line(ROWID_TYPE: |to_char(v_rowid_type);dbms_output.put_line(OBJECT_NUMBER: |to_char(v_OBJECT_NUMBER);dbms_output.put_line(RELATIVE_FNO: |to_char(

33、v_RELATIVE_FNO);dbms_output.put_line(BLOCK_NUMBER: |to_char(v_BLOCK_NUMBERE_FNO);dbms_output.put_line(ROW_NUMBER: |to_char(v_ROW_NUMBER);end;/ROWID_TYPE: 1OBJECT_NUMBER: 52738RELATIVE_FNO: 7BLOCK_NUMBER: 110ROW_NUMBER: 0也就是說如果blob字段發(fā)生壞塊,可能壞塊的block_id為273,但是要查找記錄的rowid的話需要前后跨越一段block_id才有可能找到,例如這里的11

34、0。而從obj#,rfile#,block#,row#計算得到理論上的rowid可能不存在?;氐近S山壞塊故障上:SELECT COUNT(*) FROM EP_PECC WHERE TO_CHAR(PTIME,YYYYMMDD) 20091125 AND TO_CHAR(PTIME,YYYYMMDD) 20091127;ERROR 位于第 1 行:ORA-01115: 從文件 8 讀取塊時出現 IO 錯誤 (塊 # 1461842)ORA-01110: 數據文件 8: E:ORADATADZJCUSERS02.DBFORA-27091: skgfqio: 無法進行 I/O 操作OSD-0400

35、6: ReadFile() 失敗,無法自文件讀取O/S-Error: (OS 23) 數據錯誤 (循環(huán)冗余檢查)。驗證了這個時間段區(qū)間內的數據有壞塊!Select count(*) from EP_PECC t where PTIMETO_DATE(20091026 20:48:57,yyyymmdd HH24:MI:SS)沒有報錯結論:1461833塊為 20091026 20:47:57到 20091026 20:48:57 之間。同時我也偷懶了沒有繼續(xù)查找因為連著壞了好多塊。恢復完數據庫后重傳這段時間的記錄就行了!備份時只需把期間的數據備份出來就可以。DELETE from EP_PEC

36、C t where PTIMETO_DATE(20091001 00:00:00,yyyymmdd HH24:MI:SS)和用戶溝通了一下,把以前的過期記錄全部刪除后來發(fā)現另外一張表EP_TABLE導出時也有壞塊。即將導出指定的表通過常規(guī)路徑 . . 正在導出表 EP_TABLEEXP-00056: ORACLE 錯誤 1115 出現ORA-01115: 從文件 8 讀取塊時出現 IO 錯誤 (塊 # 1200338)ORA-27070: skgfdisp: 異步讀取/寫入失敗OSD-04016: 查詢非同步 I/O 請求發(fā)生錯誤.O/S-Error: (OS 23) 數據錯誤 (循環(huán)冗余檢查

37、)。ORA-01115: 從文件 8 讀取塊時出現 IO 錯誤 (塊 # 1200338)ORA-27070: skgfdisp: 異步讀取/寫入失敗OSD-04016: 查詢非同步 I/O 請求發(fā)生錯誤.O/S-Error: (OS 23) 數據錯誤 (循環(huán)冗余檢查)。導出成功終止,但出現警告。同理處理。找到壞塊所在記錄的時間段后exp時跳過。后面的恢復處理就不寫了。特別注意:試過dbms_repair,但是dbms_repair找不到錯誤的記錄。試過ALTER SYSTEM SET EVENTS 10231 trace name context forever,level 10; 也不能成

38、功。奇怪了,只能猜硬盤壞的太厲害,產生了物理壞道。RMAN 可以備份包含損壞數據塊的數據文件,通過設置 set maxcorrupt 可以跳過指定個數的壞塊來避免備份失敗。 RMAN set maxcorrupt for datafile 1 to 10;在 Oracle9i中可以用 RMAN來執(zhí)行塊級的恢復,而且恢復期間數據文件可以是聯機狀 態(tài)。RMAN通過 Block Media Recovery(簡稱 BMR)來執(zhí)行塊級恢復操作。假設我們在查 詢一個 Oracle 表的時候接收到下面的錯誤:ERROR 位于第 1 行:ORA-01578: ORACLE 數據塊損壞(文件號 5,塊號 97

39、) ORA-01110: 數據文件 5: E:xxxx.dbf那么我們就可以在 RMAN中用 BLOCKRECOVER 命令來修復:RMAN BLOCKRECOVER DATAFILE 5 BLOCK97; 啟動 blockrecover 于 03-9月 -06 正在啟動全部恢復目錄的 resync完成全部 resync使用通道 ORA_DISK_1通道 ORA_DISK_1: 正在從數據文件副本 E:xxxx.bak 恢復塊 正在開始介質的恢復完成介質的恢復完成 blockrecover 于 03-9月 -06塊恢復 Block Media Recovery (BMR),塊是恢復的最小單元,

40、通過塊可以減少恢復 時間,而且數據文件可以在線?;謴蛪K的時候,必須指定具體的塊號,如:RMAN blockrecoverdatafile 6 block 3;具體請見 4.7.4 塊媒體恢復 Block Media Recovery (BMR)1)指示RMAN從文件的最新備份集或映像副本中還原與恢復一個指定的數據塊: RMAN blockrecover datafile 7 block 5;2)BLOCKRECOVER命令可以接受若干文件中的一列數據塊: RMAN blockrecover datafile 7 block 5,6,7 datafile 9 block 21,25;3)從指定備

41、份集中還原數據塊 RMAN blockrecover datafile 7 block 5 from backupset 1039;4)從使用標記指定的備份中還原數據塊 RMAN blockrecover datafile 7 block 5 from tag monthly_whole;5)使用至少已生成一周的備份來還原和恢復前一個備份操作發(fā)現受損的所有數據塊: RMAN blockrecover corruption list until time sysdate - 7;注意:此處關鍵字UNTIL并非表示不完全恢復!這個關鍵字意味著必須從特定日期(序列號或SCN)之前生成的備份中還原數據

42、塊。下面系統(tǒng)的總結一下壞塊故障的處理:數據庫出現壞塊現象是指:在Oracle數據庫的一個或多個數據塊內出現內容混亂的現象。由于正常的數據塊都有固定的合法內容格式,壞塊的出現,導致數據庫進程無法正常解析數據塊的內容,進而使數據庫進程報錯乃至掛起,并級聯導致整個數據庫實例出現異常。一壞塊的產生原因壞塊產生的原因大致有以下幾種:1.1 硬件問題Oracle進程在處理一個數據塊時,首先將其讀入物理內存空間,在處理完成后,再由特定進程將其寫回磁盤;如果在這個過程中,出現內存故障,CPU計算失誤,都會導致內存數據塊的內容混亂,最后反映到寫回磁盤的數據塊內容有誤。同樣,如果存儲子系統(tǒng)出現異常,數據塊損壞也就

43、隨之出現了。1.2 操作系統(tǒng)BUG由于Oracle進程對數據塊的讀寫,都是以操作系統(tǒng)內核調用(system call)的方式完成的,如果操作系統(tǒng)在內核調用存在問題,必然導致Oracle進程寫入非法的內容。1.3 操作系統(tǒng)的I/O錯誤或緩沖問題1.4 內存或paging問題Oracle軟件BUGOracle軟件特定版本上,可能出現導致數據塊的內容出現異常BUG。1.5 非Oracle進程擾亂Oracle共享內存區(qū)域如上文所述,在當數據塊的內容被讀入主機的物理內存時,如果其他非Oracle進程,對Oracle使用的共享內存區(qū)域形成了擾亂,最終導致寫回磁盤的數據塊內容混亂。1.6 異常關機,掉電,終

44、止服務異常關機,掉電,終止服務使進程異常終止,而破壞數據塊的完整性,導致壞塊產生。注:這也是為什么突然斷電會導致數據庫無法啟動由上可見,壞塊的形成原因復雜。當出現壞塊時,為了找到確切的原因,需要大量的分析時間和排查操作,甚至需要多次重現才能找出根本原因。但當故障發(fā)生在生產系統(tǒng)上,我們?yōu)榱藴p少停機時間,會盡快實施應急權變措施以保證系統(tǒng)的可用性,這樣就破壞了故障現場,對根本原因的分析因而也更加困難了。二壞塊的預防壞塊問題破壞性大,但并非不可預防。2.1 在M網站,Oracle定期發(fā)布基于特定軟件版本的“已知問題(known issues)說明”。對于可能導致壞塊的Oracle軟件BUG,在Orac

45、le公司內部,是作為高嚴重級別的問題進行處理,在“已知問題(known issues)說明”中,這些BUG以嚴重(Noticable)問題標出(標記為*或+),部分問題,Oracle還會發(fā)布警告(Alert)通告。在文檔中,Oracle會提供相應的補丁或應對措施。2.2 Oracle提供備份恢復工具Recovery Manager,提供了掃描文件檢查壞塊的功能。在Recovery Manager界面中,使用:RMAN BACKUP CHECK LOGICAL VALIDATE DATAFILE n ;可以檢查數據文件是否包含壞塊,同時并不產生實際的備份輸出。2.3 Dbv工具檢查注:因為dbv

46、要求file后面跟的必須是一個文件擴展名,所以如果用裸設備存儲的,就必須使用ln鏈接裸設備到一個文件,然后再用dbv對這個鏈接文件進行檢查。ANALYZE TABLE tablename VALIDATE STRUCTURE CASCADE它執(zhí)行壞塊的檢查,但是不會標記壞塊為corrupt,檢測的結果保存在USER_DUMP_DEST目錄下的用戶trace文件中。2.4 利用exp工具導出整個數據庫可以檢測壞塊對以下情況的壞塊是檢測不出來的:HWM以上的壞塊是不會發(fā)現的索引中存在的壞塊是不會發(fā)現的數據字典中的壞塊是不會發(fā)現的結合數據庫性能綜合考慮db_block_checksum和db_blo

47、ckchecking參數。當我們使用Recovery Manager進行實際的數據庫備份時,同時也就進行了壞塊檢查。但要注意的是,在線使用Recovery Manager掃描壞塊和備份時,需要數據庫運行在歸檔模式(archive log),否則只能在數據庫未打開的情況下進行。對于操作系統(tǒng)問題和硬件故障,則需要相應廠商的配合支持。同時,避免在數據庫主機運行其他用戶進程,避免異常停機,也會減少壞塊發(fā)生的幾率。三壞塊故障的識別遇到壞塊問題時,數據庫的異常表現通常有:報告ORA-01578錯誤。報告Ora-1110錯誤。報告ORA-00600錯誤,其中,第一個參數為2000-8000,Cache la

48、yer 2000 4000,Transaction layer 4000 6000,Data layer 6000 - 8000。Trace文件中出現Corrupt block dba: 0 x160c5958 . found。分析對象失敗。后臺進程,如DBWR,LGWR出現長時間異常等待,如“LGWR wait for redo copy”。四Oracle數據塊損壞恢復總結可以用DBV 命令來檢測是否有壞塊:在恢復前使用DBV命令檢查數據文件是否存在壞塊dbv file=d:oracleoradatamydbRONLY.DBF blocksize=8192查看數據壞塊所在數據文件號及塊號可以

49、對表進行一次全表掃描,如:select count(*) from tablename;關于DBV 命令的具體使用,請參考blog:/tianlesoftware/archive/2009/12/16/5015164.aspx4.1 沒有備份的情況下:4.1.1、使用exp/imp恢復在這種情況下肯定會造成數據的丟失,在這種情況下應采取將數據導出然后重建表再進行導入的方法,來盡量恢復損壞數據塊中的數據,但是在有壞塊的情況下是不允許導出的,如下命令:Exp test/test file=t.dmp tables=t;導出命令在執(zhí)行中會報ORA-01578錯誤,在這錯誤提示中會提示那個文件號的文件

50、以及這個文件中的哪個塊被損壞,如:ORA01578:ORACLE 數據塊損壞(文件號 4,塊號 35)針對以上的提示首先查詢那些對象被損壞:Select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=4 and 35 between block_id and block_id+blocks-1;如果被損壞的塊是索引,通??梢酝ㄟ^索引重建來解決,如果損壞的是數據(segment_type為table),那么通過設置如下內部事件使得Exp操作跳過壞塊。Alter session set

51、events=10231 trace name context forever,level 10;然后重新執(zhí)行導出命令,導出相關的表,然后執(zhí)行Drop Table命令刪除相關表,之后重建表最后導入數據。4.1.2、使用DBMS_REPAIR恢復用DBMS_REPAIR當然也會丟失數據。這里不做詳細的介紹,有興趣的可以查看oracle的在線文檔4.2 使用Rman進行恢復:首先要存在Rman的最新備份集,然后執(zhí)行如下命令:RMANbackup validate datafile 4;檢查4號數據文件是否存在壞塊執(zhí)行查詢:select * from v$database_block_corrupt

52、ion where file#=4;如果4號文件存在壞塊的話,那么將在結果集中有所顯示,會顯示損壞的塊號,根據顯示結果執(zhí)行如下命令進行恢復:RMANblockrecover datafile 4 block 35 from backupset;該命令執(zhí)行后即可恢復壞塊,并且不會造成數據丟失,但是要求數據庫必須要運行在歸檔模式下,否則RMAN無法發(fā)揮作用,而且通過RMAN做過最新的數據庫備份4.3 使用bbed恢復使用bbed恢復時必須有數據文件的拷貝。bbed就是英文block browse edit的縮寫,用來直接查看和修改數據文件數據的一個工具。BBED在windows 8i中在$ORAC

53、LE_HOME/bin下可以找到,9i中似乎未隨軟件發(fā)布,故在windows沒有這個工具,linux下需要編譯,然后把$ORACLE_HOME/rdbms/lib加到環(huán)境變量的PATH里面,就可以直接在命令中bbed了。BBED的缺省口令為blockedit,For Oracle Internal Use only 請謹慎使用Oracle不做技術支持。BBED具體的使用,參考blog:/tianlesoftware/archive/2009/12/14/5006580.aspx五如何查找壞塊所含的數據表名稱和數據的rowidrowid的結構 HYPERLINK /diego76/prevPho

54、to.do?photoId=_fks_Lvu76spe6CPRQSZmfn9s_o9-Chr01BMR t _blank ROWID 格式擴展的ROWID 在磁盤上需要10 個字節(jié)的存儲空間,并使用18 個字符來顯示。它包含下列組成元素: 數據對象編號:每個數據對象(如表或索引)在創(chuàng)建時都分配有此編號,并且此編號在數據庫中是唯一的 相關文件編號:此編號對于表空間中的每個文件是唯一的 塊編號:表示包含此行的塊在文件中的位置 行編號:標識塊頭中行目錄位置的位置在內部,數據對象編號需要32 位、相關文件編號需要10 位、塊編號需要22 位、行編號需要16 位,加起來總共是80 位或10 個字節(jié)。擴展

55、的ROWID 使用以64 為基數的編碼方案來顯示,該方案將六個位置用于數據對象編號、三個位置用于相關文件編號、六個位置用于塊編號、三個位置用于行編號。以64 為基數的編碼方案使用字符“A-Z”、“a-z”、“0-9” 和“/”。共有64 個字符,如下例所示:SQL SELECT department_id, rowid FROM hr.departments;DEPARTMENT_ID ROWID 10 AAABQMAAFAAAAA6AAA20 AAABQMAAFAAAAA6AAB30 AAABQMAAFAAAAA6AAC40 AAABQMAAFAAAAA6AAD50 AAABQMAAFAAA

56、AA6AAE60 AAABQMAAFAAAAA6AAF在本例中: AAABQM 是數據對象編號 AAF 是相關文件編號 AAAAA6 是塊編號 AAA 是ID=10 的部分的行編號Oracle7 和更早版本中的受限ROWID:Oracle8 之前的Oracle 數據庫版本使用的是受限的ROWID 格式。受限的ROWID 在內部僅使用六個字節(jié),不包含數據對象編號。此格式在Oracle7 或更早的發(fā)行版中是可以接受的,因為文件編號在一個數據庫內是唯一的。因此,較早的發(fā)行版不允許數據文件數超過1,022 個。目前,對表空間有此限制。即使Oracle8 通過使用與表空間相關的文件編號擺脫了這種限制,但

57、受限ROWID 仍用在非分區(qū)表上的非分區(qū)索引之類的對象中,其中所有索引條目指的是同一段中的行。3.行的結構 HYPERLINK /diego76/prevPhoto.do?photoId=_fks_gsQbIKD_wv8Z388VLgUUY_tT8x1Opc09 t _blank 行的結構行數據作為長度可變的記錄存儲在數據庫塊中。通常,一個行的各列按其定義時的順序存儲,并且不存儲尾隨的NULL 列。注:對于非尾隨的NULL 列,列長度需要占用一個字節(jié)。表中的每行具有: 行頭:用來存儲行中的列數、鏈接信息和行鎖定狀態(tài) 行數據:對于每一列,Oracle 服務器存儲列的長度和值(如果該列不超過250

58、 個字節(jié),則需要一個字節(jié)來存儲列長度;如果該列超過250 個字節(jié),則需要三個字節(jié)來存儲列長度。列值在緊靠列長度字節(jié)后面存儲。)相鄰的行之間不需要任何空格。塊中的每一行在行目錄中都有一個位置。目錄位置指向行首。5.1. 首先肯定知道那個數據文件壞了,查出該文件的file_id,relative_fno,tablespace_name利用dba_data_files可以查詢file_id(整個數據庫唯一序號),RELATIVE_FNO(相對一個表空間內的序號)5.2. 找到壞塊的ID(可以運行dbverify實現),假設找到的壞塊ID為1234。5.3.運行下面的查詢,根據,壞塊的file_id,

59、block id查找該塊對應的owner,segment_type,segment_name等信息 select owner,file_id,segment_name, segment_type, block_id, blocksfrom dba_extentswhere file_id=13 and block_id= 1234;5.4. 根據壞塊的file_id,owner,segment_name,block_id,如果是數據表的話,用下面的查詢來得到對應壞塊的rowid假設owner : DAVE segment_name: BL file_id : 13 block_id : 162

60、運行下面的查詢來獲得該塊所含的rowid(如果沒有索引,可能就不能用下面的方式了):select /*+ index(DAVE, i_test) */ rowidfrom DAVE.BLwhere dbms_rowid.rowid_to_absolute_fno(rowid,DAVE,BL)=13and dbms_rowid.rowid_block_number(rowid)=162; 六,如何模擬壞塊DBA 的基本知識,制造壞塊的方法很多的,可以用ultraedit,也可以用dd命令,同時也可以用orapatch工具6.1 orapatch 工具:$orapatch open tools00

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論