尊重作者著作,转自http://blog.csdn.net/guoyjoe/article/details/8567076

----------------------------------------------------------------------------------------------------

Data Block是数据库中最小的I/O单元,下面我来简单介绍下数据块的基本结构。

OK!跟着我一步步实验:

一、建表空间

SQL>create tablespace tp1 datafile '/oradata/bxocp/tp01.dbf' size 10M;

二、建用户及授权

SQL>create user gyj identified by gyj default tablespace tp1;

SQL>grant dba to gyj;

三、建表

SQL>conn gyj/gyj

SQL>create table t1 (id int,name varchar2(100));

四、插入一行数据

SQL>insert into t1 values(1,'AAAAA');

SQL>commit;

五、手动发生一个检查点,使上面一行数据写到数据文件

alter system checkpoint;

六、查这行数据所在的文件号和块号

SQL>col name for a10

SQL>select  id,name,dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from t1;

ID       NAME        FILE#     BLOCK#

----------   ---------       ----------    ----------

1      AAAAA        6        135

七、转储6号文件135号块,新开个窗口

[oracle@guoyj ~]$ sqlplus / as sysdba

SQL> alter system dump datafile 6 block 135;

八、找到转储的文件

SQL> show parameter dump

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

background_core_dump                 string      partial

background_dump_dest                 string      /u01/app/oracle/diag/rdbms/bxo

cp/bxocp/trace

再开一新窗口

[oracle@guoyj ~]$ cd  /u01/app/oracle/diag/rdbms/bxocp/bxocp/trace

[oracle@guoyj trace]$ ls -lFtr

下面这个跟踪日志就是6号文件135号块转储出来的数据块信息

-rw-r----- 1 oracle oinstall   3363 Dec 11 18:02 bxocp_ora_5429.trc -

九、分析数据块结构

[oracle@guoyj trace]$ vi bxocp_ora_5429.trc

Trace file /u01/app/oracle/diag/rdbms/bxocp/bxocp/trace/bxocp_ora_5429.trc

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

ORACLE_HOME = /u01/app/oracle/product/11.2.0

System name:    Linux

Node name:      guoyj

Release:        2.6.18-128.el5

Version:        #1 SMP Wed Dec 17 11:41:38 EST 2008

Machine:        x86_64

VM name:        VMWare Version: 6

Instance name: bxocp

Redo thread mounted by this instance: 1

Oracle process number: 28

Unix process pid: 5429, image: oracle@guoyj (TNS V1-V3)

*** 2012-12-11 18:02:31.307

*** SESSION ID:(29.15) 2012-12-11 18:02:31.307

*** CLIENT ID:() 2012-12-11 18:02:31.307

*** SERVICE NAME:(SYS$USERS) 2012-12-11 18:02:31.307

*** MODULE NAME:(sqlplus@guoyj (TNS V1-V3)) 2012-12-11 18:02:31.307

*** ACTION NAME:() 2012-12-11 18:02:31.307

Start dump data blocks tsn: 7 file#:6 minblk 135 maxblk 135

Block dump from cache:

Dump of buffer cache at level 4 for tsn=7 rdba=25165959

BH (0x7f3f6958) file#: 6 rdba: 0x01800087 (6/135) class: 1 ba: 0x7f33a000

set: 3 pool: 3 bsz: 8192 bsi: 0 sflg: 1 pwc: 103,28

dbwrid: 0 obj: 76987 objn: 76987 tsn: 7 afn: 6 hint: f

hash: [0x908b5100,0x908b5100] lru: [0x7f3f6910,0x7f3f6b70]

ckptq: [NULL] fileq: [NULL] objq: [0x7f3f6938,0x8d148e00] objaq: [0x7f3f6948,0x8d148df0]

st: XCURRENT md: NULL fpin: 'ktspbwh2: ktspfmdb' tch: 3

flags: block_written_once redo_since_read

LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [1]

Block dump from disk:

1、数据块头部分

buffer tsn: 7 rdba: 0x01800087 (6/135)

scn: 0x0000.0015a3eb seq: 0x01 flg: 0x06 tail: 0xa3eb0601frmt: 0x02 chkval: 0xec19 type: 0x06=trans data

flg:0x01 (新建块)0x2(数据块延迟清洗推进scn和seq) 0X04(设置校验和) 0x08(临时块)

type:0x06(表/索引块)

frmt:  0x01(v7)  0x02(v8)

Hex dump of block: st=0, typ_found=1

Dump of memory from 0x00002B70E9566A00 to 0x00002B70E9568A00

2B70E9566A00 0000A206 01800087 0015A3EB 06010000  [................]

2B70E9566A10 0000EC19 00000001 00012CBB 0015A3EA  [.........,......]

2B70E9566A20 00000000 0032F802 01800080 000F0004  [......2.........]

2B70E9566A30 00000346 00C00793 002200BB 00002001  [F.........".. ..]

2B70E9566A40 0015A3EB 00000000 00000000 00000000  [................]

2B70E9566A50 00000000 00000000 00000000 00000000  [................]

2B70E9566A60 00000000 00010100 0014FFFF 1F781F8C  [..............x.]

2B70E9566A70 00001F78 1F8C0001 00000000 00000000  [x...............]

2B70E9566A80 00000000 00000000 00000000 00000000  [................]

Repeat 502 times

2B70E95689F0 0202012C 410502C1 41414141 A3EB0601  [,......AAAAA....]

2.ITL

Block header dump:  0x01800087

Object id on Block? Y

seg/obj: 0x12cbbcsc: 0x00.15a3eaitc: 2flg: Etyp: 1 - DATA

brn: 0  bdba: 0x1800080 ver: 0x01 opc: 0

inc: 0  exflg: 0

seg/obj: 0x12cbb --16进制转成10进制76987

SQL> select object_id from dba_objects where object_name='T1' and owner='GYJ';

OBJECT_ID

----------

76987

csc: 0x00.15a3ea --cleanoutSCN,块清除时的SCN

itc: 2   --ITL槽的数量

flg: E   --指用的是ASSM,如果是O表示用的是free list

typ: 1 - DATA   --事务型的数据块(并且:数据块头的type:0x06),存放表和索引数据。

Itl           Xid            Uba          Flag  Lck        Scn/Fsc

0x01  0x0004.00f.00000346 0x00c00793.00bb.22 --U-    1   fsc 0x0000.0015a3eb

0x02  0x0000.000.00000000 0x00000000.0000.00 ----    0   fsc 0x0000.00000000

Itl: ITL事务槽号的流水编号

Xid:transac[X]tion identified(事务ID),由und的段号+undo的槽号+undo槽号的覆盖次数三部分组成

Uba:undo block address记录了最近一次的该记录的前镜像(修改前的值)

Flag:C是提交,U是快速提交,---是未提交

Lck:锁住了几行数据,对应有几个行锁

Scn/Fsc:Scn=SCN of commited TX; Fsc=Free space credit(bytes)

这里fsc 0x0000.0015a3eb是指提交的scn,这个值大于上次清除块时的scn=csc: 0x00.15a3ea(此scn是这个块中最小的SCN of commited)

SCN WRAP:如果事务已提交并完成清洗,该字段保存事务提交SCN的SCN WRAP部分,否则该字段保存空闲预支字节数(FSC).比如我删除了一行数据10个字节,在事务提前前,这10个字节就属于fsc(即会写到SCN WRAP),只有事务提交后,才能正式返回到空闲空间。

3.用户数据头

bdba: 0x01800087

data_block_dump,data header at 0x2b70e9566a64

===============

tsiz: 0x1f98

hsiz: 0x14

pbl: 0x2b70e9566a64

76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f8c

avsp=0x1f78

tosp=0x1f78

0xe:pti[0]      nrow=1  offs=0

0x12:pri[0]     offs=0x1f8c

bdba: 0x01800087  --数据块的地址:16进制转成2进制取前10位二进制为文件号0000 0001 1000 .....  0000000110=5号文件,后面剩于的部分表示块号,0X87转成10进制为135号块

tsiz: 0x1f98  --top of size块的总大小即8088个字节

hsiz: 0x14   --Data header size数据头大小即20个字节

pbl: 0x2b70e9566a64 --Pointer to buffer holding the block

76543210

flag=--------  N=pcrfree hit(clusters);F=do not put on free list;K=flushable cluster keys

ntab=1     --叫表数:表示这个块的数据在一个表(如果是聚簇表就有可能是2或2以上)

nrow=1     --叫行数:表示这个表有一行数据

frre=-1      -- The first free row entry in the row directory=you have to add one

fsbo=0x14   -- Free space begin offset  叫起始空间:可以存放数据空间的起始位置(即定义了数据层中空闲空间的起始offset)

fseo=0x1f8c  -- Free space end offset  叫结束空间:可以存放数据空间的结束位置(即定义了数据层中空闲空间的结束offset)

avsp=0x1f78  --Available space for new entries  叫空闲空间:定义了数据层中空闲空间的字节数

tosp=0x1f78  --Total space   叫最终空闲空间:定义了ITL中事务提交后,数据层中空闲空间的字节数

0xe:pti[0]      nrow=1  offs=0  --Table directory,整个表的开始,共一行数据,定义了该表在行索引中使用的插槽数

0x12:pri[0]     offs=0x1f8c      --Row index,叫行索引,定义了该块中包含的所有行数据的位置

4.用户数据

block_row_dump:

tab 0, row 0, @0x1f8c

tl: 12 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 2]  c1 02

col  1: [ 5]  41 41 41 41 41

end_of_block_dump

End dump data blocks tsn: 7 file#: 6 minblk 135 maxblk 135

tab 0, row 0, @0x1f8c      --第一个表第一行的位置 ,定义了该表在行索引中的起始插槽号

tl: 12fb: --H-FL-- lb: 0x1cc: 2--行头,tl: 12行长度12个字节,

fb: (Flag byte)--H-FL指H(Head piece of row)F(First data piece) L(Last data piece)

lb: 0x1 --Lock byte和上面的ITL的lck相对应,表示这行是否被lock了

cc: 2 --表示有两列,即这个表有两个字段

col  0: [ 2]c1 02--第一行的第一个字段长度和值

col  1: [ 5]41 41 41 41 41--第一行的第二个字段长度和值

数据块的最后四字节tail: 0xa3eb0601=scnBASE+flg+seq,如果不相等会报块损坏!!!

5、下面对这些数据用SQL语句做相互转换

(1)把表中的数据转成16进制(即在ORACLE内部数据块看到的数据),用以下sql语句:

gyj@OCM> select id,name,dump(01,'16'), dump('AAAAA','16')  from t1;

ID NAME       DUMP(01,'16')     DUMP('AAAAA','16')

---- ---------- ----------------- ----------------------------

1 AAAAA      Typ=2 Len=2: c1,2 Typ=96 Len=5: 41,41,41,41,41

(2)反过来把16进制转成表中的数据(当然我这边的数据类型只考虑了number和varchar类型),用以sql下语句:

ggyj@OCM> col id for 999gyj@OCM> col id1 for 999

gyj@OCM> col name for a10

gyj@OCM> col name1 for a10

gyj@OCM> select id,UTL_RAW.CAST_TO_NUMBER(replace(' c1 02 ',' ')) id1,

2  name,UTL_RAW.CAST_TO_VARCHAR2(replace('41 41 41 41 41',' ')) name1

3  from t1;

ID  ID1 NAME       NAME1

---- ---- ---------- ----------

1    1 AAAAA      AAAAA

****************************************************************************************************************************************************************************

一、对于我上面讲的:1、数据块头部分中讲的flg标志再做一些详细的补充

0x01   (新建块)

0x2   (数据块延迟清洗推进scn和seq)

0X04  (设置校验和)

0x08  (临时块)

对于 flg标志的值是由上面一些位做组合运算的,下面我们来看几下例子:

1、先来看看0x01   (新建块)和0X04  (设置校验和) 的组合

我的版本是11gr2

gyj@OCM> select * from v$version;

BANNER

--------------------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

由于11gr2在创建表的时侯有个延迟段参数的控制,默认不分配EXTNETS空间

gyj@OCM> show show parameter deferred_segment_creation

showmode OFF

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

deferred_segment_creation            boolean     TRUE

那么我在建表的同时要立马分配EXTENTS,好我马上建个表,操作如下:

gyj@OCM> create table t20(id int ,name varchar2(10)) SEGMENT CREATION IMMEDIATE;

Table created.

查分配的区号,文件号,块号

gyj@OCM> select extent_id,file_id,block_id from dba_extents where segment_name='T20';

EXTENT_ID    FILE_ID   BLOCK_ID

---------- ---------- ----------

0          3        152

对3号文件的152号块做DUMP,做dump时最好新打会一个会话,避免产生不必要的日志,操作如下

[oracle@ocm ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Mon Mar 18 07:40:55 2013

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

sys@OCM> alter system dump datafile 3 block 152;

System altered.

好,现在马上到找到跟踪日志

sys@OCM> show parameter dump

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

background_core_dump                 string      partial

background_dump_dest                 string      /u01/app/oracle/diag/rdbms/ocm

/ocm/trace

core_dump_dest                       string      /u01/app/oracle/diag/rdbms/ocm

/ocm/cdump

max_dump_file_size                   string      unlimited

shadow_core_dump                     string      partial

user_dump_dest                       string      /u01/app/oracle/diag/rdbms/ocm

/ocm/trace

[oracle@ocm trace]$ cd /u01/app/oracle/diag/rdbms/ocm/ocm/trace

[oracle@ocm trace]$ ls -lFtr

[oracle@ocm trace]$ more ocm_ora_12910.trc

贴出数据块头的信息:

scn: 0x0000.00000000 seq: 0x01 flg: 0x05 tail: 0x00000001

frmt: 0x02 chkval: 0xa798 type: 0x00=unknown

从上面看出flg是flg: 0x05,就是0x01 +0x04的组合,

0x01说明这是一个新建的块,因为我的表的是刚刚创建的,没有向块中插入数据。

0x04说明有设置校验,chkval: 0xa798这个就是校验和,这个与参数db_block_checksum有关gyj@OCM> show parameter db_block_checksum

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

db_block_checksum                    string      TYPICAL默认设置了db_block_checksum,就会启动校验和检查数据块的一致性。另外数据块尾部的4个字节也是配合数据块头来验证数据块的一致性。

如果一个块头被标识成软损坏,那么块头的序列号为0xff,标志为0x00

2、再来看0x2   (数据块延迟清洗推进scn和seq)

对于延迟块清洗推进要细说有点复杂,到时候对这一块开个专题,这里我就简单介绍一下。

在11g版本中,对数据DML操作,Oracle都是采取快速提交,在事务槽中可以观察到,OK,我先来做个测试来验证一下:

先插入一条数,然后提交,再dump,操作如下:

gyj@OCM> insert into t1 values(2,'BBBBB');

1 row created.

gyj@OCM> commit;

Commit complete.

gyj@OCM> alter system flush buffer_cache;

System altered.

gyj@OCM> gyj@OCM> select id,name,dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from t1 where id=2;

ID NAME       DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)

---- ---------- ------------------------------------ ------------------------------------

2 BBBBB                                         3                                  132

sys@OCM> alter system dump datafile 3 block 132;

System altered.

dump 的内容如下:注意看下面的红色字体部分

数据块头

buffer tsn: 7 rdba: 0x00c00084 (3/132)

scn: 0x0000.004bb8d3 seq: 0x02flg: 0x06 tail:0xb8d30602

frmt: 0x02 chkval: 0x6a0c type:0x06=trans data

事务ITL

Object id on Block? Y

seg/obj: 0x12723 csc: 0x00.4bb8d1  itc: 2 flg: E  typ: 1 - DATA

brn: 0  bdba:0xc00080 ver: 0x01 opc: 0

inc: 0 exflg: 0

Itl          Xid                  Uba        Flag  Lck        Scn/Fsc

0x01   0x0008.016.00001131 0x018019a3.0160.16  --U-    1  fsc 0x0000.004bb8d3

0x02   0x0003.013.0000107a 0x018017c7.0128.23  C---    0  scn 0x0000.004bb60d

数据部分

bdba: 0x00c00084

data_block_dump,data header at0x827664

===============

tsiz: 0x1f98

hsiz: 0x18

pbl: 0x00827664

76543210

flag=--------

ntab=1

nrow=3

frre=-1

fsbo=0x18

fseo=0x1f75

avsp=0x1f5d

tosp=0x1f5d

0xe:pti[0]      nrow=3 offs=0

0x12:pri[0]     offs=0x1f8c

0x14:pri[1]     offs=0x1f81

0x16:pri[2]     offs=0x1f75

block_row_dump:

tab 0, row 0, @0x1f8c

tl: 12 fb: --H-FL-- lb: 0x0  cc:2

col  0: [ 2]  c1 02

col  1: [ 5]  41 41 41 41 41

tab 0, row 1, @0x1f81

tl: 11 fb: --H-FL-- lb: 0x0  cc:2

col  0: [ 2]  c1 02

col  1: [ 4]  67 79 6a 31

tab 0, row 2, @0x1f75

tl: 12 fb: --H-FL-- lb: 0x1  cc:2

col  0: [ 2]  c1 03

col  1: [ 5]  42 42 42 42 42

end_of_block_dump

从上面的事务ITL上看到0x01 0x0008.016.00001131 0x018019a3.0160.16 --U- 1 fsc 0x0000.004bb8d3,这里提交标记是U,表示快示提交,它对应的就是我们的刚刚插入的那行记录。

gyj@OCM> insert into t1 values(2,'BBBBB');1 row created.

gyj@OCM> commit;

实际上很容易看出,从上面的数据看出

tab 0, row 2, @0x1f75

tl: 12 fb: --H-FL-- lb: 0x1 cc: 2          ---lb: 0x1对应的就是事务槽的1号槽。

col 0: [ 2] c1 03

col 1: [ 5] 42 42 42 42 42              ----16进制42就是B

那么什么时候会把提交标记U变成C呢,当我再修改另一行记录时,Oracle向0x02 0x0003.013.0000107a 0x018017c7.0128.23 C--- 0 scn 0x0000.004bb60d2号事务槽插入事务,2号事槽的提交标记又变成快速提交,同时oracle会把原来1号事务槽的提交标记由U(快速提交)变成C(正常提交),并且同时还清除锁标记Lck=0  andlb: 0x00,最后就是我们要说的数据块延迟清洗推进,即在csc: 0x00.4bb8d1改修最后的SCN,实际上csc是本块的最小的commit SCN.

那下面我按上面所说再来做个操作,即插入一下数据,提交,dump,再观察 块头的flg,事务槽,数据,及csc。

gyj@OCM> update t1 set name='CCCCC' where id=1;

2 rows updated.

gyj@OCM> commit;

Commit complete.

gyj@OCM> alter system flush buffer_cache;

System altered.

sys@OCM> alter system dump datafile 3 block 132;

System altered.

dump 的内容如下:注意看下面的红色字体部分

数据块头

buffer tsn: 7 rdba: 0x00c00084 (3/132)

scn: 0x0000.004bbba3 seq: 0x03flg: 0x06 tail:0xbba30603

frmt: 0x02 chkval: 0x3d04 type:0x06=trans data

事务ITL

Block header dump:  0x00c00084

Object id on Block? Y

seg/obj: 0x12723  csc:0x00.4bb8d1  itc: 2  flg: E  typ: 1 - DATA

brn: 0  bdba:0xc00080 ver: 0x01 opc: 0

inc: 0 exflg: 0

Itl          Xid                  Uba        Flag  Lck        Scn/Fsc

0x01   0x0008.016.00001131 0x018019a3.0160.16  --U-    1  fsc 0x0000.004bb8d3

0x02   0x0004.003.00000c54 0x01801a36.00d1.03  --U-    2  fsc 0x0000.004bbba3

数据部分

bdba: 0x00c00084

data_block_dump,data header at0xc03664

===============

tsiz: 0x1f98

hsiz: 0x18

pbl: 0x00c03664

76543210

flag=--------

ntab=1

nrow=3

frre=-1

fsbo=0x18

fseo=0x1f69

avsp=0x1f5c

tosp=0x1f5c

0xe:pti[0]      nrow=3 offs=0

0x12:pri[0]     offs=0x1f8c

0x14:pri[1]     offs=0x1f69

0x16:pri[2]     offs=0x1f75

block_row_dump:

tab 0, row 0, @0x1f8c

tl: 12 fb: --H-FL-- lb: 0x2  cc:2

col  0: [ 2]  c1 02

col  1: [ 5]  43 43 43 43 43

tab 0, row 1, @0x1f69

tl: 12 fb: --H-FL-- lb: 0x2  cc:2

col  0: [ 2]  c1 02

col  1: [ 5]  43 43 43 43 43

tab 0, row 2, @0x1f75

tl: 12 fb: --H-FL-- lb: 0x1  cc:2

col  0: [ 2]  c1 03

col  1: [ 5]  42 42 42 42 42

end_of_block_dump

dump出来发现不是我上面所说的,呵呵。。。,现在两个事务槽的提交标记都是U,U就是代表快速提交,即不清楚行锁。看下面两个dump的csc: 0x00.4bb8d1 即数据块延迟 清洗 没有推进,不要急,我们再做一个操作,再操作一下事务,这次肯定会清楚行锁 ,并且csc: 0x00.4bb8d1 即 数据块延迟  清洗 肯定会推进。

gyj@OCM> insert into t1 values(3,'DDDDDD') ;

1 row created.

gyj@OCM> commit;

Commit complete.

gyj@OCM> alter system flush buffer_cache;

System altered.

sys@OCM> alter system dump datafile 3 block 132;

System altered.

dump 的内容如下:注意看下面的红色字体部分

数据块头

buffer tsn: 7 rdba: 0x00c00084 (3/132)

scn: 0x0000.004bbd8b seq: 0x01flg: 0x06 tail: 0xbd8b0601

frmt: 0x02 chkval: 0xc1f4 type: 0x06=trans data

事务ITL

Object id on Block? Y

seg/obj: 0x12723  csc: 0x00.4bbd8a  itc: 2  flg:E  typ: 1 - DATA

brn: 0  bdba: 0xc00080 ver: 0x01 opc: 0

inc: 0  exflg: 0

Itl           Xid                 Uba        Flag  Lck       Scn/Fsc

0x01  0x0002.014.0000105d  0x01801aa2.0130.17  --U-   1  fsc 0x0000.004bbd8b

0x02  0x0004.003.00000c54  0x01801a36.00d1.03  C---   0  scn 0x0000.004bbba3

数据部分

bdba: 0x00c00084

data_block_dump,data header at 0xd85664

===============

tsiz: 0x1f98

hsiz: 0x1a

pbl: 0x00d85664

76543210

flag=--------

ntab=1

nrow=4

frre=-1

fsbo=0x1a

fseo=0x1f5c

avsp=0x1f4d

tosp=0x1f4d

0xe:pti[0]      nrow=4  offs=0

0x12:pri[0]     offs=0x1f8c

0x14:pri[1]     offs=0x1f69

0x16:pri[2]     offs=0x1f75

0x18:pri[3]     offs=0x1f5c

block_row_dump:

tab 0, row 0, @0x1f8c

tl: 12 fb: --H-FL-- lb: 0x0  cc: 2

col  0: [ 2]  c1 02

col  1: [ 5]  43 43 43 43 43

tab 0, row 1, @0x1f69

tl: 12 fb: --H-FL-- lb: 0x0  cc: 2

col  0: [ 2]  c1 02

col  1: [ 5]  43 43 43 43 43

tab 0, row 2, @0x1f75

tl: 12 fb: --H-FL-- lb: 0x0  cc: 2

col  0: [ 2]  c1 03

col  1: [ 5]  42 42 42 42 42

tab 0, row 3, @0x1f5c

tl: 13 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 2]  c1 04

col  1: [ 6]  44 44 44 44 44 44

end_of_block_dump

flg: 0x06 =0x02+0x04

果然是这样,当事务槽上的提交标志都是快速提交(U),那再有事务进来,Oracle先找个ITL SLOT插入事务,顺便把其它ITL slot上的快速提交U 变成正常提交C,并且清除行锁,最最最得要我想说的就是csc: 0x00.4bbd8a数据块延迟 清洗真的推进了(原来是csc: 0x00.4bb8d1)。。。一定记住csc: 0x00.4bbd8a是数据本块中最小的COMMIT SCN,实际上它表示上次事务槽上没清除的锁现在清除一下,然后就做了一个延迟 清洗推进 .

好,即然说到这里,我再对数据块中非常重要的一块再单独拿出来讲讲:就是ITL(事务槽),事务在数据库中非常重要,如果要细讲事务,那东西很多。这里我先来简单讲讲事务。

那什么是事务?事务的定义是一个独立的逻辑工作单元:它由特定的一系列必须作为一个整体一起成功或失败的SQL语句组成。事务可以由多个数据操作语言(data manipulation language,DML)语句组成,但只能含有一个数据定义语言(data definition language,DDL)语句。

事务的ACID特征

A)、原子性(Atomicity)

事务中的所有动作要么都发生,要么都不发生

B)、一致性(Consistency)

事务将数据库从一种状态转变为下一种一致状态

C)、隔离性(Isolation)

一个事务的影响在该事务提交前对其他事务都不可见

D)、持久性(Durability)

事务一旦提交,其结果就是永久性的

事务的定义和特性就说到这里,我继续dump,分本一下数据块中的ITL槽,OK,我现在马上开始一个事务:

我现在把T1表中的id=3的这行的name=DDDDDD 改成EEEEEE,做UPDATE操作,不提交,让事务一直活动着。

gyj@OCM> select id,name,dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block#

from t1 where id=3;

ID NAME            FILE#     BLOCK#

---------- ---------- ---------- ----------

3 DDDDDD              3        132

gyj@OCM> update t1 set name ='EEEEEE' where id=3;

1 row updated.

这时先不要提交,让事务活动着,一会去观察块中的ITL槽,为了能让上面修改的数据马上写到数据文件,执行缓存刷新操作,

如下:

gyj@OCM> alter system flush buffer_cache;

System altered.

好,这时,我马上开一个新窗口做dump操作:

sys@OCM> alter system dump datafile 3 block 132;

System altered.

贴出DUMP的主要内容ITL部分:

Object id on Block? Y

seg/obj: 0x12723  csc: 0x00.4c5fd3  itc: 2  flg: E  typ: 1 - DATA

brn: 0  bdba: 0xc00080 ver: 0x01 opc: 0

inc: 0  exflg: 0

Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x0002.014.0000105d  0x01801aa2.0130.17  C---    0  scn 0x0000.004bbd8b

0x02   0x0008.00b.00001144  0x01801e95.0161.1b  ----    1  fsc 0x0000.00000000

这里 seg/obj: 0x12723就是对象号,我们用计算器把0x12723(16进制转化成10进制)得到75555,就是说对角号是75555.

sys@OCM> select OBJECT_ID,DATA_OBJECT_ID from dba_objects where object_NAME='T1' and owner='GYJ';

OBJECT_ID DATA_OBJECT_ID

---------- --------------

7535075555

各位兄弟注意了,这里的对象号是指段的号即DATA_OBJECT_ID( OBJECT_ID与DATA_OBJECT_ID,什么时候不一样呢,一般做truncate操作,DATA_OBJECT_ID就会发生变化,这里就不细说了)

好,我们的重点就是看ITL槽,从上面的ITL看出,我们刚刚操作的update正在活动的事务就是在第二个事务槽上即:

Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x02   0x0008.00b.00001144  0x01801e95.0161.1b  ----    1  fsc 0x0000.00000000

我主要来分析一下Xid和Uba

首先Xid是由XIDUSN(Undo segment number)、XIDSLOT(Slot number)+XIDSQN(Sequence number)三部分组成的。

OK,即然说到事务,我们不得不看视图:v$transaction:

sys@OCM> select xid,xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec,status from v$transaction;

XID                  XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC STATUS

---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------------

08000B0044110000          8         11       4420          6       7829        353         27 ACTIVE

从上面的视图v$transaction得到:

XIDUSN=8    (8号回滚段)

XIDSLOT=11  (在8号回滚段的事务表的第11行),哥哥这里不要晕哦,这里的事务表是指8号回滚段的段头块。

XIDSQN=4420 (事务表第11行被覆盖了4420次)

把上面数据块中ITL事务槽中的Xid=0x0008.00b.00001144进行分解,你们看:

0x0008 (16进制)--> (10进制)8

00b  (16进制)-->(10进制) 11

00001144(16进制)-->(10进制)4420

分解出来完本与我们在transaction中看到的 XIDUSN    XIDSLOT     XIDSQN完成一样!

好,我们再来看ILT中的Uba=0x01801e95.0161.1b进行分析:

Uba由文件号、块号、序列号及记录号四部分组成的:

0x01801e95(16进制)--> (10进制)由四个字节组成把它转成32位的二进制,取前面10位二进制得到0000000110=6,剩下的

22位=7829(其实就是0x1e95用计算器转得到7829)

0161 (16进制)--> (10进制) 353

1b    (16进制)--> (10进制) 27

我靠,分解出来与我们在transaction中看到的UBAFIL     UBABLK     UBASQN     UBAREC完成一致!

兄弟们,你们觉得知道这些有什么用吗,其实很有用啊,这些就是UNDO啊,呵呵Oracle之前就靠UNDO打下半壁江山,对于UNDO,我

会在下后面的帖中做详细介绍让彻底解读UNDO让一致性读不再是秘密!(这里留个位置放undo的超链接)

讲到这里,其实还有个跟事务分不开的东东,那就是锁,一个很重要的视图:v$lock;

sys@OCM> select * from v$lock where sid=183;

ADDR     KADDR           SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK

-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------

50C84DA4 50C84DD0        183 AE        100          0          4          0      22492          0

02066600 02066630        183 TM      75350          0          3          0       2893          0

4FA268F4 4FA26934        183 TX     524299       4420          6          0       2893          0

这信息很有用:

TM锁:TM-75350-0

TX锁:TX-524299-4420

对于锁制机会在后面的帖中分享一下移动级的:锁等待分析处理、DX锁等待处理(这里留个位置放超链接)

最后总结:数据块的组成部分,包括以下四部分:

1、数据块头

2、事务槽ITL

3、数据

4、数据块尾

数据块格式就先说到这里了,有问题的兄弟可以一起讨论学习!不断更新中。。。

******************************************************************************************************

补充:NUMBER类型的转储

col  0: [ 2]  c2 02 数字100转存后是这样

SQL> select (to_number('2','xxxx')-1)*power(100,to_number('c2','xxxx')-193) from dual;

(TO_NUMBER('2','XXXX')-1)*POWE

------------------------------

100

这样就算回去了

数字-123.333 转存后是

col  0: [ 6]  3d 64 59 59 47 66

select -((101 - to_number('64', 'xxxx')) *

power(100, 62 - to_number('3d', 'xxxx')) +

(101 - to_number('59', 'xxxx')) *

power(100, 62 - to_number('3d', 'xxxx') - 1) +

(101 - to_number('59', 'xxxx')) *

power(100, 62 - to_number('3d', 'xxxx') - 2) +

(101 - to_number('47', 'xxxx')) *

power(100, 62 - to_number('3d', 'xxxx') - 3) )

这样就算回去了

转存后是16进制的

要 改回10进制

创建一个表

SQL> create table t1

2  (it number);

Table created

SQL> insert into t1

2  values(100);

1 row inserted

计算器块

SQL> select rowid from t1;

ROWID

------------------

AAAXKYAABAAAU4aAAA

SQL> select dbms_rowid.rowid_relative_fno('AAAXKYAABAAAU4aAAA'),dbms_rowid.rowid_block_number('AAAXKYAABAAAU4aAAA') from t1;

DBMS_ROWID.ROWID_RELATIVE_FNO( DBMS_ROWID.ROWID_BLOCK_NUMBER(

------------------------------ ------------------------------

1                          85530

进行DUMP

SQL> alter system dump datafile 1 block 85530;

System altered

查看其数字的dump格式

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f9a

avsp=0x1f83

tosp=0x1f83

0xe:pti[0]        nrow=1        offs=0

0x12:pri[0]        offs=0x1f9a

block_row_dump:

tab 0, row 0, @0x1f9a

tl: 6 fb: --H-FL-- lb: 0x1  cc: 1

col  0: [ 2]  c2 02  ----这里就是DUMP出来的,长度是2

end_of_block_dump

End dump data blocks tsn: 0 file#: 1 minblk 85530 maxblk 85530

其实这里的C2 02就是其具体的数字。使用DUMP函数也能得出

SQL> select dump(it,16) from t1;

DUMP(IT,16)

--------------------------------------------------------------------------------

Typ=2 Len=2: c2,2

然后通过ORACLE的算法计算回去

SQL> select to_number('c2','xxxx') from dual;

TO_NUMBER('C2','XXXX')

----------------------

194

SQL> select to_number('2','xxxx') from dual;

TO_NUMBER('2','XXXX')

---------------------

2

其实这里的如果换算为10进制是

194,2

如果大于128 就是正数,小于128就是负数

指数是194-193=1

数字位1 是2-1=1*100^(1-0)=100 -1是因为正数+1存储

所以数字也就还原为100

SQL> select (to_number('2','xxxx')-1)*power(100,to_number('c2','xxxx')-193) from dual;

(TO_NUMBER('2','XXXX')-1)*POWE

------------------------------

100

用SQL就是这样,这是第一位

在加入一个负数

SQL> insert into test

2  values(-123.333);

1 row inserted

SQL> commit;

Commit complete

进行DUMP如上

tab 0, row 1, @0x1f90

tl: 10 fb: --H-FL-- lb: 0x2  cc: 1

col  0: [ 6]  3d 64 59 59 47 66

进行计算

Typ=2 Len=6: 3d,64,59,59,47,66

SQL> select dump(it,16) from testpp;

DUMP(IT,16)

--------------------------------------------------------------------------------

Typ=2 Len=2: c2,2

Typ=2 Len=6: 3d,64,59,59,47,66  --66 及10进制的102是一个排序位不用理会,用在负数的时候

内部存储长度6 指数3d 后面数数字位

换算为10进制就是

61,100,89,89,71,102

61是指数未

102 是排序位

中间的数字位

select -((101 - to_number('64', 'xxxx')) *

power(100, 62 - to_number('3d', 'xxxx')) +

(101 - to_number('59', 'xxxx')) *

power(100, 62 - to_number('3d', 'xxxx') - 1) +

(101 - to_number('59', 'xxxx')) *

power(100, 62 - to_number('3d', 'xxxx') - 2) +

(101 - to_number('47', 'xxxx')) *

power(100, 62 - to_number('3d', 'xxxx') - 3) )

from dual;

这样数字就完成了转换。

解析oracle的dump文件,读懂数据块dump文件信息相关推荐

  1. oracle itl解析,oracle数据块dump文件中ITL详解

    oracle数据块dump文件中ITL详解 dump出Oracle block后,可以看到事物槽,包含有事物槽号(ITL),XID,UBA,FLAG,LCK,SCN. 本文主要讨论FLAG标记的规则, ...

  2. oracle数据块dump信息,从数据块的dump信息能看出什么

    本帖最后由 zcs0237 于 2013-6-13 16:57 编辑 a.本文搜集大量网友文章编写而成 b.为节省篇幅,部分输出结果做了精简 c.感谢对本帖补充.建议.错误更正 d.推荐网站: === ...

  3. 一文读懂数据要素(附研究文档大合集下载)

    最近数据要素这个词不断出现在大数据圈里也同时出现在公众视野.各个研究机构,政府部门都在重点关注数据要素及其作用及发展,并提供各类政策性的指引,那么什么是数据要素呢? 本文将综合目前主流的研究进行归纳整 ...

  4. 一文读懂数据中台技术架构

    一文读懂数据中台技术架构 https://www.toutiao.com/i6836923386560512516/?tt_from=weixin&utm_campaign=client_sh ...

  5. 如何读懂数据含义?(通俗版)

    很多新人读不懂数据含义.对着报表,只会和复读机一样,叨叨:"昨天销量100,今天销量120,增加20--"讲这些只要不是瞎子都能看的到的东西.也因此经常被笑话,咋办?!今天我们系统 ...

  6. 一文读懂“数据分发服务DDS”(Data Distribution Service,RTPS,OMG)

    一文读懂"数据分发服务DDS"(Data Distribution Service,RTPS,OMG) https://blog.csdn.net/DDS_CSIT/article ...

  7. php 旧数据 覆盖,旧文件被新数据覆盖了文件还能恢复吗?

    原标题:旧文件被新数据覆盖了文件还能恢复吗? 文件被覆盖了数据还能恢复吗?文件覆盖一般是指原有的文件被新的同名文件覆盖,导致之前的数据丢失的情况.这些和误删除和误格式化不同,主要是文件被替换的过程,这 ...

  8. html表格打印成pdf格式文件,使用html2pdf打印PDF格式文件中的数据作为PDF文件

    我想从表单文章中获取一些数据并将其输出到PDF2文件中,并在同一页面上使用html2pdf.但是,当试图将表单数据发布到同一页面时,它不会打开PDF文件,这可能是因为PHP文件的其余部分将出现在if( ...

  9. 解析.DBC文件, 读懂CAN通信矩阵,实现车内信号仿真

    通常我们拿到某个ECU的通信矩阵数据库文件,.dbc后缀名的文件. 直接使用CANdb++ Editor打开,可以很直观的读懂信号矩阵的信息,例如下图: 现在要把上图呈现的信号从.dbc文件中解析出来 ...

最新文章

  1. 火爆GitHub的《机器学习100天》,有人把它翻译成了中文版
  2. 【iCore4 双核心板_ARM】例程二十三:LWIP_HTTP实验——网页服务器
  3. Linux 命令 - curl: transfer a URL
  4. python访问网页被拒_Python Requests.get访问网页403错误
  5. 「leetcode」 1382. 将二叉搜索树变平衡:【构造平衡二叉搜索树】详解
  6. c# 算式 计算器_C#计算器
  7. 微信联系人一键导出的方法在这里
  8. Intel SGX技术详细解释(非常棒)
  9. 全15期BIM等级考试解析(内附考试秘籍)
  10. 计算机优化英语课堂教学,多媒体课件优化英语课堂的反思性研究
  11. 计算机无法读取手机内存,手机内存卡不能读取如何解决
  12. 单独备份config配置文件 (来自老梁邮件)
  13. 2020手机cpu天梯图
  14. 道路中心线提取、河道中心线的提取(ArcScan)
  15. 仓库出现了两个除了首字母大小写不一样的相同文件
  16. iOS 应用架构 (二)
  17. GPS手机射频的一些测试项目
  18. 5.Serializer,ModelSerializer区别
  19. 网页前端设计-作业三(JavaScript)
  20. NOAA(美国海洋和大气管理局)气象数据获取与POI点数据获取

热门文章

  1. scrolltop 原生js_解决js页面滚动效果scrollTop在FireFox与Chrome浏览器间的兼容问题的方法...
  2. 研究生如何做研究和写论文
  3. 西西弗斯数的转换|C++
  4. 曾记否,到中流击水,浪遏飞舟
  5. css+html制作订单页面
  6. 英语 in, on, at的区别
  7. 如何使用免费的服务器
  8. 编程珠玑译-Column 1:开篇
  9. 2023年吉林大学口腔专业考研上岸前辈备考经验指导
  10. 所谓0脂低卡的代糖如何影响血糖和胰岛素你真的了解吗?