block格式

来源:互联网 发布:淘宝网的绿知了的价格 编辑:程序博客网 时间:2024/04/30 16:12

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: 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? 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的出现
--- 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 的格式也可能越来越困难

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 狗狗肛门腺发炎怎么办 狗狗耳朵受伤了怎么办 狗狗的耳朵发热怎么办 头疼带的耳朵疼怎么办 戴眼镜压耳朵疼怎么办 偏头神经跳疼怎么办 脸消肿后有硬块怎么办 拔完智齿好疼怎么办 补过的牙裂了怎么办 补牙后吃冷热疼怎么办 假体下巴肿疼怎么办 左脸疼痛张嘴疼怎么办 一张嘴脸颊会痛怎么办 法斗地包天怎么办 皮肤起小水泡痒怎么办 手臂起小水泡痒怎么办 手背有小水泡痒怎么办 水泡破了很痒怎么办 有一块牙龈肿了怎么办 耳前瘘管有脓怎么办 睡歪脖子很痛怎么办 睡歪脖子怎么办小妙招 睡觉睡得脖子疼怎么办 睡久了后脑勺疼怎么办 腮帮肿了但不疼怎么办 吃硬东西腮帮痛怎么办 嘴巴长开旁边疼怎么办 晚上腿酸睡不着觉怎么办 吃酸的牙齿酸软怎么办 吃酸东西牙齿酸怎么办 拔完智齿神经疼怎么办 22岁腿关节疼痛怎么办 耳洞里面有硬块怎么办 耳洞发炎有硬块怎么办 小孩慢性扁桃体发炎怎么办大全 侧切伤口化脓了怎么办 狗狗伤口不愈合怎么办 狗后腿烂了化脓怎么办 乳腺增生腋下淋巴结肿大怎么办 手术刀口冒脓了怎么办 脚伤口感染肿了怎么办