oracle数据文件内部BLOCK结构详解

2025-05-10Oracle / RAC

datafile block block size :8192

                Offset
                0
                1
                2
                3
                4
                5
                6
                7
                8
                9
                a
                b
                c
                d
                e
                f








                00014000
                06
                A2
                00
                00
                0A
                00
                40
                01
                0E
                89
                43
                00
                00
                00
                05
                02
                type
                frmt
                spare1/2_kcbh
             | 
                rdba
                scn
                seq
                flg
                                **1 : 20 bytes**
                             | 

                                type:
                                0x06=trans data defined in kcb.h
                                frmt:
                                8i~9i 都是0x02 10.1.0 2k: 0x62 4k:0x82 8k:0xa2 16k:0xc2 (logfile 0x22 512 bytes)
                                spare1/2_kcbh:
                                ub1 spare1_kcbh this field is no longer used (old inc#, now always 0)
                                ub1 spare2_kcbh this field is no longer used (old ts#, now always 0)
                                rdba:
                                0x0140000a 转换成2进制后它的前10 bit 表示file id 后22 bit 表示的block id
                                可以看出一个tablespace 可以有1023 个datafile ,每个datafile可以有4M 的block
                                10G 出现的 big datafile 这里表示的就是block id了 没有file id
                                9.2.0试验过一个tablespace可以有1023个datafile 一个object可以存放在1023个datafile中
                                scn:
                                scn: 0x0000.0043890e
                                seq:
                                A sequence number incremented for each change to a block at the same SCN
                                A new SCN is allocated if the sequence number wraps.
                                同一个SCN影响这个block中的行数大于 254 行就会为这个事务分配一个新的SCN
                                如下面的操作就可能引起同一个SCN但影响的同一个block 中的行超过254行
                                "delete from table_name"
                                影响的行数(最大254) 是用从 0x01 到 0xfe 表示的
                                当这个byte 的数据为 0xff 的时候标志这个 block 坏调了---> ora-01578
                                Sequence number:
                                SEQ -> 0 /* non-logged changes - do not advance seq# */
                                SEQ -> (UB1MAXVAL-1)/* maximum possible sequence number */
                                SEQ -> (UB1MAXVAL) /* seq# to indicate a block is corrupt,equal to FF. soft corrupt*/
                                0xff : When present it indicates that the block has been marked as corrupt by Oracle. either by the db_block_checking functionality or the equivalent events (10210 for data blocks, 10211 for index blocks, and 10212 for cluster blocks) when making a database change, or by the DBMS_REPAIR.FIX_CORRUPT_BLOCKS procedure, or by PMON after an unsuccessful online block recovery attempt while recovering a failed process, or by RMAN during a BACKUP, COPY or VALIDATE command with the CHECK LOGICAL option. Logical corruptions are normally due to either recovery through a NOLOGGING operation, or an Oracle software bug.
                                flg:
                                as defined in kcbh.h

define KCBHFNEW 0x01 /* new block – zeroed data area */

define KCBHFDLC 0x02 /* Delayed Logging Change advance SCN/seq */

define KCBHFCKV 0x04 /* ChecK Value saved-block xor's to zero */

define KCBHFTMP 0x08 /* Temporary block */

                                这是一个可以组合的值 也就是说有为 6 的时候是 2,4 两种情况的组合
                                Block structure as defined in kcbh.h:
                                struct kcbh
                                {ub1 type_kcbh; /* Block type* /
                                ub1 frmt_kcbh; /* #define KCBH_FRMT8 2 */
                                ub1 spare1_kcbh;
                                ub1 spare2_kcbh;
                                krdba rdba_kcbh; /* relative DBA /
                                ub4 bas_kcbh; /* base of SCN */
                                ub2 wrp_kcbh; /* wrap of SCN */
                                ub1 seq_kcbh; /* sequence # of changes at same scn */
                                ub1 flg_kcbh;
                                ub2 chkval_kcbh;
                                };
                00014010
                00
                00
                00
                00
                01
                00
                17
                00
                54
                D2
                00
                00
                0A
                89
                43
                00
                chkval
             | 
                spare3_kcbh
             | 
                typ
                ?
                seg/obj
                csc
                                spare3_kcbh :
                                ub2 spare3_kcbh

                                **2 : 24 bytes (总计44bytes)**
                             | 
                                typ :
                                1 - DATA 2 index
                                改成3了在10.1.0 上引起了ora-600[2032]然后ORA-27101: shared memory realm does not exist
                                oracle进行查询的时候是根据 obj$表中的情况来判断对象的类型的,不是根据这个typ
                                也就是说如果有一个表但改变表中block的这个标志位,一样可以查询出数据来,
                                但dump block 时会出错,ORA-00600: 内部错误代码,自变量: [4555], [0], [], [], [], [], [], []
                                错误中的 [0] 就是typ对应的数据
                                在10G中改变它后update这个block的数据commit可以但rollback的报错
                                ?
                                见过有其他值 但用编辑器改这个值 在 dump 文件中显示不出来变化
                                seg/obj:
                                0xd254
                                csc :
                                0x00.43890a The SCN at which the last full cleanout was performed on the block
                00014020
                00
                00
                E8
                1F
                02
                00
                03
                00
                00
                00
                00
                00
                04
                00
                0C
                00
                csc
             | 
                ?
             | 
                itc
                ?
                flg
                fsl
                fnx
                xid
                                **3 : 24 bytes * itl (2个itl总计92bytes)**
                             | 

                                ?
                                见过有其他值 但用编辑器改这个值 在 dump 文件中显示不出来变化
                                itc
                                ITL 条目的个数 max 255超过会报ORA-02207
                                ORA-00060 ORA-00054 可能是没空间分配itl条目了或它的争用引起的
                                在8i中 INITRANS default为1 , 9.2.0中 INITRANS default为2
                                flg
                                indicates that the block is on a freelist. Otherwise the flag is -
                                9i 的ASSM 的情况下这个值为 E
                                ixora 上说他占用 2 bytes 但我下面的试验和他的结果有一定的出入
                                我观察到的情况是 : Object id on Block? Y flg: O ver: 0x01
                                上面的3项是用同一个 byte 来表示的

flg: O ver: 0x01 Object id on Block? Y

                                从我的观察中 dump 出来的文件中 flg ver Object id on Block
                                他们共同占用的这个一个字节 他的规律可以从下面的情况看出
                                2进制数据 flg ver Object id on Block?
                                0x00 - 0x00 N
                                0x01 0 0x00 N
                                0x02 - 0x01 Y
                                0x03 0 0x01 Y
                                0x04 - 0x02 Y
                                0x05 0 0x02 Y
                                0x06 - 0x03 Y
                                0x07 0 0x03 Y
                                0x08 - 0x04 N
                                0x09 0 0x04 N
                                0x0a - 0x05 Y
                                0x0b 0 0x05 Y
                                0x0c - 0x06 Y
                                0x0d 0 0x06 Y
                                0x0e - 0x07 Y
                                0x0f 0 0x07 Y
                                0x10 ... 类似上面的循环了 这种情况在9i上已经改变因为ASSM的出现
                                fsl :
                                Index to the first slot on the ITL freelist. ITL TX freelist slot
                                fnx :
                                自由列表中下一块的地址 Null if this block is not on a freelist 有数据例如: fnx: 0x1000029
                00014030
                50
                18
                00
                00
                96
                14
                80
                00
                B9
                07
                01
                00
                01
                20
                00
                00
                xid
                uba
                Lck Flag
             | 
                Scn/Fsc
             | 
                                xid :
                                Transaction ID (UndoSeg.Slot.Wrap)
                                值可以用select XIDUSN, XIDSLOT,XIDSQN from v$transaction;查到
                                This is comprised of the rollback segment number (2 bytes), the slot number
                                in the transaction table of that rollback segment (2 bytes), and the number
                                of times use of that transaction table has wrapped (4 bytes).

                                uba :
                                Undo address (UndoDBA.SeqNo.RecordNo)
                                The location of the undo for the most recent change to this block by this transaction. This is comprised of the DBA of the rollback segment block (4 bytes), the sequence number (2 bytes), and the record number for the change in that undo block (1 byte), plus 1 unused byte.
                                Lck Flag:
                                Lck 锁定的row数 这里还用到了下一个 byte 的数据
                                2 对应的二进制表示为 0010 正好和dump文件中的 --U- 吻合
                                flag 1 nibble
                                C = Committed; U = Commit Upper Bound; T = Active at CSC; B = Rollback of this UBA gives before image of the ITL.
                                ---- = transaction is active, or committed pending cleanout
                                C--- = transaction has been committed and locks cleaned out
                                -B-- = this undo record contains the undo for this ITL entry
                                --U- = transaction committed (maybe long ago); SCN is an upper bound
                                ---T = transaction was still active at block cleanout SCN
                                Lck 3 nibbles
                                The number of row-level locks held in the block by this transaction.
                                Scn/Fsc :
                                If the transaction has been cleaned out, this is the commit SCN or an upper bound thereof. Otherwise the leading two bytes contain the free space credit for the transaction - that is, the number of bytes freed in the block by the transaction
                                Scn = SCN of commited TX; Fsc = Free space credit (bytes)
                00014040
                0E
                89
                43
                00
                00
                00
                00
                00
                00
                00
                00
                00
                00
                00
                00
                00
                Scn/Fsc
                第2条itl 这里没使用
                00014050
                00
                00
                00
                00
                00
                00
                00
                00
                00
                00
                00
                00
                00
                01
                01
                00
                第2条itl 这里没使用
                flag
                ntab
                nrow
             | 
                                **4 : 14 bytes 从这个flag位置开始是data区 也是下面的行的offset的起始地址**
                             | 

                                flag :
                                N=pctfree hit(clusters), F=don't put on free list
                                K=flushable cluster keys. 当然还有别的标记: A ...
                                ntab :
                                这block中有几个table的数据 cluster这个就可能大于1
                                nrow :
                                block 有多少行数据
                00014060
                FF
                FF
                14
                00
                9B
                1F
                83
                1F
                83
                1F
                00
                00
                01
                00
                9B
                1F
                frre
             | 
                fsbo
             | 
                fseo
             | 
                avsp
             | 
                tosp
             | 
                offs
             | 
                nrow
             | 
                row offs
             | 
                                frre :
                                First free row index entry. -1=you have to add one.

                                fsbo :
                                Free Space Begin offset 出去row dict 后面的可以放数据的空间的起始位置
                                也可以看成是从这个区域的开始"flag"到最后一个 "row offs"占用的空间
                                fseo :
                                Free Space End offset ( 9.2.0 )参与db_block_checking的计算剩余空间
                                select 的时候oracle不是简单的根据offset定位row.这个值也是参与了定位row的
                                avsp :
                                Available space in the block (pctfree and pctused) ORA-01578
                                tosp :
                                Total available space when all TXs commit ( 9.2.0 )参与db_block_checking
                                offs :
                                偏移量 用 cluster 的时候可以看出值
                                nrow :
                                这个table有多少行数据
                                row offs :
                                这行数据相对的起始位置 after delete & commit is 0xffff
                00015FF0
                00
                00
                00
                00
                00
                00
                00
                2C
                01
                01
                01
                61
                05
                06
                0E
                89
                fb
                lb
                cc
                length
                data
                block tail
                                **5 : 用户数据**
                             | 

                                **6 : 4 bytes block tail**
                             | 
                                fb :
                                K = Cluster Key (Flags may change meaning if this is set to show HASH cluster)
                                C = Cluster table member
                                H = Head piece of row
                                D = Deleted row
                                F = First data piece
                                L = Last data piece
                                P = First column continues from previous piece
                                N = Last column continues in next piece
                                lb :
                                和上面的 ITL 的lck相对应 表示这行是否被 lock 了
                                cc :
                                有几列数据 这里只能表示255列 超过了就会有链接行
                                length :
                                这列的数据的长度是多少
                                0xfa ( 250 bytes ) 其实0xfb,0xfc,0xfd 也同样是250bytes
                                0xfe fb 00 ( 0xfb 00 表示的251 bytes 0xfe表示row的长度超过了250 bytes)
                                0xff 表示number 的 null 这也是oracle中null的表现形式排序的时候null最大了
                                字段的数据超过250字节是就用3bytes来表示字段的长度,因为如果是long类型它的字段再长
                                它在这个block中的数据的长度不会超过64K 所以最长用3bytes来表示行的长度已经够了.再长就链接行了
                                data :
                                'a'
                                block tail :
                                改这 block 最后的4 bytes 数据中的任意肯定ora-1578
                                第 1 byte : 对应开始的 seq
                                第 2 byte : 对应开始的 type
                                第3,4byte : 对应开始的scn的末2为 control file 这里是control seq

>

10.1.0~lgone@ONE.LG.OK> create table a(v varchar2(4000)) TABLESPACE t;

Table created.

10.1.0~lgone@ONE.LG.OK> insert into a values('a');

1 row created.

Start dump data blocks tsn: 17 file#: 5 minblk 10 maxblk 10 buffer tsn: 17 rdba: 0x0140000a (5/10) //// buffer tsn:

     数据文件对应的 tablespace 的 number   这只是dump文件中记录的数据而已
     block 中是没有记录 tablespace 的 number 的  

scn: 0x0000.0043890e seq: 0x05 flg: 0x02 tail: 0x890e0605 frmt: 0x02 chkval: 0x0000 type: 0x06=trans data Block header dump: 0x0140000a Object id on Block? Y seg/obj: 0xd254 csc: 0x00.43890a itc: 2 flg: O typ: 1 – DATA

 fsl: 0  fnx: 0x0 ver: 0x01

Itl Xid Uba Flag Lck Scn/Fsc 0x01 0x0004.00c.00001850 0x00801496.07b9.01 –U- 1 fsc 0x0000.0043890e 0x02 0x0000.000.00000000 0x00000000.0000.00 —- 0 fsc 0x0000.00000000

data_block_dump,data header at 0x87e125c //// data_block_dump,data header at 0x87e125c

     其实这个block不是直接从 data buffer 中 dump 出来的这个表示真正dump时 block 的数据区的起始位置
     也就是下面这部分开始的位置

=============== //// tsiz: hsiz: pbl: bdba: 在数据文件都是没有存储的 tsiz: 0x1fa0 //// Total data area size

                 8k的block: 8192-20(block head)-24(Transaction Header)-24*2(一个事务条)-4(block tail)=8096(0x1fa0)

hsiz: 0x14 //// Data header size 数据块头20个字节+数据块尾4个字节=24字节(0x14) pbl: 0x087e125c //// Pointer to buffer holding the block bdba: 0x0140000a

 76543210

flag=——– ntab=1 nrow=1 frre=-1 fsbo=0x14 fseo=0x1f9b avsp=0x1f83 tosp=0x1f83 0xe:pti[0] nrow=1 offs=0 0x12:pri[0] offs=0x1f9b block_row_dump: tab 0, row 0, @0x1f9b tl: 5 fb: –H-FL– lb: 0x1 cc: 1 col 0: [ 1] 61 end_of_block_dump End dump data blocks tsn: 17 file#: 5 minblk 10 maxblk 10

>

>

block 坏掉了还可以报:

ORA-600 (4519) Cache layer block type is incorrect
ORA-600 (4393) Check for Type for Segment header with free list
ORA-600 (4136) Check Rollback segment block
ORA-600 (4154) Check Rollback segment block 
Ora-600[kcbzpb_1],[d],[kind],[chk] gets signaled when the block got corrupted in memory.
The only way it should be bad is if a stray store into memory destroyed the header or tail.
d = blocknumber, kind= kind of corruption detected,chk = checksum flag
ora-600[3398] and ora-600[3339]
ora-600[3398] is not in oracle 8.
ora-600[3398] means it failed a verification check before writing back to disk,  so it must
    be an in-memory corruption.
ora-600[3339] comes with ora-1578 and means either disk corruption or in memory corruption after read.
ora-600 [3339] has been removed from 7.2+
From 7.2+  ora-600 [3398] has become ora-600 [3374] with some checks added.

2进制存储格式

           ALTER SESSION SET EVENTS '10289 trace name context forever, level 1';
           ALTER SESSION SET EVENTS '10289 trace name context off';

>

Similar Posts:

  • oracle 跟踪文件和转储命令详解
  • 一.Oracle跟踪文件 Oracle跟踪文件分为三种类型: 一种是后台报警日志文件,记录数据库在启动.关闭和运行期间后台进程的活动情况,如表空间创建.回滚段创建.某些alter命令.日志切换.错误消息等.在数据库出现故障时,应首先查看该文件,但文件中的信息与任何错误状态没有必然的联系.后台报警日志文件保存BACKGROUND_DUMP_DEST参数指定的目录中,文件格式为SIDALRT.LOG. 另一种类型是DBWR.LGWR.SMON等后台进程创建的后台跟踪文件.后台跟踪文件根据后台进程运行

  • ORACLE数据泵 expdp/impdp使用详解(转)
  • ORACLE使用EXPDP和IMPDP数据泵进行导出导入的方法 使用expdp和impdp时应该注重的事项: 1.exp和imp是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. 2.expdp和impdp是服务端的工具程序,他们只能在oracle服务端使用,不能在客户端使用. 3.imp只适用于exp导出的文件,不适用于expdp导出文件:impdp只适用于expdp导出的文件,而不适用于exp导出文件. 4.对于10g以上的服务器,使用exp通常不能导出0行数据的空表,而此时必须

  • ORACLE语句优化53条规则详解(转)
  • ORACLE语句优化53条规则详解(转) 1.选用适合的ORACLE优化器 ORACLE的优化器共有3种: a.RULE(基于规则) b.COST(基于成本) c.CHOOSE(选择性) 设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS.也可以在SQL句级或是会话(session)级对其进行覆盖. 为了使用基于成本的优化器(CBO,Cost-Based Optimizer),你

  • Oracle语句优化53个规则详解(转载)
  • Oracle语句优化53个规则详解(转载) Oracle语句优化53个规则详解 1. 选用适合的ORACLE优化器 ORACLE的优化器共有3种: a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性) 设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS . 你当然也在SQL句级或是会话(session)级对其进行覆盖. 为了使用基于成本的优化

  • python类:class创建、数据方法属性及访问控制详解
  • 在Python中,可以通过class关键字定义自己的类,然后通过自定义的类对象类创建实例对象. python中创建类 创建一个Student的类,并且实现了这个类的初始化函数"__init__": class Student(object): count = 0 books = [] def __init__(self, name): self.name = name 接下来就通过上面的Student类来看看Python中类的相关内容. 类构造和初始化 "__init__&q

  • Nero刻录ISO文件的过程步骤详解
  • 常见的镜像文件格式有ISO.BIN.IMG.TAO.DAO.CIF.FCD. Nero刻录ISO文件的过程步骤详解(附Nero下载地址无需注册) 刻录ISO文件的软件其实很多–以Nero(德国公司出品的专业光盘烧录软件)刻录CD系统盘为例子. 我在这里讲的是用Nero刻录一般的ISO光盘镜像文件—为什么叫一般ISO光盘镜像文件呢?因为刻录ISO光盘 镜像还有超刻录方法.(指要刻录的文件大于700M或小于870M:一般的CD光盘最大的也就是870M左右) 那么如何使用Nero Burni

  • Java构造和解析Json数据的两种方法详解二
  • 在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Json数据的方法示例. 用json-lib构造和解析Json数据的方法详解请参见我上一篇博文:Java构造和解析Json数据的两种方法详解一 一.介绍 org.json包是另一个用来beans,collections,maps,java arrays 和XML和JSON互相转换的包,主要就是用来解析Js

  • 在线移动oracle 数据文件位置
  • 在线移动oracle 数据文件 Oracle数据文件可以在数据库OPEN的时候被重命名或移动,但此时表空间必须为只读,这将允许用户从表中查询,但禁止他们这样做的插入,更新和删除,在表空间至于只读状态的时候,冻结数据文件块头.阻止更新数据文件块头,此时才能在线拷贝数据文件 <注:system表空间除外,system 表空间无法offline> 本测试以TEST表空间为例 SQL> select * from v$version; BANNER ———————–

  • Oracle数据文件移动方法
  • 6.2 参考资料:Oracle数据库移动方法 这里所指"数据库移动"是将Oracle数据文件(系统数据文件或用户数据文件).控制文件.重做日志移动至新的存储路径,并修改Oracle相关配置,使之可以重新正常启动.这种应用常见于系统扩容后的Oracle数据存储路径的调整. 以下面为例,移动系统表空间的相关文件位置,并重新配置Oracle.假设原存储路径为/oradata,新存储路径为/oratest. 6.2.1 移动数据库文件 1) 获取数据库相关信息 查看一下数据库的文件内容: sq