oracle数据库block状态,oracle block 格式-数据库专栏,ORACLE

本文详细解析了Oracle数据库8.1.7版本8KB数据块的结构,包括数据文件地址、系统变更号、事务信息、块头、行信息等,并探讨了不同字段的含义和作用,以及如何通过ALTER SYSTEM DUMP命令进行数据块的转储和分析。
摘要由CSDN通过智能技术生成

信息参考:  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: 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=dont 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   

— 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 没见过其他的值 dont know

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

— 00                :   没见变过其他的值 dont 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 的格式也可能越来越困难

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值