Oracle block 格式

信息参考:  http://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 上

select dbms_rowid.ROWID_RELATIVE_FNO(rowid) as file#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) as block# from t;

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

转载 http://www.cnblogs.com/rootq/archive/2008/11/12/1332213.html

Oracle block 格式的更多相关文章

  1. Oracle日期格式转换,tochar(),todate()

    Oracle日期格式转换 本文主要介绍Oracle中的日期转换. 1. 日期转化为字符串 (以2016年10月20日为例) select to_char(sysdate,'yyyy-mm-dd hh2 ...

  2. oracle 日期格式

    oracle 日期格式 to_date("要转换的字符串","转换的格式")   两个参数的格式必须匹配,否则会报错. 即按照第二个参数的格式解释第一个参数. ...

  3. oracle 日期格式操作

    原文转自:http://hi.baidu.com/gzfvb/blog/item/5062b7f008eb70a8a50f5206.html   Oracle日期格式:   to_date(" ...

  4. 【Oracle】Oracle日期格式详解

    本文章没有经过验证,纯属使用CV大法.感谢原创的大牛. to_date("要转换的字符串","转换的格式")   两个参数的格式必须匹配,否则会报错. 即按照第 ...

  5. 设置Oracle时间格式

    ORACLE的DATE类型的显示方式取决于NLS_DATE_FORMAT初始化参数NLS_DATE_FORMAT参数可以在以下几个级别设置1.数据库级别——如果希望所有人都看到某种格式的数据,则在SQ ...

  6. ORACLE日期格式

    to_date("要转换的字符串","转换的格式")   两个参数的格式必须匹配,否则会报错. 即按照第二个参数的格式解释第一个参数. to_char(日期,& ...

  7. oracle时间格式转换问题 ORA-01810: format code appears twice--转

    今天在做报表查询的时候Oracle报错: 信息为 ORA-01810: format code appears twice 原因:由于想java一样转化时间格式,但是Oracle中是不区分大小写的,所 ...

  8. oracle 日期格式大全

    to_date("要转换的字符串","转换的格式")   两个参数的格式必须匹配,否则会报错. 即按照第二个参数的格式解释第一个参数. to_char(日期,& ...

  9. oracle中to_date详细用法示例(oracle日期格式转换)

    这篇文章主要介绍了oracle中to_date详细用法示例,包括期和字符转换函数用法.字符串和时间互转.求某天是星期几.两个日期间的天数.月份差等用法 TO_DATE格式(以时间:2007-11-02 ...

随机推荐

  1. java项目添加到Tomcat中运行-(项目转换为Dynamic Web Project)

    当在eclipse中建了一个java project项目希望他运行在Tomcat中时: 在项目上右键单击,选择 Properties: 在左侧选择 Project Facets,单击右侧的 ”Conv ...

  2. Scrapy爬虫库使用初体验

    安装pip install Scrapy 中间可能会遇到的问题: 超时,网络问题需要多次尝试 缺少vc++库,官网可以下载 win32api缺失,https://sourceforge.net/pro ...

  3. PHP循环嵌套例子

    循环嵌套1.实现如下效果:第一行第二行第三行第四行第五行1 2 3 4 51 2 3 4 51 2 3 4 51 2 3 4 52.实现如下效果图:第一行第二行第三行第四行第五行1 2 3 4 56 ...

  4. android Camera模块分析

    Android Camera Module Architecture and Bottom layer communication mechanism              ----------- ...

  5. JavaScript库基本格式写法

    /********************************************************************* * JavaScript库基本格式写法 * 说明: * 由 ...

  6. 文件的copy

    def mycopy(src_filename, dst_filename): try: fr = open(src_filename, "rb") try: try: fw = ...

  7. phpcms后台主菜单不显示

    phpcms\modules\admin\templates\main.tpl.php 注释掉既可

  8. Java [Leetcode 167]Two Sum II - Input array is sorted

    题目描述: Given an array of integers that is already sorted in ascending order, find two numbers such th ...

  9. python 判断类型

    转自:http://san-yun.iteye.com/blog/1543174 Python可以得到一个对象的类型 ,利用type函数: >>>lst = [1, 2, 3] &g ...

  10. FastAdmin 前端页面传参笔记

    FastAdmin 前端页面传参笔记 看到 QQ 群里的小伙伴询问如何传参,然后在社区里找到一笔记帖子 1 还要参考在线文档控制器部分2. 引用 Karson 的回复: 如果我们需要自己在控制器中透传 ...