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
来源:https://www.cnblogs.com/maruidong/p/6323327.html