`

oracle block 格式

 
阅读更多

create table t(n number); 

insert into t values(1);   --- 从 dbms_rowid 中看出table t 的数据在datafile 4 的第3个 block 上 

alter system dump datafile 4 block 3; 

下面是 dump 的文件的信息 

还可以用下面的语句然后再用上面的 dump 语句看内存中 block 的2进制存储格式 

但这内存中的2进制格式和datafile中block数据表示的顺序会略有不同可能是内存寻址的缘故吧 

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

ALTER SESSION SET EVENTS '10289 trace name context off'; 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

                     下面的是 udump 目录下面 dump 文件的信息 


----------------------- 第一部分 


buffer tsn: 7 rdba: 0x01000003 (4/3) 

scn: 0x0000.000802a5 seq: 0x01 flg: 0x02 tail: 0x02a50601 

frmt: 0x02 chkval: 0x0000 type: 0x06=trans data 


--- buffer tsn:         数据文件对应的 tablespace 的 number   这只是dump文件中记录的数据而已 

---                                               block 中是没有记录 tablespace 的 number 的 

--- rdba:    4 bytes    datafile 中 block 的地址 标示的第几个 block 

--- scn:     6 bytes    system change number 

--- seq:     1 byte     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 

--- flg:     1 byte     1 = virgin block 

---                     2 = last change to the block was for a cleanout operation 

---                     4 = checksum value is set 

---                     8 = temporary data 

---                     这是一个可以组合的值 也就是说有为 6 的时候是 2,4 两种情况的组合 

--- tail:    4 bytes    这是记录在 block 的最后面的 4 bytes 的数据 

---                         dump文件中只是把他写在了前面而已 

--- frmt:    1 byte     oracle 8 以后看见的都是 0x02 

--- chkval: 2 bytes    在 init 文件中设置了 db_block_checksum=true 才有值 

--- type:    1 byte     这个 block 的类型 这里主要看 0x06 这种 因为这种是用来存用户数据的 

---                         其他的类型可以参考http://www.ixora.com.au/notes/cache_block_types.htm 


----------------------- 第二部分 

Block header dump: 0x01000003 

Object id on Block? Y 

seg/obj: 0x614a csc: 0x00.802a3 itc: 1 flg: O typ: 1 - DATA 

     fsl: 0 fnx: 0x0 ver: 0x01 

      

--- seg/obj: 4 bytes    这里是16进制的 对应 sys.obj$.obj# 数据字典的数据 

--- csc:     6 bytes    The SCN at which the last full cleanout was performed on the block 

--- itc:     1 byte     下面的Itl事务条的个数 8.1.7的文档上面说可以使用 INITRANS 在建表的时候 

---                       限制这个值的大小(max 255超过会报ORA-02207) 但要考虑block 的空间是否够 

---                       表在8i中 INITRANS default为1 , 9.2.0中 INITRANS default为2 

---                       Yong Huang 说有些时候发生ORA-00060可以把表的 INITRANS 设置大点 

---                       ixora 上说当block的空间不够创建一个ITL的时候一样可能引起ORA-00054 

--- flg:     2 bytes    0 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 来表示的 

--- typ:     1 byte     1 为 table ; 2 为 index. oracle进行查询的时候是根据 obj$表中的情况来判断对象的类型的,不是根据这个typ。 


也就是说如果有一个表但改变表中block 

---                       的这个标志位,一样可以查询出数据来,但dump block 时会出错,如下面的ora 

---                       ORA-00600: 内部错误代码,自变量: [4555], [0], [], [], [], [], [], [] 

---                       错误中的 [0] 就是typ对应的数据 

--- fsl:     1 byte     Index to the first slot on the ITL freelist. ITL TX freelist slot 

--- fnx:     4 bytes    自由列表中下一块的地址 Null if this block is not on a freelist 

---                       有数据例如: fnx: 0x1000029 

--- ver:     1 byte     format (version) 这个数据没有看到相关的文档介绍 从ixora上说是占用1byte 

---                       但我从下面的2进制文件中看到的有不同 下面有介绍 

--- unused: 4 bytes    在这里还有4 bytes 的空闲的空间 但在上面的 dump 文件上是没显示出来的 

---                        这个unused 的4 bytes是 ixora 上面的说法 

---     9i 的 ASSM 的 " fsl: 0 fnx: 0x0 ver: 0x01 "这一段数据的情况已经改变了 


----------------------- 第三部分 

Itl           Xid                  Uba                      Flag Lck        Scn/Fsc 

0x01   xid: 0x0003.045.000000b4    uba: 0x0080170a.00c7.36 --U-    1 fsc 0x0000.000802a5 


--- 这是 oracle 用来记录事务信息的部分 这里显示的只有一个ITL条 有多少个ITL条是可以动态增加的 

--- 只要 block 中的空间足够 可以定义初始化的 ITL 条的个数 用 INITRANS 这storage 参数 

--- 这里有多少个 ITL 可以从上面 "第二部分" 的 "itc:" 看出来 

--- 这部分牵扯 rollback segment 或 undo tablespace 

--- Itl                 itl 的序号 

--- xid:     8 bytes    值可以用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:     8 bytes    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. 

--- flag     1 nibble   ---- = 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 6 bytes    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 

---         参考http://www.ixora.com.au/q+a/datablock.htm#end 

--- 


----------------------- 第四部分 

data_block_dump 

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

tsiz: 0x1fb8 

hsiz: 0x14 

pbl: 0x02476c44 

bdba: 0x01000003 

flag=----------- 

ntab=1 

nrow=1 

frre=-1 

fsbo=0x14 

fseo=0x1fb2 

avsp=0x1f9b 

tosp=0x1f9b 

0xe:pti[0] nrow=1 offs=0 

0x12:pri[0] offs=0x1fb2 


---       tsiz:    hsiz:   pbl:   bdba: 在数据文件都是没有存储的 

--- tsiz:        除了上面的3部分和block尾部的4个字节剩下的空间 0x1fb8就是8120字节 8k的block: 

---              8192-20(block head)-24(Transaction Header)-24(一个事务条)-4(block tail)=8120 

--- hsiz:        数据块头20个字节+数据块尾4个字节=24字节(0x14) 

--- pbl:         ptr to buffer holding the block 我是用的专用模式dump的datafile中的block出来 

---              在同一个session的dump文件中 dump 出来的block 的这个都是同一个值 

--- bdba:        和第一部分中的rdba 一个意思           

--- flag         1 byte     N=pctfree hit(clusters), F=don't put on free list 

---                         K=flushable cluster keys. 当然还有别的标记: A ... 

--- ntab         1 byte     这block中有几个table的数据   cluster这个就可能大于1 

--- nrow         2 bytes    block 中有多少行数据 

--- frre         2 bytes    First free row index entry. -1=you have to add one. 

--- fsbo         2 bytes    Free Space Begin offset 

--- fseo         2 bytes    Free Space End offset 

--- avsp         2 bytes    Available space in the block    <pctfree and pctused 

--- tosp         2 bytes    Total available space when all TXs commit 

--- 0xe: nrow    2 bytes    block 中的这个table有多少行数据 

--- 0xe: offs    2 bytes    偏移量 用 cluster 的时候可以看出值 


----------------------- 第五部分 

block_row_dump: 

tab 0, row 0, @0x1fb2 

tl: 6 fb: --H-FL-- lb: 0x1 cc: 1 

col 0: [ 2] c1 02 

end_of_block_dump 


--- tl:     这条记录中的长度 包括row head 的一般情况的 3 字节和表示数据长度的1字节和数据本身的长度 

--- fb:   1 byte   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:   1 byte   和上面第三部分的 ITL 的lck相对应 表示这行是否被 lock 了 

--- cc:   1 byte   表示这行有几列数据 

--- col 0: [ 2] : 1 byte 表示这行的这列的长度 

--- c1 02 :        这就是table中的数据 "1" 可以通过下面的语句看 oracle真正使用的是 

---                那些16进制的数据来表示的用户数据 select dump(col_name,16) from table_name; 


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 


       下面的数据就是上面的 dump 文件对应的2进制文件 我依照 2 进制数据的顺序解释内容 


------------------------ 下面的对应上面dump 文件的第一部分 

Offset      0 1 2 3 4 5 6 7   8 9 A B C D E F 


00006000   06 02 00 00 03 00 00 01 A5 02 08 00 00 00 01 02   

00006010   00 00 00 00 


--- 06               :   type: 0x06=trans data (对应上面dump文件中的内容) 

--- 02               :   frmt: 0x02 

--- 00 00            :   filler 应该是 unused 上面的dump文件中并没有显示这部分内容 

--- 03 00 00 01      :   rdba: 0x01000003 在同一个 tablespace 中是唯一的 当 datafile 中可能不唯一 

---                        来看看他的规律 :连续建4个 datafile 他们的第一block为 

---                        0x 01 00 04 01 

---                        0x 01 00 08 01 

---                        0x 01 00 0c 01 

---                        0x 01 00 00 02 

---                        对应的数据在是 0x01040001 , 0x01080001 , 0x010c0001 , 0x02000001 

---                        这就可以看出一个 datafile 的最大的容量是 0x01040001~0x0107ffff 总共是 

---                        4M(因为还有一个datafile head)个block 如果block 是8k 一个datafile就是 32G 

---                        这就是oracle 的文档上面对 oracle 的 datafile (8k的时候)最大 32G 的原因 

---                        同样可以看出一个 tablespace 的datafile 可以从 0x0100 到 0xfffe 就是1023 

---                        个 datafile 这也是 oracle 的文档上面说一个tablesapce可以有1022 个datafile 

---                        的原因(其实一个 tablespace 可以有 1023 个 datafile   我建过) 

---                        oracle10G中 block 的big datafile 的这段数据的情况是0x00000001~0xffffffff 

---                        这也是为什么一个 big datafile 的tablesapce只有一个datafile 并且最大值为 

---                        32T (8k的时候 : 4G*8k=32T ; 32k的数据块的时候为128T) 

--- A5 02 08 00 00 00 : scn: 0x0000.000802a5   oracle是c语言写的 这6位不正好是一个 unsigned long 

---                        和 unsigned int的组合 

--- 01                : seq: 0x01 

--- 02                : flg: 0x02 

--- 00 00             : chkval: 0x0000 在 init 中设置了 db_block_checksum=true 才有值 

--- 00 00             : unused 上面的dump文件中并没有显示这部分内容 

---    上面的20个bytes的数据任改其中的值肯定发生ORA-XXXXX(不一定就是ora-01578 我还看见过ora-600) 

                                             



------------------------ 下面的对应上面dump 文件的第二部分 


                       01 00 00 00 4A 61 00 00 A3 02 08 00   

00006020   00 00 00 00 01 00 03 00 00 00 00 00 


--- 01                :   typ: 1 - DATA 

--- 00                :   只见过 0x00 没见过其他的值 don't know 

--- 00                :   见过有其他值 但用编辑器改这个值 在 dump 文件中显示不出来变化 

--- 00                :   没见变过其他的值 don't know 

--- 4A 61 00 00       :   seg/obj: 0x614a 

--- A3 02 08 00 00 00 :   csc: 0x00.802a3 

--- 00 00             :   见过有其他值 但用编辑器改这个值 在 dump 文件中显示不出来变化       

--- 01                :   itc: 1    下面的 ITL 条目的个数 

--- 00                :   见过有其他值 但用编辑器改这个值 在 dump 文件中显示不出来变化 

--- 03                :   flg: O         ver: 0x01        Object id on Block    

---                       从我的观察中 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的出现 

--- 00                :   fsl: 0 

--- 00 00 00 00       :   fnx: 0x0 


------------------------ 下面的对应上面dump 文件的第三部分 


                                                03 00 45 00   

00006030   B4 00 00 00 0A 17 80 00 C7 00 36 00 01 20 00 00   

00006040   A5 02 08 00 


--- 03 00 45 00 B4 00 00 00 :   xid: 0x0003.045.000000b4 

--- 0A 17 80 00 C7 00 36 00 :   uba: 0x0080170a.00c7.36 

--- 01 0                    :   Lck   锁定的row数 这里还用到了下一个 byte 的数据 

--- 2                        :   Flag 2 对应的二进制表示为 0010 正好和dump文件中的 --U- 吻合 

--- 00 00 A5 02 08 00        :   Scn/Fsc 


------------------------ 下面的对应上面dump 文件的第四部分 


                       00 01 01 00 FF FF 14 00 B2 1F 9B 1F   

00006050   9B 1F 00 00 01 00 B2 1F   


--- 00               :   flag 

--- 01 


              :   ntab 

--- 01 00            :   nrow 

--- FF FF            :   frre 

--- 14 00            :   fsbo 

--- B2 1F            :   fseo 

--- 9B 1F            :   avsp 

--- 9B 1F            :   tosp 

--- 00 00            :   0xe: offs 

--- 01 00            :   0xe: nrow 

--- B2 1F            :   0x12:pri[0] offs=0x1fb2 


------------------------ 下面的对应上面dump 文件的第五部分 


--- 这部分和上面的数据中间省略了很多 因为这列子中这些部分没存储数据 


00007FF0   00 00 00 00 00 00 2C 01 01 02 C1 02 


--- 这是 block 中存用户数据的地方 

--- 2C     :    fb: 

--- 01     :    lb: 这一行是否被lock 

--- 01     :    这条记录中有多少列的数据 从这里看出因为只用一个byte去记录这一行有多少列 

---               所以最多是255列 但一个表可以最多是1000列 如果table 的列大于255列 这里就会 

---               发生链接 根据一行记录的长度来看是 块内的链接或者是块与块直接的链接 

---               这也是为什么table 的设计会尽量少于255列的原因 

--- 02     :    第1列的数据的长度是多少 

--- C1 02 :    存储在 block 中的数据 "1" 

下面的对应上面dump 文件的第一部分的 "tail: 0x02a50601" 

                                                01 06 A5 02 

--- 这是用来效验 block 是否完整的标志 改这 block 最后的4 bytes 数据中的任意肯定ora-1578 


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

上面只是讲解了一个最简单的oracle 的block 的格式 其他还有很多的情况 如 cluster , index 等 

long , lob , long raw 这些在 block 中的表示因为数据长度的不同都会有不同的体现 


有的时候改动block 中的任意数据不一定会发生 ORA-01578 因为下面的两个参数没有设置为 true 

db_block_checking    db_block_checksum    

这两个参数对于system tablespace 默认都是true 所以改变 system tablespace 中的 

数据肯定会发生ORA-01578 

随着oracle版本的不断升级 oracle 对block中存储数据的正确性也在不断的提升要求 而且通过常规的 

手段想去了解 oracle block 的格式也可能越来越困难 

分享到:
评论

相关推荐

    Oracle数据块结构分析说明BLOCK结构详解

    Oracle是业界广泛使用的大型关系型数据库管理系统,其核心组成部分之一就是数据块结构(Block)。数据块是Oracle数据库中最小的存储单位,是操作系统中读写数据的基本单位,也是数据库实例中逻辑上存储数据的基本...

    oracle数据块(block)结构详解

    Oracle采用变长行格式,意味着不同行可以占用不同大小的空间,行数据区可以灵活调整以适应不同长度的行。 5. 空闲空间(Free Space):当行被删除或更新后,留下的空闲空间会被用来存储新的行数据,以提高空间利用...

    Oracle RAC 环境中 gc block lost 和私网通信性能问题的诊断

    Oracle RAC 环境中 gc block lost 和私网通信性能问题的诊断 Oracle RAC(Real Application Clusters)环境中,gc block lost 和私网通信性能问题是两个常见的性能瓶颈问题,本文将对这两个问题进行详细的分析和...

    Oracle_BBED(block_browse_and_editor)使用手册 英文版

    BBED(Oracle Block Brower and EDitor Tool),用来直接查看和修改数据文件数据的一个工具,是Oracle一款内部工具,可以直接修改Oracle数据文件块的内容,在一些极端恢复场景下比较有用。

    Oracle基本数据类型存储格式浅析

    《Oracle基本数据类型存储格式详解》 Oracle数据库中,数据类型的存储格式对于数据库的性能和空间利用率至关重要。本文将深入探讨Oracle的字符类型、数字类型、日期类型、ROWID类型和RAW类型的基本数据类型的存储...

    data_block物理结构的认识

    在 Oracle 数据库中,数据块(Data Block)是最基本的数据存储单位。一个数据块通常包含了一系列的记录,这些记录用于存储数据库表中的数据。理解数据块的物理结构对于深入掌握 Oracle 数据库的工作原理至关重要。 ...

    dumping oracle block

    总结来说,“dumping oracle block”是一项用于深入洞察Oracle数据库内部运作的技术,它可以提供超出常规查询所能提供的信息。通过学习如何进行块转储以及如何解析其结果,DBA能够更好地理解和解决问题,同时满足对...

    Oracle数据库block中AVG-SPACE的意义

    在Oracle数据库中,Block是数据存储的基本单位,而AVG_SPACE是与Block内部空间使用情况密切相关的统计信息。理解AVG_SPACE的意义对于优化数据库性能和管理空间至关重要。 AVG_SPACE表示在每个Block中的平均空闲空间...

    oracle dul source code

    9. **文件格式**:OracleBlock.java可能涉及到定义输出文件的格式,如CSV、固定宽度文件或自定义格式。这会影响数据的导入和分析过程。 10. **并行与分布式处理**:对于非常大的数据集,源代码可能利用并行或分布式...

    oracle 11g 数据文件头block 1解析

    oracle 11g 数据文件头block 1解析 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ##powered by :黄林杰_Huanglinjie ##version : 2023-v11 ##联系方式:17767151782 ##blog: https://blog.csdn.net/lixora/ ##info: ...

    oracle9i全备份导入到11g说明

    在不同的Oracle版本中,默认的`block size`可能不同,例如,Oracle 9i默认的`block size`为8K或16K,而Oracle 11g默认的`block size`为8K。 #### 三、问题分析 在本案例中,源数据库为Oracle 9i,目标数据库为...

    Oracle dissassembling_the_data_block

    本文将围绕 Oracle 的内部工具 BBED (Block Browse and Edit) 来展开讨论,旨在帮助读者更好地理解数据块的结构及其在数据库中的作用。 #### 二、Oracle 数据块概述 Oracle 数据库的核心存储单元是数据块,它由一...

    Oracle Recovery Tools-最新版(202407)

    2. Oracle 单个block标记为坏块 3. 查看和修改某个block内容 4. 修改文件头scn(checkpoint scn) 5. 修改文件头resetlogs scn 6. 修改文件头fuzzy标记 7. 不同文件之间数据块拷贝 8. 修改oracle进程内存中内容,...

    Oracle bbed工具 包含Linux和Windows版本

    Oracle bbed工具是Block Browser and Editor(块浏览编辑器)的缩写,它是Oracle数据库在安装时一起附带的工具。一般此工具倾向于仅作为Oracle内部使用,且Oracle公司并不公开此工具使用细节。由于bbed可以对Oracle...

    Oracle Form 触发器的执行顺序

    Oracle Form 触发器的执行顺序 Oracle Form 是 Oracle E-Business Suite R12 中的一个功能强大且灵活的开发工具,用于创建复杂的商业应用程序。其中,触发器(Trigger)是一种非常重要的组件,它可以根据不同的事件...

    关于ORACLE通过file_id与block_id定位数据库对象遇到的问题引发的思考

    在ORACLE中,我们可以通过file_id(file#)与block_id(block#)去定位一个数据库对象(object)。例如,我们在10046生成的trace文件中file#=4 block#=266 blocks=8,那么我可以通过下面两个SQL去定位对象 SQL 1:此...

    oracle基本数据类型存储格式浅析.pdf

    ### Oracle基本数据类型存储格式浅析 —— 字符类型 #### 概述 在Oracle数据库中,字符类型是非常常见的数据类型之一,它主要用于存储文本信息。本文将详细探讨Oracle数据库中几种基本字符类型的存储格式,包括`...

    linux下oracle创建实例总结

    ### Linux 下 Oracle 10.2.0 创建实例详尽指南 #### 一、环境配置与准备 在开始创建 Oracle 数据库实例之前,确保已经安装了 Oracle 10.2.0 版本,并完成了相应的环境变量配置。下面将详细介绍环境配置的步骤。 *...

    linux下oracle手动建实例

    ### Linux 下 Oracle 手动建实例详解 #### 一、概述 在Linux环境中手动构建Oracle实例是一项高级且复杂的任务,通常适用于需要定制化配置或特殊需求的场景。本文档将根据给定的信息,详细介绍如何在Linux环境下手动...

Global site tag (gtag.js) - Google Analytics