本帖最后由 zcs0237 于 2013-6-13 16:57 编辑
a.本文搜集大量网友文章编写而成
b.为节省篇幅,部分输出结果做了精简
c.感谢对本帖补充、建议、错误更正
d.推荐网站:
=========本文内容:数据块dump相关知识简化总结===========
实验说明:将dump与select出的以下信息比较、分析
1、表的总行数、总列数
2、所改列为第几行第几列
3、从数据块中找到字段值
4、itl事务号与v$trasaction事务号
5、commit对itl中flag/scn的改变
6、commit仅改变itl 条目的flag,its lck和row-header的lb事务指针不变
************************************************
01.1-相关基础知识
一、data block相关原理1、事务修改数据块的流程
--server进程把block读入data buffer
--延迟block cleanout
--在块上请求ITL slot
--如果其他活跃事务通过ITL锁定了要修改的行,则入等待队列。
--锁定要修改的行:事务修改块中的行时,把行中row header中的lb字段置为该事务在该块中获得的ITL的编号,这就是oracle行锁的实现。
2、事务槽与事务表
事务槽:数据块头中(见下图中的Transaction Header),块头中每个ITL占46B,ITL编号范围为1~255,用一个字节即两个16进制数表示。
事务表:undo段的第一个块,undo段头块存放事务信息
3、dbwr有很多触发条件,经常性的把db buffer中的脏块写入磁盘
二、ITL中Flag所代表的事务状态---- = 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
三、块的物理结构
1、The Cache Header-------------------------------------------------------------------------------------------------------------------------
Start dump data blocks tsn: 4 file#: 4 minblk 32 maxblk 32
buffer tsn: 8 rdba: 0x00c0007a (3/122)
scn: 0x0000.0068d716 seq: 0x01 flg: 0x02 tail: 0xd7160601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Hex dump of corrupt header 3 = CHKVAL
Dump of memory from 0x0EB8B400 to 0x0EB8B414
… …
2、The Transaction Header(块中的transaction信息)
①ITL list的头信息-----------------------------------------------------------------------------------------------Object id on Block? Y
seg/obj: 0xc7cc csc: 0x00.86f4c itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1000019 ver: 0x01 opc: 0
②Intrest Transaction List -------------------------------------------------------------------------------Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.00b.00000fac 0x00801885.008c.56 --U- 1 fsc 0x0000.0068d716
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
3、data area header
①table dictionary header------------------------------------------------------------------------------------------------------------------------
data_block_dump,data header at 0xeb8b464
===============
tsiz: 0x1f98 //total data area size
hsiz: 0x2e //data header size
pbl: 0x0eb8b464 //pointer指针to buffer holding the block
bdba: 0x01000020 //block dba / rdba
flag=-------- //n=pctfree hit(clusters),f=don't put on freelist,k=flushable cluster keys
ntab=1 //number of tables (>1 so this is a cluster)
nrow=14 //number of rows
frre=-1 //First free row index entry. -1=you have to add one.
fsbo=0x2e //free space begin offset
fseo=0x1d61 //free space end offset
avsp=0x1d33 //available space in the block
tosp=0x1d33 //total available space when all transactions commit
0xe:pti[0] nrow=14 offs=0
②row directroy 每增加一条row就多出2bytes用来记载该row--------------------------------------------------------------------------------------------------------------------------
0x12:pri[0] offs=0x1f72
0x14:pri[1] offs=0x1f47
……
0x2c:pri[13] offs=0x1d61
③row header--------------------------------------------------------------------------------------------------------------------------
tab 0表号, row 0行号, @0x1f72 //row header
tl: 38行size fb: --H-FL-- lb: 0x2事务槽号 cc: 8总列数
④row data--------------------------------------------------------------------------------------------------------------------------
col 0: [ 3] c2 4a 46 //column length
… …
col 6: *NULL*
col 7: [ 2] c1 15
************************************************
01.2-select查询得到的信息
一、emp表共14行SQL> select count(*) from scott.emp;
14
二、emp表共8字段,SAL为第6字段SQL> select * from scott.emp where rownum=1;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------ ------- ------ ------ --------- ----- ------ -------
7369 SMITH CLERK 7902 17-DEC-80 800 20
************************************************
01.3-dump出的信息(commit前)
一、修改第1行的第6个字段改为8000SQL> set heading off
select ename,sal from scott.emp where sal=800;
--SMITH 800薪水为800的只有一条记录
SQL> update scott.emp set sal=8000 where sal=800;
--1 row updated.
二、该条记录在4号文件第32号块上SQL> select 'file# '||dbms_rowid.rowid_relative_fno(rowid),'block# '||dbms_rowid.rowid_block_number(rowid) from scott.emp where sal=8000;
--file# 4 block# 32
三、dump导出4号文件32号块SQL> alter system dump datafile 4 block 32;
--System altered.
四、列出dump文件SQL> select '!vi ' || d.VALUE || '/'
|| LOWER (RTRIM (i.INSTANCE, CHR (0)))
|| '_ora_' || p.spid || '.trc' trace_file_name
FROM (select p.spid FROM v$mystat m, v$session s, v$process p
WHERE m.statistic# = 1 AND s.SID = m.SID AND p.addr = s.paddr) p,
(select t.INSTANCE FROM v$thread t, v$parameter v WHERE v.NAME = 'thread'
AND (v.VALUE = 0 OR t.thread# = TO_NUMBER (v.VALUE))) i,
(select value from v$parameter where name = 'user_dump_dest') d
/
-- !vi /u01/app/oracle/admin/orcl/udump/orcl_ora_3698.trc
五、在vi中输入/Itl搜第一个Itl(I要大写)=块的热点ITL Slot
SQL> !vi /u01/app/oracle/admin/orcl/udump/orcl_ora_3698.trc
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.011.000000f2 0x00805794.00c8.49 C--- 0 scn 0x0000.0006bfdb
0x02 0x0006.02c.00000108 0x0080073b.00c4.03 ---- 1 fsc 0x0000.00000000
1、flag=-----说明事务还在活动
2、0x02事务槽Lck=1——说明此事务锁定1行
3、scn/fsc为空——说明未clean out
补充:由此知道ORACLE中的row lock是记录在block header中的。
六、对比dump、select:事务ID相同1、查看ITL的XID(=usn#.slot#.wrap#)
SQL> select xidusn,xidslot,xidsqn from v$transaction;
-- 6 44 264
2、转换dump文件中的itl
SQL> select to_number('6','XX'),to_number('2c','XXX'),to_number('108','XXXX') from dual;
-- 6 44 264
七、用grep定位指向第0x2事务的行并分析
$ grep -E '\' -B1 -A 9 /u01/app/oracle/admin/orcl/udump/orcl_ora_3698.trctab 0, row 0, @0x1f72 //row0=第1行
tl: 38 fb: --H-FL-- lb: 0x2 cc: 8 //lb:0x2指向第二个Itl条目
col 0: [ 3] c2 4a 46 //第1个字段
... ...
col 5: [ 2] c2 51 //第6个字段
col 6: *NULL*
col 7: [ 2] c1 15
tab 0, row 1, @0x1f47
1、row 0 lb: 0x2————证明我们update的是表的第1行
2、cc: 8和col 0~col 7——证明与select看到的8列一致
3、证明第6列已改为8000
SQL> select UTL_RAW.CAST_TO_NUMBER(replace(' c2 51 ',' ')) from dual;
--8000 //把oracle内部16进制转成表中字段的数据与update新值做比较
************************************************
01.4-dump出的信息(commit后)
一、提交后再dumpSQL> commit;
alter system dump datafile 4 block 32;
二、列出新的dump文件SQL> @gettracefile.sql
--!vi /u01/app/oracle/admin/orcl/udump/orcl_ora_3975.trc
三、查看事务槽——有两点变化SQL> !vi /u01/app/oracle/admin/orcl/udump/orcl_ora_3975.trc
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.011.000000f2 0x00805794.00c8.49 C--- 0 scn 0x0000.0006bfdb
0x02 0x0006.02c.00000108 0x0080073b.00c4.03 --U- 1 fsc 0x0000.000874f7
1、flag= U-----证明transaction committed
2、fsc、scn——证明fsc快速提交,且已clean out
3、Lck=1———证明falg=U事务已提交,Itl可重用了不需清除lck
四、查看行头——指向lb:0x2没变,利于commit效率提高
$ grep -E '\' -B1 -A 9 /u01/app/oracle/admin/orcl/udump/orcl_ora_3975.trctab 0, row 0, @0x1f72
tl: 38 fb: --H-FL-- lb: 0x2 cc: 8
col 0: [ 3] c2 4a 46
col 1: [ 5] 53 4d 49 54 48
col 2: [ 5] 43 4c 45 52 4b
col 3: [ 3] c2 50 03
col 4: [ 7] 77 b4 0c 11 01 01 01
col 5: [ 2] c2 51
col 6: *NULL*
col 7: [ 2] c1 15
tab 0, row 1, @0x1f47
最近itpub发帖:
无GUI智能部署oracle脚本及视频
http://www.itpub.net/thread-1778735-1-1.html
有哪些Oracle进程?消耗了多少存?http://www.itpub.net/thread-1780654-1-1.html