上周在客户那里遇到了一例由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
本文转自maclean_007 51CTO博客,原文链接:http://blog.51cto.com/maclean/1278069