人工的にOracleデータブロックにロジックエラが起こったことをシミュレーションするORA-00600:[13013] [5001]一例

ORACLEデータベース によくあるエラ の解決策

プロのOracle Databaseの復旧サービスを提供
携帯番号: +86 13764045638 メール:[email protected]

 

前週で、お客様からOracle Bugによって、テーブルデータブロックロジックエラでORA-00600:[13013], [5001]を引き起こした例をもらった。ここで、よりうまく説明できるように、人工的にそのエラをシミュレーションする発想が生み出した。

基礎的な知識

Oracleにテーブルのデータブロックはブロックへっだ、トランザクションスロット、行ディクショナリー、及び行データなどいろんな構造で組み立てた。行データは行数据(rowdata)いろんなrow piece によって組み立てる。各row pieceのヘッダにflag、locks、cols(cc)三つのマーク位置がある。

そのflagはrow pieceのタイプをマークした。そのflag位置は一つのバイトを占めて、違ったbit位置が違った意味を意味している。以下の通り:

 

 

ROW_CLUSTER_KEY = 0x80;              KDRHFK
ROW_CTABLE_NUMBER = 0x40;            KDRHFC
ROW_HEAD_PIECE = 0x20;               KDRHFH
ROW_DELETED_ROW = 0x10;              KDRHFD
ROW_FIRST_PIECE = 0x08;              KDRHFF
ROW_LAST_PIECE = 0x04;               KDRHFL
ROW_FROM_PREVIOUS = 0x02;            KDRHFP
ROW_CONTINUE_NEXT = 0x01;            KDRHFN

一般的に、もっとも普通なrow pieceは普通スタックテーブル(heap table)に削除されていない。そして行転移/行リンクもない。そのflag位置は以下の通り

普通のrowのflagは

Single Row =
ROW_HEAD_PIECE + ROW_FIRST_PIECE + ROW_LAST_PIECE= 0x20 + 0x08 + 0x04= 0x2c

===================================================================================

cluster keyのflagは

Cluster Key =
ROW_CLUSTER_KEY + ROW_HEAD_PIECE + ROW_FIRST_PIECE + ROW_LAST_PIECE=
KDRHFL, KDRHFF, KDRHFH, KDRHFK =0x80 + 0x2c =  0xac

BBED> x /rn
rowdata[68]                                 @8166
-----------
flag@8166: 0xac (KDRHFL, KDRHFF, KDRHFH, KDRHFK)
lock@8167: 0x00
cols@8168:    1
kref@8169:    1
mref@8171:    1
hrid@8173:0x01800014.0
nrid@8179:0x01800014.0

col    0[2] @8185: 10 

===================================================================================

Cluster Row =
ROW_CTABLE_NUMBER + ROW_HEAD_PIECE + ROW_FIRST_PIECE + ROW_LAST_PIECE =
(KDRHFL, KDRHFF, KDRHFH, KDRHFC) = 0x6c 

BBED> x /rncc
rowdata[0]                                  @8098
----------
flag@8098: 0x6c (KDRHFL, KDRHFF, KDRHFH, KDRHFC)
lock@8099: 0x00
cols@8100:   10

col    0[2] @8102: 200
col    1[8] @8105: Jennifer
col    2[6] @8114: Whalen
col    3[7] @8121: JWHALEN
col   4[12] @8129: 515.123.4444
col    5[7] @8142: w....
col    6[7] @8150: AD_ASST
col    7[2] @8158: 

                    col    8[0] @8161: *NULL*
col    9[3] @8162: .

ORA-00600:[13013], [5001]且Arg [f] Code =3 が現れて、row pieceのflag >0xc0と意味している,
つまり、そのrow pieceは同時にkeyとclustered(row is marked as both a Key and Clustered)とマークされた。その検証コードはcheck code 6251である。

flag >= 0xc0 の時にkdrchk: row is marked as both a Key and Clustered Block 12 failed with check code 6251が現れる

 0xac >flag >= 0xa0 の時に kdrchk: row is Key and Not only piece of key Block 12 failed with check code 6255が現れる

 flag = 0x43の時に kdrchk: C and neither of H or F Block 12 failed with check code 6263が現れる

 flag = 0x83 の時に  kdrchk: row is marked both as a Key and being continued Block 12 failed with check code 6254が現れる

Oracleプロセスがデータブロックをアクセスするときに、まずはブロックの合計値はテストする。そして、ブロックにあるCHECKSUM値と比べる。一致していれば、そのブロックに物理的なエラがないと意味している。ブロックを100%正確を確保するために、このテストだけでまだ足りない。それで、Oracleが一部の列ロジックテストを導入して、各ロジックテストは一つのテストコードに該当する (check code)row pieceのflag、cols(cc)状況テストなども含んでいる。

実際に、このロジック検証テストの関数は:kdbchk、kddummy_blkchk、kco_blkchk、kdBlkCheckError、kdrchkなどを含んでいる。

ここで、サビースプロセスがトラブルデータブロックをアクセスした、テストコードはそのflagがflag为0xff(KCHDFLPN)だと検出できた。そのflagはロジック的に衝突したから、テストコードはそのrow pieceにエラがあると認めている。さらに、updateによって、ORA-00600:[13013], [5001]あるクエリORA-600 [qertbFetchByRowID]内部エラを引き起こした。

ここで説明する必要があるのは、いろんな人がdbvツールで、ロジックエラを検出出来ないと認めているが、実際に、dbvもrmanもvalidate structureもbbed-verifyもある程度のロジックエラを検出できる。けど、一番頼りになるのが、db_block_checksum=trueの場合のvalidate structure [online]検証コマンドである。一方、普通のdbvは一つテストしかできないが。しかも、交換的なテストもできない、そして、テーブルとインディクスが不一致のトラブルを解決できる。けどvalidate structure onlineなら、案外できる。


正式シミュレーション

以上はORA-00600:[13013], [5001]内部エラがどうやって引き起こされたかを理解できた。次に人工的にそのエラをシミュレーションするのも難しくなくなる。ここで、bbedツールを使ってください。

次に実験用のtablespace,table,indexを作成する:

 

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

SQL> select * from global_name;

GLOBAL_NAME
--------------------------------------------------------------------------------
www.askmac.cn

/* 実験用テーブルスペースを作成する  */

SQL> create tablespace maclean datafile '/home/oracle/maclean.dbf' size 20M;

Tablespace created.

SQL> create table tv tablespace maclean as select rownum t1,'find me' t2 from
dba_tables where rownumcreate index ind_tv on tv(t1) tablespace users;

Index created.

SQL> update tv set t2='corrption here' where t1=200;
update tv set t2='corrption here' where t1=200
*
ERROR at line 1:
ORA-12899: value too large for column "SYS"."TV"."T2" (actual: 14, maximum: 7)

SQL> alter table tv modify t2 varchar2(200);

Table altered.

SQL> update tv set t2='corruption here' where t1=200;

1 row updated.

SQL> commit;

Commit complete.

/* 以上はインスタンステーブルを作成した。そのなかt1=200の記録は後で人工的に修正する行である。             */

SQL> select dump(200,16) from dual;

DUMP(200,16)
-----------------
Typ=2 Len=2: c2,3

/* 16進数コードで、t1=200の記録行を容易く探し出せる */ 
SQL> alter system checkpoint;

System altered.

SQL> alter tablespace maclean read only;

Tablespace altered.

SQL> select dbms_rowid.rowid_block_number(rowid) bno ,dbms_rowid.rowid_relative_fno(rowid) fno from tv;

BNO FNO
---------- ----------
12 6

[oracle@rh2 ~]$ cp maclean.dbf maclean.dbf.bak


次にBBEDツールで、目標を探し出し、人工的に修正してください:

[oracle@rh2 ~]$ bbed filename=maclean.dbf mode=edit
Password:

BBED: Release 2.0.0.0.0 - Limited Production on Sun Sep 18 22:14:59 2011

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

BBED> set blocksize 8192
BLOCKSIZE 8192

BBED> set block 13
BLOCK# 13

BBED> map /v

File: maclean.dbf (0)
Block: 13 Dba:0x00000000
------------------------------------------------------------
KTB Data Block (Table/Cluster)

struct kcbh, 20 bytes @0
ub1 type_kcbh @0
ub1 frmt_kcbh @1
ub1 spare1_kcbh @2
ub1 spare2_kcbh @3
ub4 rdba_kcbh @4
ub4 bas_kcbh @8
ub2 wrp_kcbh @12
ub1 seq_kcbh @14
ub1 flg_kcbh @15
ub2 chkval_kcbh @16
ub2 spare3_kcbh @18

struct ktbbh, 96 bytes @20
ub1 ktbbhtyp @20
union ktbbhsid, 4 bytes @24
struct ktbbhcsc, 8 bytes @28
b2 ktbbhict @36
ub1 ktbbhflg @38
ub1 ktbbhfsl @39
ub4 ktbbhfnx @40
struct ktbbhitl[3], 72 bytes @44

struct kdbh, 14 bytes @124
ub1 kdbhflag @124
b1 kdbhntab @125
b2 kdbhnrow @126
sb2 kdbhfrre @128
sb2 kdbhfsbo @130
sb2 kdbhfseo @132
b2 kdbhavsp @134
b2 kdbhtosp @136

struct kdbt[1], 4 bytes @138
b2 kdbtoffs @138
b2 kdbtnrow @140

sb2 kdbr[200] @142

ub1 freespace[4725] @542

ub1 rowdata[2921] @5267

ub4 tailchk @8188

BBED> find /x c203

File: maclean.dbf (0)
Block: 13 Offsets: 5271 to 5782 Dba:0x00000000
------------------------------------------------------------------------
c2030f63 6f727275 7074696f 6e206865 72652c00 0202c203 0766696e 64206d65
2c000203 c2026407 66696e64 206d652c 000203c2 02630766 696e6420 6d652c00
0203c202 62076669 6e64206d 652c0002 03c20261 0766696e 64206d65 2c000203
c2026007 66696e64 206d652c 000203c2 025f0766 696e6420 6d652c00 0203c202
5e076669 6e64206d 652c0002 03c2025d 0766696e 64206d65 2c000203 c2025c07
66696e64 206d652c 000203c2 025b0766 696e6420 6d652c00 0203c202 5a076669
6e64206d 652c0002 03c20259 0766696e 64206d65 2c000203 c2025807 66696e64
206d652c 000203c2 02570766 696e6420 6d652c00 0203c202 56076669 6e64206d
652c0002 03c20255 0766696e 64206d65 2c000203 c2025407 66696e64 206d652c
000203c2 02530766 696e6420 6d652c00 0203c202 52076669 6e64206d 652c0002
03c20251 0766696e 64206d65 2c000203 c2025007 66696e64 206d652c 000203c2
024f0766 696e6420 6d652c00 0203c202 4e076669 6e64206d 652c0002 03c2024d
0766696e 64206d65 2c000203 c2024c07 66696e64 206d652c 000203c2 024b0766
696e6420 6d652c00 0203c202 4a076669 6e64206d 652c0002 03c20249 0766696e
64206d65 2c000203 c2024807 66696e64 206d652c 000203c2 02470766 696e6420
6d652c00 0203c202 46076669 6e64206d 652c0002 03c20245 0766696e 64206d65

t1=200の偏差値は5271と探し出した。

では、fbの偏差値は5271 -4 = 5267

BBED> set offset 5267

OFFSET 5267

BBED> d
File: maclean.dbf (0)
Block: 13 Offsets: 5267 to 5778 Dba:0x00000000
------------------------------------------------------------------------
2c020202 c2030f63 6f727275 7074696f 6e206865 72652c00 0202c203 0766696e
64206d65 2c000203 c2026407 66696e64 206d652c 000203c2 02630766 696e6420
6d652c00 0203c202 62076669 6e64206d 652c0002 03c20261 0766696e 64206d65
2c000203 c2026007 66696e64 206d652c 000203c2 025f0766 696e6420 6d652c00
0203c202 5e076669 6e64206d 652c0002 03c2025d 0766696e 64206d65 2c000203
c2025c07 66696e64 206d652c 000203c2 025b0766 696e6420 6d652c00 0203c202
5a076669 6e64206d 652c0002 03c20259 0766696e 64206d65 2c000203 c2025807
66696e64 206d652c 000203c2 02570766 696e6420 6d652c00 0203c202 56076669
6e64206d 652c0002 03c20255 0766696e 64206d65 2c000203 c2025407 66696e64
206d652c 000203c2 02530766 696e6420 6d652c00 0203c202 52076669 6e64206d
652c0002 03c20251 0766696e 64206d65 2c000203 c2025007 66696e64 206d652c
000203c2 024f0766 696e6420 6d652c00 0203c202 4e076669 6e64206d 652c0002
03c2024d 0766696e 64206d65 2c000203 c2024c07 66696e64 206d652c 000203c2
024b0766 696e6420 6d652c00 0203c202 4a076669 6e64206d 652c0002 03c20249
0766696e 64206d65 2c000203 c2024807 66696e64 206d652c 000203c2 02470766
696e6420 6d652c00 0203c202 46076669 6e64206d 652c0002 03c20245 0766696e

/* 指定した行アドレスは5267だど探し出せる。既存するflagはまともな0x2cである  */

BBED> x /rnc

rowdata[0] @5267
----------
flag@5267: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@5268: 0x02
cols@5269: 2

col 0[2] @5270: 200
col 1[15] @5273: corruption here

flag を 0xff BBED> modify /x 0xffに修正してください。

Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y
File: maclean.dbf (0)
Block: 13 Offsets: 5267 to 5778 Dba:0x00000000
------------------------------------------------------------------------
ff020202 c2030f63 6f727275 7074696f 6e206865 72652c00 0202c203 0766696e
64206d65 2c000203 c2026407 66696e64 206d652c 000203c2 02630766 696e6420
6d652c00 0203c202 62076669 6e64206d 652c0002 03c20261 0766696e 64206d65
2c000203 c2026007 66696e64 206d652c 000203c2 025f0766 696e6420 6d652c00
0203c202 5e076669 6e64206d 652c0002 03c2025d 0766696e 64206d65 2c000203
c2025c07 66696e64 206d652c 000203c2 025b0766 696e6420 6d652c00 0203c202
5a076669 6e64206d 652c0002 03c20259 0766696e 64206d65 2c000203 c2025807
66696e64 206d652c 000203c2 02570766 696e6420 6d652c00 0203c202 56076669
6e64206d 652c0002 03c20255 0766696e 64206d65 2c000203 c2025407 66696e64
206d652c 000203c2 02530766 696e6420 6d652c00 0203c202 52076669 6e64206d
652c0002 03c20251 0766696e 64206d65 2c000203 c2025007 66696e64 206d652c
000203c2 024f0766 696e6420 6d652c00 0203c202 4e076669 6e64206d 652c0002
03c2024d 0766696e 64206d65 2c000203 c2024c07 66696e64 206d652c 000203c2
024b0766 696e6420 6d652c00 0203c202 4a076669 6e64206d 652c0002 03c20249
0766696e 64206d65 2c000203 c2024807 66696e64 206d652c 000203c2 02470766
696e6420 6d652c00 0203c202 46076669 6e64206d 652c0002 03c20245 0766696e

BBED> x /rnc

rowdata[0] @5267
----------
flag@5267: 0xff (KDRHFN, KDRHFP, KDRHFL, KDRHFF, KDRHFD, KDRHFH, KDRHFC, KDRHFK)
lock@5268: 0x02
cols@5269: 0
ckix@5270: 2

BBED> sum apply

Check value for File 0, Block 13:
current = 0x0000, required = 0x0000

私たち使っているbbedのverifyコマンドはデータブロックをテストして、トラブルflagを検出できる。

BBED> verify
DBVERIFY - Verification starting
FILE = maclean.dbf
BLOCK = 12

kdrchk: row is marked as both a Key and Clustered

prow=0x7f5335f05693 flag=0xff
Block Checking: DBA = 25165836, Block Type = KTB-managed data block
data header at 0x7f5335f0427c
kdbchk: bad row tab 0, slot 199
Block 12 failed with check code 6251

DBVERIFY - Verification complete

Total Blocks Examined : 1
Total Blocks Processed (Data) : 1
Total Blocks Failing (Data) : 1
Total Blocks Processed (Index): 0
Total Blocks Failing (Index): 0
Total Blocks Empty : 0
Total Blocks Marked Corrupt : 0
Total Blocks Influx : 0

dbvツールもこのようなロジックエラを検出できる。

[oracle@rh2 ~]$ dbv file=maclean.dbf

DBVERIFY: Release 10.2.0.4.0 - Production on Sun Sep 18 22:27:49 2011

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

DBVERIFY - Verification starting : FILE = maclean.dbf
kdrchk: row is marked as both a Key and Clustered
prow=0x7f9ef25f7693 flag=0xff
Block Checking: DBA = 25165836, Block Type = KTB-managed data block
data header at 0x7f9ef25f627c
kdbchk: bad row tab 0, slot 199
Page 12 failed with check code 6251

DBVERIFY - Verification complete

Total Pages Examined : 2560
Total Pages Processed (Data) : 1
Total Pages Failing (Data) : 1
Total Pages Processed (Index): 0
Total Pages Failing (Index): 0
Total Pages Processed (Other): 11
Total Pages Processed (Seg) : 0
Total Pages Failing (Seg) : 0
Total Pages Empty : 2548
Total Pages Marked Corrupt : 0
Total Pages Influx : 0
Highest block SCN : 691691 (0.691691)


Sqlplusに戻って、前に修正したデータ行をアクセスする。ORA-600[13013] [5001]エラを引き起こす:


SQL> alter system flush buffer_cache;

System altered.

SQL> update tv set t2='correct here' where t1=200;
update tv set t2='correct here' where t1=200
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [13013], [5001], [52937],
[25165836], [199], [25165836], [3], []

PLAN_TABLE_OUTPUT
---------------------------------------------------------
Plan hash value: 568795662

----------------------------------------------------------------------------
| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | UPDATE STATEMENT  |        |     1 |   115 |     2   (0)| 00:00:01 |
|   1 |  UPDATE           | TV     |       |       |            |          |
|*  2 |   INDEX RANGE SCAN| IND_TV |     1 |   115 |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("T1"=200)

SQL> select * from tv where t1=200;
select * from tv where t1=200
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [qertbFetchByRowID], [], [], [], [],
[], [], []

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1015724781

--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     1 |   115 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TV     |     1 |   115 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IND_TV |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("T1"=200)

ここで、トラブル行記録をupdateするときに、予想のとおり、ORA-00600:[13013], [5001]エラが現れた。けどACCESS BY INDEX ROWIDするときに、ORA-00600:[qertbFetchByRowID]エラになった。
解決策
1.バックアップがあれば、blockrecoveryを利用して、オンラインでトラブルブロックを解決できる:
RMAN> blockrecover datafile 6 block 12;
Starting blockrecover at 18-SEP-11
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=144 devtype=DISK
starting media recovery
media recovery complete, elapsed time: 00:00:01
Finished blockrecover at 18-SEP-11
だが、そのロジックエラは確かにOracle Bugを引き起こしたとしたら、blockrecoverも無効になる。この場合に、二つ目の方法を使ってください。

2. 二つ目はバックアップもないデータベースあるいはリカバリデータブロックが使えなくなった場合に対して利用できる。10231トランザクションを設定し、そのテーブルをctasコピできる。けど、これによって、トラブルがあった行記録をなくなるかもしれない:
SQL> alter session set events ‘10231 trace name context forever, level 10’
SQL> Create table.TABLE_COPY as select * from TABLE;

より多くのkdrchk関数の情報はこちら:


Add check for continued row piece pointing to itself with
corruption description:

"kdrchk: Row piece pointing to itself"

DB_BLOCK_CHECKING = MEDIUM will check for row pieces where the
next rowid (nrid) points to itself (chained row points to itself).
It produces error ORA-600 [kddummy_blkchk] or ORA-600 [kdBlkCheckError]
with check code [6266] (3rd ORA-600 argument).

DBVERIFY reports the same corruption description if the block is corrupt on disk.

RMAN when run with the CHECK LOGICAL option reports it as
     corruption_type=CORRUPT/LOGICAL in v$database_block_corruption.

"ANALYZE TABLE  VALIDATE STRUCTURE" produces error ORA-1498 and trace file
shows the same corruption description.

With this fix in place DBMS_REPAIR can be used to identify and mark the affected
block as Soft Corrupt producing error ORA-1578 and it can be skipped it for DML's
using DBMS_REPAIR.SKIP_CORRUPT_BLOCKS.

 [CM][SG][event 1][domain Q423][mem 0] Joining shared group
  kdrchk: column length 0 but not null
            prow=0x2a97f4d9d6 flag=0x2c column=57
  Block Checking: DBA = 29635651, Block Type = KTB-managed data block
  data header at 0x2a97f4be7c
  kdbchk: bad row tab 0, slot 2
  data_block_dump,data header at 0x2a97d113d8
  data_block_dump,data header at 0x2a97d113d8

 kdrchk: found invalid symbol reference 48
  reference to delete symbol
  valid symbol range [0,78)
  Block Checking: DBA = 411055291, Block Type = KTB-managed data block
  data header at 0x68a3f4
  kdbchk: bad row tab 0, slot 4
  Page 13499 failed with check code 6265

kdrchk: C and neither of H or F
          prow=0x4282803ae flag=0x41
Block Checking: DBA = 322963095, Block Type = KTB-managed data block
data header at 0x42828007c

kdrchk: column length 0 but not null
          prow=0x10021035e flag=0x2c column=40
Block Checking: DBA = 25189259, Block Type = KTB-managed data block
data header at 0x10020fe7c
kdbchk: bad row tab 0, slot 0
Page 23435 failed with check code 6264
kdrchk: column length 0 but not null
          prow=0x1002122e5 flag=0x2c column=40
Block Checking: DBA = 25189260, Block Type = KTB-managed data block

kdrchk:  row is marked as both a Key and Clustered
prow=0xd2bfa981 flag=0xff
File#67, Block#74754

kdbchk: bad row tab 0, slot 0
kdrchk:  no columns, but has one of P or N
          prow=0x934fbffa flag=0x31

DIAGNOSTIC ANALYSIS:
====================
A look at the block dump in the analyze trace file revealed two very
suspicious looking rows:

tab 0, row 0, @0x1ede
tl: 2 fb: --HD---N lb: 0x0
tab 0, row 1, @0x1edc
tl: 2 fb: --HD---N lb: 0x0

The flag bytes in these rows look incorrect.



Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *