block的初探

二次信任 提交于 2020-01-15 16:11:21

 

1、  创建一张测试表:

create table t1(a integer,b varchar2(100),c varchar2(100));

insert into t1 values(1,null,'aaaa');

insert into t1 values(1,null,'bbbb');

insert into t1 values(1,1111,null);

2、  查找表(段)所在的位置:

select extent_id,file_id,block_id from dba_extents where segment_name='T1';

 

3、  查找12号文件是什么:

select file_name from dba_data_files where file_id=12;

 

4、  查找具体的块号:

  

5、  下面用linux命令dd将3029这个块dump出来:

dd if=/oradata/oracle/datafiles/NNC_DATA01_07.dbf    of=g.dmp  bs=8192 skip=3029 count=1

cp  g.dmp /db_backup/

6、  UE打开g.dmp文件进行查看,文件尾部:

 

其中

  

   蓝色的数字代表:2c是行头,01表示改行使用了1号ITL槽,03表示这一条记录有多少个字段(3个)。

   02,c1,02是第一个字段的值,这个字段是数字类型,02表示该字段的长度,C1  02就是十进制的1, 后面的FF表示第二个字段为空值,而04,61,61,61是最后一个字段aaaa。、

   第三条记录地址为00001fd0h,

以2c 01,02开头,每一行的第三个字节表示这一行的字段数量。而至一行在insert的时候最后一个字段为null。说明:如果某一行的最后几个字段都为null,oracle存储时会直接省略,以节约存储空间

 

 

 

 

实验:

 

1、  create tablespace m1 datafile '/oradata/oracle/datafiles/m1.dbf' size 10M; 

2、  create user mard identified by 1 default tablespace m1;

3、  grant dba to mard;

4、  create table t1(id int,name varchar2(100));

5、  insert into t1 values(1,'AAAA');

6、  commit;

7、  alter system checkpoint;-----检查点发生,数据写入数据文件

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

----查找t1的这行数据的所在的文件号和块号

----结果:1,AAAA,22,132

9、alter system dump datafile 22 block 132;    (新开窗口将该块dmp下来)

10、show parameter dump;

    NAME                                 TYPE        VALUE

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

background_core_dump                 string      partial

background_dump_dest                 string      /oradata/oracle/app/diag/rdbms/ora11g/ora11g/trace

core_dump_dest                       string      /oradata/oracle/app/diag/rdbms/ora11g/ora11g/cdump

max_dump_file_size                   string      unlimited

shadow_core_dump                     string      partial

user_dump_dest                       string      /oradata/oracle/app/diag/rdbms/ora11g/ora11g/trace

11、ll –t、cp ora11g_ora_17529.trc /db_backup/

12、用工具打开查看或vi进行查看:

 

分析数据块结构:

 

 

 

数据块头部:

红色部分为数据块头部:

flg: 0x01(新建块)0x02(数据块延迟清洗推进SCN和SEQ)0x04(设置校验和)0x08(临时块)

type:0x06(表/索引块)

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

 

buffer tsn:7  --该块对应的表空间号。这里指的是7号表空间

rdba:0x05800084 (22/132)---相对数据块地址,表示该块为22号数据文件第132个块,用4个字节32 位来表示,前10位为相对文件号,后22为为快号。05800084=0000 0101 1000 0000 0000 1000 0100。Rdba在数据块中的offset是4,即rdba存在于数据块中的第5 -9个字节。

scn:0x0000.00baa810 ----数据块头部的scn,总共占6个字节,前两个字节表示SCN Wrap。后四个字节表示SCNbase。如果后者达到了四个字节表示的最大值,SCN  Wrap+1,SCN base清零,在数据块中offset是8

seq: 0x01在数据块中offset是14

flg:0x06,在数据块中的offset是15

tail:0xa8100601---即tail check,存放于数据块的最后4个字节,用于检查数据块的一致性。tail check组成:SCN base的低2个字节+type+seq。即0xa8100601=a810+06+01

frmt:0x02---块格式  01表示oracle7,02表示oracle8+

type:0x06=trans data,参考一下表格:

 

 

事务列表区分析:

 

 

 

Block header dump:  0x05800084

 Object id on Block? Y

 seg/obj: 0x25491  csc: 0x00.baa7ea  itc: 2  flg: E  typ: 1 - DATA

     brn: 0  bdba: 0x5800080 ver: 0x01 opc: 0

     inc: 0  exflg: 0

 

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x000a.005.00018903  0x00c6860f.3aba.2b  --U-    1  fsc 0x0000.00baa810

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

 

seg/obj: 0x25491    --该数据块中对象的object_id,我们dmp的表是t1,下面验证下:

SQL> select to_number('25491','XXXXXX') from dual;    -----此处用to_number函数,将16进制的数转化为10进制

 

TO_NUMBER('25491','XXXXXX')

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

                     152721

SQL> select object_name,object_type from dba_objects where object_id=152721;

 

OBJECT_NAME                                                                      OBJECT_TYPE

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

T1                                                                               TABLE

 

csc: 0x00.baa7ea   --SCN at the block cleanout,,表示最后一次清除(block cleanout)的scn

itc: 2  ----块中ITL slot的数量,两个

flg: E  ----flg:0表示此块被放置在自由列表(freelist)中。

Typ:1-DATA   类型1表述数据,类型2表示索引

Bdba---block relative data block address(RDBA)

 

下边看一下事务槽:

Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x000a.005.00018903  0x00c6860f.3aba.2b  --U-    1  fsc 0x0000.00baa810

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

Oracle中每个数据块中都有一个或者多个事务槽,每一个对数据块的并发访问事务都会占据一个事务槽

Xid:事务id,在回滚段事务中有一条记录和这个事务对应。Xid组成:undo segment number+transaction table slot number+Wrap(覆盖次数);

Uba:回滚段地址,该事务对应的回滚段地址。Uba组成:回滚块地址(undo文件号和数据块号)+回滚序列号+回滚记录号

SQL> select xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec from v$transaction;

 

    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC

---------- ---------- ---------- ---------- ---------- ---------- ----------、

Flag:事务标志位:

C:事务已提交,锁被清除

B:这个撤销记录包含撤销此ITL的条目

U:事务已提交,锁还没有被清除

T:块清除的SCN被记录时,该事务仍然是活动的。块上如果有已经提交的事务,那么在clean out的时候,块会被进行清除,但这个块里面的事务不会被清除。

 

LCK:表示这个事务影响的行数

Scn/Fsc:commit SCN或者快速提交的的SCN

 

 

用户数据头

 

 

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

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

pbl: 0x7ff4e5fae064-------pointer to buffer holding the block

     76543210

flag=--------

ntab=1    表数   1表示这个数据块的数据在一个表

nrow=1    行数

frre=-1    

fsbo=0x14      起始空间

fseo=0x1f8d     结束空间

avsp=0x1f79     空闲空间

tosp=0x1f79     最终空闲空间

 

用户数据:

 

block_row_dump:

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

tl: 11 --行头  tl: 11,行长度是11个字节

fb: --H-FL—  flag byte

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

cc: 2       表示由于两列  

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

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

end_of_block_dump

End dump data blocks tsn: 7 file#: 22 minblk 132 maxblk 132

 

 

关于表、行所在的块id的问题:

上面获得id的是视图及方法:

1、  查看表的起始块:dba_extents

select extent_id,file_id,block_id from dba_extents where segment_name='T2';  

2、  根据1得到的文件号查看具体数据文件:dba_data_files

select file_name from dba_data_files where file_id=12;

3、  查看表中的数据行所在的块号:

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

4、  查看对象表总共占据的block数据:

SQL> exec dbms_stats.gather_table_stats(user,'T2');

SQL> select num_rows,blocks from user_tables where table_name='T2';

 

实验数据:

1、查找T2表的文件号和块起始号

SQL> select extent_id,file_id,block_id from dba_extents where segment_name='T2';

 

 EXTENT_ID    FILE_ID   BLOCK_ID

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

         0         22        136

2、查看文件究竟是哪个文件

SQL> select file_name from dba_data_files where file_id=22;

 

FILE_NAME

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

/oradata/oracle/datafiles/m1.dbf

3、查看行数据所在的块号

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

 

                                     ID NAME            FILE#     BLOCK#

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

                                      1 AAAA               22        140

                                      2 BBBB               22        140

                                      3 CCCC               22        140

                                      4 DDDDDDDD           22        140

                                      5 EEEEEE             22        140

                                      6 FFFFFFF            22        140

4、查看T2表总共占据的block数据

SQL> exec dbms_stats.gather_table_stats(user,'T2');

 

PL/SQL procedure successfully completed

 

SQL> select num_rows,blocks from user_tables where table_name='T2';

 

  NUM_ROWS     BLOCKS

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

         6          5

通过实验数据可以看到行数据在140#块上,而表T2的起始块是136#。将每个块dump下来对比:

 

 

136#:Dump of First Level Bitmap Block

 

137#:Dump of Second Level Bitmap Block

 

138#:Segment Type:      138存放段该table的块头,一级位图和二级位图地址以及该segment拥有的extent总数

 

SQL> select header_block from dba_segments where segment_name='T2';

 

HEADER_BLOCK

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

         138

 

 

139#:type: 0x06=trans data   

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!