这边文章不能算做自己写的,顶多算作转载了别人的文章,只不过自己做了些实验,同时加入了些自己的理解。文章中大部分内容来自:http://blog.csdn.net/l2g32003/archive/2004/05/17/20444.aspx
对原文作者表示感谢!
同时要说明的是,ORACLE不同版本不同SEGMENT类型的BLOCK格式都有些出入的,而且这里列出的也可能有不准确或者还不理解的地方,欢迎大家补充、指正。同时,因为前半部分是使用一个压缩表来实验的,做到后面发现压缩表跟普通表差异太大,所以换了另一个TRACE开始写,可能会有前后对不上的情况
Start dump data blocks tsn: 35 file#: 74 minblk 299167 maxblk 299167
--这段是说要DUMP的BLOCK位于第35个TABLESPACE,第74个FILE,DUMP出来的最小和最大块都是299167,也就是只DUMP了299167块
buffer tsn: 35 rdba: 0x1284909f (74/299167)
--这里的tsn表示TABLESPACE NUMBER,十进制,表示是第35个TABLESPACE,可以从V$TABLESPACE中查看ts#=35的,来查看表空间相关情况
--rdba表示块在数据文件中的位置,也就是第几个BLOCK。后五位可以换算得到BLOCK的位置,可是前面3位不知道怎么去换算得到数据文件的编号。不过这个地址可以使用dbms_utility.data_block_address_file或者dbms_utility.data_block_address_block来转换出来这个地址数据哪个文件的哪个BLOCK
scn: 0x0003.6ee95f7b seq: 0x01 flg: 0x04 tail: 0x5f7b0601
--scn表示块的scn号,只有当CHECKPOINT发生的时候,这里的SCN才会发生改变(注意:如果修改数据后没有CHECKPOINT就去DUMP,发现SCN号却发生了变化,那是因为DUMP出来的是脏的BUFFER CACHE中的数据,真正的物理文件中的数据可以通过BBED来查看。同时,可以到V$BH中去查看这个BLOCK的状态,可以发现即使DUMP完成后,这个BLOCK还是DIRTY,说明这个BLOCK是从BUFFER直接DUMP出来的,而不是先把块写到文件中,然后再从文件DUMP出来。)
--seq表示同一个SCN影响这个block中的行数大于 254 行就会为这个事务分配一个新的SCN,如下面的操作就可能引起同一个SCN但影响的同一个block 中的行超过254行,"delete from table_name" ,影响的行数(最大254) 是用从 0x01 到 0xfe 表示的,当这个byte 的数据为 0xff 的时候标志这个 block 坏调了---> ora-01578
--flg:1,virgin block;2,last change to the block was for a cleanout operation;4,checksum value is set;8,temporary data。并且这些值是可以组合出一些新的值,比如5表示同时有1+4的属性,6表示同时有2+4的属性。
--tail:表示这个块的最后4个字节的数据,可以翻到DUMP出来的一堆16进制码的最后,就会找到跟这个值对应的一个块的最末尾的值
frmt: 0x02 chkval: 0xbafb type: 0x06=trans data
--frmt:oracle8以后看见的都是0x02
--chkval:BLOCK的校验值,用来BLOCK内容的损坏
--type:表示这个BLOCK的类型,06跟后面的字母解释都说明这个块是数据块。其他类型参考http://zhang41082.itpub.net/post/7167/495315
Hex dump of block: st=0, typ_found=1
--这里不知道啥意思
Dump of memory from 0x0000000005EF1200 to 0x0000000005EF3200
--这里表示从内存的某个地址DUMP到另一个地址,DUMP的时候总是先DUMP内存中的内容,然后再DUMP出文件中ASCII表示的内容
005EF1200 0000A206 1284909F 6EE95F7B 04010003 [........{_.n....]
005EF1210 0000BAFB 00000001 0003EC2D 6EE95F7B [........-...{_.n]
005EF1220 00000003 00320004 12849089 0012004C [......2.....L...]
005EF1230 000A33B2 00000000 00000000 00038000 [.3..............]
005EF1240 6DDACA5F 00000000 00000000 00000000 [_..m............]
005EF1250 00000000 00000000 00000000 00000000 [................]
Repeat 3 times
--上面这些天书就是从内存中DUMP出来的内容,最左边一列表示内存地址(可以看到第一行的地址跟上面描述的起始地址是一致的,而且每行存储16字节内容,那么内存地址每增加一行,计数都会进一位,因为16进制,就表示内存地址增加了16)。
--往右边的四列表示了实际存储的内容,每两位是一个字节,所以一共存储了16字节内容
--最右边括号中的内容表示内存中内容实际对应的ASCII码(这个对应关系不那么准确,尤其是在块的头部有很多控制字符,往后面翻到数据存储的地方,这个对应关系会比较靠谱点)
--最下面的Repeat 3 times表示上面的一行内容在这里被重复了三次,也就是说ORACLE为了省事,如果发现哪些行内容跟上面的内容一样,那么这样就不显示出来,而是显示说跟上面一样的内容还有几行,省点地方。
Block header dump: 0x1284909f
--这个跟前面的RDBA对应,表示这个块是哪个数据文件的哪个块
Object id on Block? Y
--这里是说明对象的ID是否也保存在这个BLOCK中,ORACLE 6以后这里总是Y
seg/obj: 0x3ec2d csc: 0x03.6ee95f7b itc: 4 flg: E typ: 1 - DATA
--其中的SEG/OBJ表示的是这个BLOCK所对应的OBJECT的OBJECT_ID,而不一定是真正的SEGMENT_ID,具体参考:http://zhang41082.itpub.net/post/7167/495078
--csc:The SCN at which the last full cleanout was performed on the block,也就是一般说的块的SCN号,这个号只有当BUFFER中的块被刷到磁盘的时候才会更新,不然DUMP出来的CSC是不变的。
--itc:ITL的总数,这里显示的是当前的BLOCK中的ITL总数,而不是创建这个BLOCK的时候初始设置的ITL总数。
--flg:如果是0表示这个块是在FREELIST上的,如果是-表示不在FREELIST上。如果是ASSM的,会显示为E。
--typ:1 为 table ; 2 为 index. oracle进行查询的时候是根据 obj$表中的情况来判断对象的类型的,不是根据这个typ。
brn: 0 bdba: 0x12849089 ver: 0x01 opc: 0
inc: 0 exflg: 0
--上面这一堆暂时未知
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x004c.012.000a33b2 0x00000000.0000.00 C--- 0 scn 0x0003.6ddaca5f
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x04 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
--这里的第一列表示ITL的槽位编号,因为这个表缺省的itl为4,所以即使没有那么多事务,这里DUMP也是有4行记录
--第二列表示V$TRANSACTION中对应的事务号,三个值转换成十进制分别对应到V$TRANSACTION的XIDUSN,XIDSLOT,XIDSQN三个字段,分别表示事务所对应的回滚段的编号、槽位号和顺序号
--第三列UBA表示事务在回滚段中对应的地址。第一部分表示回滚段块地址;第二部分表示回滚块序号,对应v$transaction中 UBASQN;第三部分表示undo chain(irb), 将指向具体使用的undo block。其中第一部分可以使用dbms_utility.data_block_address_file和dbms_utility.data_block_address_block转换得到这个事务对应的UNDO BLOCK的地址。
-- ---- 表示transaction is active, or committed pending cleanout,C---表示事务已经提交并且持有的锁已经清除;-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列表示这个事务所持有的行级锁的数目
--SCN/FSC:其中FSC表示FAST COMMIT的SCN。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
这里还有一个延迟块清除的概念,会影响到这里的内容,接下来会专门再开一片来说明这个咚咚。
data_block_dump,data header at 0x5eef45c
--这里说明了这个BLOCK的数据头从什么地方开始,后面会用这个地址加上偏移来计算每行数据的地址
tsiz: 0x1fa0
--这里说明可以存放数据的空间大小,这里是8096字节
hsiz: 0x18
--BLOCK_HEADER占用空间大小,这里是24字节
pbl: 0x05eef45c
bdba: 0x0041b96a
76543210
--未知
flag=--------
--N=pctfree hit(clusters), F=don't put on free list,K=flushable cluster keys. 别的标记未知
ntab=1
--这个BLOCK中存放了几个表中的数据,一般都是1,当表是CLUSTER TABLE的时候,会大于1
nrow=3
--这个BLOCK中有几行数据
frre=-1
--First free row index entry,-1=you have to add one
fsbo=0x18
--Free Space Begin offset,空闲空间从哪里开始
fseo=0x1f91
--Free Space End offset,空闲空间到哪里结束
avsp=0x1f6d
--Available space in the block
tosp=0x1f6d
--Total available space when all TXs commit,所有事物都提交后,可使用的空间
0xe:pti[0] nrow=3 offs=0
0x12:pri[0] offs=0x1f9b
0x14:pri[1] offs=0x1f96
0x16:pri[2] offs=0x1f91
--每行的偏移量
block_row_dump:
tab 0, row 0, @0x1f9b
--第一(其实是零)行数据的起始地址
tl: 5 fb: --H-FL-- lb: 0x0 cc: 1
--tl表示这条记录的总长度,一般ROW HEAD占3个字节,行长本身占一字节,所以这个值减去4是实际的行数据长度
--fb是一个标志位:
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,和上面的ITL那里的LCK对应的,表示这行数据是否被加锁
--cc,column count,表示这行数据有几列
col 0: [ 1] 31
--col 0表示这里是这行数据的第一列
--[1]表示这列数据的长度
--31表示这列数据的ASCII码,这里的31表示实际的数据是1
下面的行数据依次类推,跟上面的行数据类似
tab 0, row 1, @0x1f96
tl: 5 fb: --H-FL-- lb: 0x0 cc: 1
col 0: [ 1] 78
tab 0, row 2, @0x1f91
tl: 5 fb: --H-FL-- lb: 0x1 cc: 1
col 0: [ 1] 62
end_of_block_dump
--最后表示这个BLOCK DUMP结束
===============================================
object_id和data_object_id的区别和联系(转载)
查看DBA_OBJECTS视图的时候碰到这个问题,有些疑惑,往上搜搜,发现已经有前辈研究过了,看过之后豁然开朗,这里简单转载并摘录一部分(实验过程太长,就不转载了,只摘录结论供参考)。
转载自:http://www.orawh.com/62.html
object_id和data_object_id同样是表示数据库对象的一个唯一标志,但是object_id表示的是逻辑 id,data_object_id表示的是物理id。如果一些object没有物理属性的话那它就不存在data_object_id,例如 procedure,function,package,data type,db link,mv定义,view定义,临时表,分区表定义等等这些object都是没有对应着某个segment,因此它们的data_object_id 都为空。
当表刚创建的时候它的object_id和data_object_id都是相等的,但是如果表经过move或truncate后那么data_object_id将会有变化(如果表中没有记录的时候进行truncate的话,data_object_id是不会发生变化的),truncate之后虽然segment的位置没有移动,但是data_object_id还是发生变化了。通过视图的定义跟下去,可以得到data_object_id是从obj$.dataobj#来的,而obj$.dataobj#最终又对应着seg$.HWMINCR
data_object_id的最终用处就是方便物理对象的管理:比如我们做alter table exchange partition的时候, 就可以直接修改object_id与data_object_id的对应关系, 就可以实现这个操作.
:
?
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23721637/viewspace-1033721/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/23721637/viewspace-1033721/