天天看點

【BBED】BBED模拟并修複ORA-08102錯誤---------------------------------------------------------------------第二章 實驗部分  實驗中用到的SQL總結

【BBED】BBED模拟并修複ORA-08102錯誤

【BBED】BBED模拟并修複ORA-08102錯誤---------------------------------------------------------------------第二章 實驗部分  實驗中用到的SQL總結

各位技術愛好者,看完本文後,你可以掌握如下的技能,也可以學到一些其它你所不知道的知識,~O(∩_∩)O~:

① 使用BBED修複ORA-08102錯誤(重點)

② BBED的使用

③ 資料塊格式的dump檔案解釋

④ ORA-08102錯誤的trace檔案解釋

⑤ 從rdba擷取ROWID資訊

⑥ 其它實用技能

這幾天一個朋友問我有關ORA-08102的錯誤,而且是關于OBJ$表上的I_OBJ4索引。這些系統對象的索引,不能采用重建或設定事件的方式來修複該錯誤。模模糊糊的記得很早以前看過使用BBED的方式來修複該錯誤,隻是已經記不清了。正好,趁此機會把該錯誤再模拟的複現一下,也把bbed再熟悉一下吧。

朋友發給我的參考文章也是大師惜分飛的部落格位址,大緻看了一下過程,主要是找到索引塊的相關位址,然後利用bbed把鍵值修改的和表中存儲的一緻即可。還是那句話,“紙上得來終覺淺,絕知此事要躬行。”,自己模拟實驗,這個過程是必須的。

廢話不多說,開始實驗吧。

閱讀本篇文章,請先閱讀以下内容:

3.BBED的幾篇文章:

1、bbed畢竟是未公開的恢複方式,是以不熟悉的朋友要慎用。

2、startup force慎用

3、操作bbed之前最好先把資料庫關閉

An ORA-08102 indicates that there is a mismatch between the key(s) stored in the index and the values stored in the table.What typically happens in the index is built and at some future time,some type of corruption occurs,either in the table or index,to cause the mismatch.

ORA-08102常見于索引鍵值與表上存的值不一緻。

[oracle@rhel6lhr ~]$ oerr ora 8102

08102, 00000, "index key not found, obj# %s, file %s, block %s (%s)"

// *Cause:  Internal error: possible inconsistency in index

// *Action:  Send trace file to your customer support representative, along

//           with information on reproducing the error

ora-08102這種錯誤說明索引或表出現了資料不一緻,索引上記錄的鍵值和表裡的資料不一緻,引起通路失敗,一般重建下索引就可以解決。兩邊不一緻改表和索引都能達到目的,隻要一緻即可,但有一個原則就是索引鍵值始終要保證按順序遞增。通常有三種情況:

1.如果損壞為索引,則删除索引并重建索引,但對于index的obj#小于56的情況,由于是核心的bootstrap$對象,index是在DB啟動時由DB自動建立,此種情況下通過設定event 38003或startup migrate模式都不能解決,但obj#>56的則可以。

2.如果損壞為塊級别,則采用壞塊的處理方法

3.如果損壞的為表的記錄級别的則采用bbed或其它工具

I_OBJ1、I_OBJ2、I_OBJ3、I_OBJ4、I_OBJ5這幾個都是OBJ$基表的索引,如果損壞會非常麻煩,因為ORACLE 對這些對象的DDL做了嚴格限制,沒有辦法簡單修複它們。

【BBED】BBED模拟并修複ORA-08102錯誤---------------------------------------------------------------------第二章 實驗部分  實驗中用到的SQL總結

SYS@ora11g > drop index i_obj4;

drop index i_obj5

           *

ERROR at line 1:

ORA-00701: object necessary for warmstarting database cannot be altered

項目

source db

db 類型

單機

db version

11.2.0.3.0

db 存儲

FS

OS版本及kernel版本

RHEL 6.5

實驗目标:使用BBED模拟并修複ORA-08102錯誤。

模拟錯誤過程:通過bbed修改OBJ$表中DATAOBJ#列最大的行所在的塊,讓DATAOBJ#的值增大,進而和索引中記錄的值不一緻。重新開機資料庫并建立表讓資料庫報出ORA-08102錯誤。

修複錯誤過程:通過bbed把表中或索引中的不一緻的資料修改成一緻的,進而修複ORA-08102錯誤。

[oracle@rhel6lhr ~]$ more rman_full.sh

rman target / nocatalog <<>

run{

backup database format '/home/oracle/bak/%d_%U.full';

sql 'alter system archive log current';

backup archivelog all format '/home/oracle/bak/%d_%U.arc';

backup current controlfile format '/home/oracle/bak/%d_%U.ctl';

}

EOF

通過BBED修改OBJ$中DATAOBJ$重制I_OBJ4索引報ORA-08102錯誤。定位需要破壞的OBJ$上DATAOBJ$列最大的記錄,使之和索引I_OBJ4中記錄不一緻,進而實作ORA-8102錯誤。

[oracle@rhel6lhr ~]$ ORACLE_SID=ora11g

[oracle@rhel6lhr ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on Thu Sep 21 09:24:08 2017

Copyright (c) 1982, 2011, Oracle.  All rights reserved.

Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

SYS@ora11g > select object_id,object_type from dba_objects where object_name='I_OBJ4';

OBJECT_ID OBJECT_TYPE

---------- -------------------

        39 INDEX

SYS@ora11g > select max(DATAOBJ#) from obj$;

MAX(DATAOBJ#)

-------------

        94098

SYS@ora11g > select dump(94098,16) from dual;

DUMP(94098,16)

-----------------------

Typ=2 Len=4: c3,a,29,63 ===>>>>> Typ=2表示NUMBER,96表示CHAR。Len=4表示4位長度,是以,94098在資料庫内部的存儲格式為04c30a2963

SYS@ora11g > SELECT DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) FILE#,

  2         DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) BLOCK#,

  3         DBMS_ROWID.ROWID_ROW_NUMBER(ROWID) ROW#

  4    FROM OBJ$

  5   WHERE DATAOBJ# = 94098;

     FILE#     BLOCK#       ROW#

---------- ---------- ----------

         1        241         27

SYS@ora11g > SELECT COUNT(*) COUNTS,

  2         MAX(DBMS_ROWID.ROWID_ROW_NUMBER(ROWID)) MAX_ROWNUM,

  3         MIN(DBMS_ROWID.ROWID_ROW_NUMBER(ROWID)) MIN_ROWNUM

  4    FROM SYS.OBJ$ D

  5   WHERE DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) = 1

  6     AND DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) = 241;

    COUNTS MAX_ROWNUM MIN_ROWNUM

       105        104          0

根據以上的SQL可以得到下表的内容:

OBJ$上DATAOBJ#列的最大值

94098

OBJ$上DATAOBJ#列的最大值dump值

Typ=2 Len=4: c3,a,29,63  即:04c30a2963

該行所在資料塊的位址

該行的存儲情況

即:OBJ$表上DATAOBJ#列的最大值為94098,該值在Oracle資料庫中的存儲格式為04c30a2963,該行資料所在的塊為1号檔案,241号塊,第27行,該塊上共有105行資料,最大值的行号為104,最小值的行号為0。

全文請參考:http://blog.itpub.net/26736162/viewspace-2145368/

SELECT COUNT(*) COUNTS,

       MAX(DBMS_ROWID.ROWID_ROW_NUMBER(ROWID)) MAX_ROWNUM,

       MIN(DBMS_ROWID.ROWID_ROW_NUMBER(ROWID)) MIN_ROWNUM

  FROM SYS.OBJ$ D

WHERE DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) = 1

   AND DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) = 241;

SELECT DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) FILE#,

       DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) BLOCK#,

       DBMS_ROWID.ROWID_ROW_NUMBER(ROWID) ROW#

  FROM SYS.OBJ$

WHERE DATAOBJ# = 94109;

SELECT DUMP(94098, 16) FROM DUAL;

SELECT DUMP(OBJ#, 16),

       DUMP(DATAOBJ#, 16),

       DUMP(OWNER#, 16),

       DUMP(NAME, 16),

       DUMP(NAMESPACE, 16),

       DUMP(SUBNAME, 16),

       DUMP(TYPE#, 16),

       DUMP(CTIME, 16),

       DUMP(MTIME, 16),

       DUMP(STIME, 16),

       DUMP(STATUS, 16),

       DUMP(REMOTEOWNER, 16),

       DUMP(LINKNAME, 16),

       DUMP(FLAGS, 16),

       DUMP(OID$, 16),

       DUMP(SPARE1, 16),

       DUMP(SPARE2, 16),

       DUMP(SPARE3, 16),

       DUMP(SPARE4, 16),

       DUMP(SPARE5, 16),

       DUMP(SPARE6, 16)

WHERE DATAOBJ# = 94098;

SELECT OBJ#,

       DATAOBJ#,

       OWNER#,

       NAME,

       NAMESPACE,

       SUBNAME,

       TYPE#,

       CTIME,

       MTIME,

       STIME,

       STATUS,

       REMOTEOWNER,

       LINKNAME,

       FLAGS,

       OID$,

       SPARE1,

       SPARE2,

       SPARE3

SELECT * FROM SYS.OBJ$ D WHERE D.NAME = 'OBJ$';

SELECT 'DUMP(' || D.COLUMN_NAME || ',16),'

  FROM DBA_TAB_COLS D

WHERE D.TABLE_NAME = 'OBJ$'

ORDER BY D.COLUMN_ID;

SELECT D.COLUMN_NAME || ','

SELECT * FROM sys.Bootstrap$ ;

ORA-08102: index key not found, obj# 39, file 1, block 94083 (2)

select /*+ index(t i_obj4) */ DATAOBJ# from sys.obj$  t 

minus

select /*+ full(t1) */ DATAOBJ# from sys.obj$  t1;

select /*+ full(t1) */ DATAOBJ# from sys.obj$  t1

  select /*+ index(t i_obj4) */ DATAOBJ# from sys.obj$  t 

;

select /*+ full(t) */  DATAOBJ#,type#,owner# from sys.obj$  t  WHERE t.dataobj# IN (94098,94099);

select /*+ full(t i_obj4) */  DATAOBJ#,type#,owner# from sys.obj$  t  WHERE t.dataobj# IN (94098,94099);

--16進制轉換為10進制

select utl_raw.cast_to_number('c30a2964') from dual;

show all

map

p kdbr

p *kdbr[27]

x /rnnncncntttnccncnnn

d /v count 32

f /x c30a29

sum

sum apply

v

     本文轉自lhrbest 51CTO部落格,原文連結http://blog.51cto.com/lhrbest/1967898:,如需轉載請自行聯系原作者