您的位置:首页技术文章
文章详情页

oracle block 格式

浏览:25日期:2023-11-18 11:19:07
信息参考:; www.ixora.com.au 非凡感谢 overtime 大哥对我的无私的帮助和对我一直鼓励支持我的网友这些资料是没得到Oracle 支持的 所以不能保证信息的正确性 请谨慎使用 科技无限 随便转载 oracle 8.1.7 8k block; windows XP;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: 0x02a50601frmt: 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:; 0x01000003Object id on Block? Yseg/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 '这一段数据的情况已经改变了-----------------------; 第三部分ItlXid; Uba;;;Flag; Lck;;;;;Scn/Fsc0x01xid:; 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: 0x1fb8hsiz: 0x14pbl: 0x02476c44bdba: 0x01000003flag=-----------ntab=1nrow=1frre=-1fsbo=0x14fseo=0x1fb2avsp=0x1f9btosp=0x1f9b0xe:pti[0];nrow=1;offs=00x12: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, @0x1fb2tl: 6 fb: --H-FL-- lb: 0x1 cc: 1col; 0: [ 2]; c1 02end_of_block_dump--- tl:;;这条记录中的长度 包括row head 的一般情况的 3 字节和表示数据长度的1字节和数据本身的长度--- fb:1 byteK = 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; 78; 9; A; B; C; D; E; F0000600006 02 00 00 03 00 00 01; A5 02 08 00 00 00 01 020000601000 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.000802a5oracle是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 000000602000 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? Y---;;;;从我的观察中 dump 出来的文件中flg;;ver;;Object id on Block---;;;;他们共同占用的这个一个字节他的规律可以从下面的情况看出--- 2进制数据;;flg;;;;ver;;;;Object id on Block?---0x00 -;;;;;0x00N---0x01 0;;;;;0x00N---0x02 -;;;;;0x01Y---0x03 0;;;;;0x01Y---0x04 -;;;;;0x02Y---0x05 0;;;;;0x02Y---0x06 -;;;;;0x03 Y---0x07 0;;;;;0x03Y---0x08 -;;;;;0x04N---0x09 0;;;;;0x04N---0x0a -;;;;;0x05Y---0x0b 0;;;;;0x05Y---0x0c -;;;;;0x06Y---0x0d 0;;;;;0x06Y---0x0e -;;;;;0x07Y---0x0f 0;;;;;0x07Y---;;; ;;;;;0x10 ... 类似上面的循环了这种情况在9i上已经改变因为ASSM的出现--- 00;;;;;:fsl: 0--- 00 00 00 00;;;;:fnx: 0x0------------------------; 下面的对应上面dump 文件的第三部分 03 00 45 0000006030B4 00 00 00 0A 17 80 00; C7 00 36 00 01 20 00 0000006040A5 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 1F000060509B 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 文件的第五部分--- 这部分和上面的数据中间省略了很多 因为这列子中这些部分没存储数据 00007FF000 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 因为下面的两个参数没有设置为 truedb_block_checking;db_block_checksum;这两个参数对于system tablespace 默认都是true 所以改变 system tablespace 中的数据肯定会发生ORA-01578随着oracle版本的不断升级 oracle 对block中存储数据的正确性也在不断的提升要求 而且通过常规的手段想去了解 oracle block 的格式也可能越来越困难
标签: Oracle 数据库