ORACLE 数据块、ITL SELECT和UPDATE逻辑梳理

理解粗浅,仅供参考


这里数据块指的都是缓冲区数据块

一致性读文章参考:http://hi.baidu.com/edeed/item/7aff6ee4b3f0870f8d3ea8b3

DUMP数据块文章参考:http://blog.163.com/dazuiba_008/blog/static/363349812012111111399549


ORACLE 9.2.0

DUMP的意思是查看一个数据块的内容

PLSQL命令窗口由ROWID查找数据块位置,普通权限用户

SQL> select t.*,dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block# from test_user t;
 
        ID        AGE NAME           FILE#     BLOCK#
---------- ---------- --------- ---------- ----------
         1        999 tommy              1      85546
         2        999 jerry              1      85546
         3        999 henry              1      85546
         4        999 hibernate          1      85546
         5        999 birt               1      85546
         6        999 garden             1      85546
         7        999 green              1      85546
         8        999 green              1      85546
         9        999 green              1      85546
        10        999 green              1      85546
 
10 rows selected
对应文件号、块号

ALTER SYSTEM CHECKPOINT;手动刷新缓存到数据文件,没有这一步,物理文件可能与缓冲区内容不一致,DBWN参考http://blog.chinaunix.net/uid-24501667-id-3028586.html
ALTER SYSTEM DUMP DATAFILE 1 BLOCK 85546;生成BLOCK对应的TRACE文件
第一次DUMP生成一个.trc(TRACE)文件,以后的DUMP会把结果附加到文件里面,以时间分别。

进入LINUX ORACLE目录

$ pwd
/oracle/product/9.2.0/admin/***
$ ll
total 16
drwxr-xr-x   2 oracle     oinstall        96 Jan 17 10:40 adump
drwxr-xr-x   2 oracle     oinstall      4096 May 13 10:12 bdump
drwxr-xr-x   2 oracle     oinstall        96 Jan 17 10:40 cdump
drwxr-xr-x   2 oracle     oinstall        96 Jan 17 11:48 create
drwxr-xr-x   2 oracle     oinstall        96 Jan 17 10:40 hdump
drwxr-xr-x   2 oracle     oinstall        96 Jan 17 11:48 pfile
drwxr-xr-x   2 oracle     oinstall        96 Jan 17 11:48 scripts
drwxr-xr-x   2 oracle     oinstall      4096 May 23 14:23 udump
$ 

在*DUMP文件夹里面找。我的文件在UDUMP目录。

$ cd udump
$ ls -lt
total 176
-rw-r-----   1 oracle     oinstall     18660 May 23 16:19 ***_ora_7997.trc
-rw-r-----   1 oracle     oinstall      5582 May 23 10:23 ***_ora_3771.trc
-rw-r-----   1 oracle     oinstall      1725 May 13 10:13 ***_ora_14056.trc
-rw-r-----   1 oracle     oinstall      3720 Apr 19 18:41 ***_ora_1205.trc
-rw-r-----   1 oracle     oinstall      3390 Apr 19 18:22 ***_ora_28836.trc
...
以更新时间排序。
然后可以more vi cat 看文件内容了。


先说说我对于一致性读的理解

一致性读文章参考:http://hi.baidu.com/edeed/item/7aff6ee4b3f0870f8d3ea8b3

SQL执行计划有Consistent gets 和 db block gets,很多文章说前者是读UNDO块,让人误解,其实这两个命名是有道理的。前者指需要保证一致性读从而读到的数据块,从而可能读到UNDO BLOCK,也可能不会,后者相反指不需保证一致性,完全从DATA BLOCK读取。比如SELECT必须保证一致性读,UPDATE不需要,会选择db block gets从数据块直接读。

借用上面链接的例子,分析一下数据块和ITL、UNDO块。

表TB1,1W条记录,第一万条记录在数据块在DB1,上一次更新在8:50,用户A在9:00遍历全表,需要15分钟到达最后一行,9:15读到的数据应该是9:00时刻的快照结果,而无论期间有没有更新,提交未提交。这就是一致性读。

9:00 DB1中的ITL信息为:SCN850    UNDO1/提交标志、事务号等

9:10用户B修改最后一行,不管提交未提交,DB1中ITL信息为:SCN910   UNDO2,其他

(更新与提交都会修改SCN,SCN结果会被修改两次,数据块头也有一个SCN,ITL中也有一个SCN,这些先不管)

ITL显示的信息是,数据块最后一次修改的流水号,此次修改以前数据保存的回滚段位置(更新数据会立即更新数据块,不管提交未提交,同时保存更新前数据到UNDO表空间),进入UNDO2,可以看到其中除了包含本次事务前的数据(或者其他能够完成回滚的操作数据),还有一个ITL,这个ITL是从数据块DB1里面复制过来的,DB1中更新ITL为SCN910之前先把其中数据复制到UNDO2,所以UNDO2中ITL为:SCN850 UNDO1,其他


9:11用户C修改数据块DB1,ITL变为:SCN911  UNDO3,其他

UNDO3中ITL为:SCN910   UNDO2,其他


9:15查询到数据块DB1时,发现SCN911大于查询SCN900,于是进入UNDO3,发现SCN910依然大过900,进入UNDO2,OK,然后由UNDO2和UNDO3里面的回滚操作数据组织出8:50DB1的数据,OK

ORA-01555快照过旧。更新数据如果提交的话,ITL有提交标志,提交后UNDO BLOCK允许被覆盖(这里超时时间好像可以设置)

如果9:10更新被提交,UNDO2标记已提交,然后9:12被其他事务覆盖,其中ITL为SCN912  UNDO4,其他

9:15查询到达的时候,根据UNDO3找到UNDO2块,发现其中SCN912大过UNDO3中的SCN911,抛出此异常。显然,根本重现不了9:00时刻的数据快照了。


-----------------------------------------------------------------------一致性读OVER----------------------------------------------------------------------------

-----------------------------------------------------------------------UPDATE做了哪些工作 开始------------------------------------------------------------------------

参考http://zhidao.baidu.com/question/480089238.html


个人理解。

UPDATE过程中主要实现两件事,行锁和回滚支持,这里只关心数据块的改动。

申请到undo资源,写入数据->在数据块头ITL表中申请一个空表项,写入数据->在每条要修改的记录行的行头写入申请到的ITL索引->更新数据

在四个SESSION中执行四条不同的UPDATE修改四条数据。几分钟后提交两条数据,另外两条未提交。
可见ITL中FLAG的--U--标志,意思是已提交但是提交操作在更新操作很久以后。
----是未提交。--C--是
--- flag     1 nibble   ---- = 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


*** 2013-05-23 15:53:31.242
Start dump data blocks tsn: 0 file#: 1 minblk 85546 maxblk 85546
buffer tsn: 0 rdba: 0x00414e2a (1/85546)
scn: 0x0000.059dfd7b seq: 0x01 flg: 0x02 tail: 0xfd7b0601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Block header dump:  0x00414e2a
 Object id on Block? Y
 seg/obj: 0xcabd  csc: 0x00.59dfd09  itc: 4  flg: O  typ: 1 - DATA
     fsl: 0  fnx: 0x0 ver: 0x01
 
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0003.02d.0000ea56  0x0080002f.195a.13  ----    1  fsc 0x0000.00000000
0x02   0x0002.00c.0000eb42  0x00800020.1bf1.27  ----    1  fsc 0x0000.00000000
0x03   0x000a.00d.0000b2aa  0x0080029d.109e.47  --U-    1  fsc 0x0000.059dfd7b
0x04   0x0004.019.0000b27e  0x0080003e.16b2.2a  --U-    1  fsc 0x0000.059dfd79
 
data_block_dump,data header at 0x8000000100193c8c
===============
tsiz: 0x1f70
hsiz: 0x26
pbl: 0x8000000100193c8c
bdba: 0x00414e2a
     76543210
flag=--------
ntab=1
nrow=10
frre=-1
fsbo=0x26
fseo=0x1dc8
avsp=0x1ea6
tosp=0x1ea6
0xe:pti[0]      nrow=10 offs=0
0x12:pri[0]     offs=0x1ef3
0x14:pri[1]     offs=0x1ee3
0x16:pri[2]     offs=0x1e3c
0x18:pri[3]     offs=0x1e28
0x1a:pri[4]     offs=0x1e19
0x1c:pri[5]     offs=0x1e08
0x1e:pri[6]     offs=0x1df8
0x20:pri[7]     offs=0x1de8
0x22:pri[8]     offs=0x1dd8
0x24:pri[9]     offs=0x1dc8
block_row_dump:
tab 0, row 0, @0x1ef3
tl: 16 fb: --H-FL-- lb: 0x1  cc: 3
col  0: [ 2]  c1 02
col  1: [ 3]  c2 0b 02
col  2: [ 5]  74 6f 6d 6d 79
tab 0, row 1, @0x1ee3
tl: 16 fb: --H-FL-- lb: 0x0  cc: 3
col  0: [ 2]  c1 03
col  1: [ 3]  c2 0b 02
col  2: [ 5]  6a 65 72 72 79
tab 0, row 2, @0x1e3c
tl: 16 fb: --H-FL-- lb: 0x2  cc: 3
col  0: [ 2]  c1 04
col  1: [ 3]  c2 0b 02
col  2: [ 5]  68 65 6e 72 79
tab 0, row 3, @0x1e28
tl: 20 fb: --H-FL-- lb: 0x3  cc: 3
col  0: [ 2]  c1 05
col  1: [ 3]  c2 0b 02
col  2: [ 9]  68 69 62 65 72 6e 61 74 65
tab 0, row 4, @0x1e19
tl: 15 fb: --H-FL-- lb: 0x4  cc: 3
col  0: [ 2]  c1 06
col  1: [ 3]  c2 0b 02
col  2: [ 4]  62 69 72 74
tab 0, row 5, @0x1e08
tl: 17 fb: --H-FL-- lb: 0x0  cc: 3
col  0: [ 2]  c1 07
col  1: [ 3]  c2 0a 64
col  2: [ 6]  67 61 72 64 65 6e
tab 0, row 6, @0x1df8
tl: 16 fb: --H-FL-- lb: 0x0  cc: 3
col  0: [ 2]  c1 08
col  1: [ 3]  c2 0a 64
col  2: [ 5]  67 72 65 65 6e
tab 0, row 7, @0x1de8
tl: 16 fb: --H-FL-- lb: 0x0  cc: 3
col  0: [ 2]  c1 09
col  1: [ 3]  c2 0a 64
col  2: [ 5]  67 72 65 65 6e
tab 0, row 8, @0x1dd8
tl: 16 fb: --H-FL-- lb: 0x0  cc: 3
col  0: [ 2]  c1 0a
col  1: [ 3]  c2 0a 64
col  2: [ 5]  67 72 65 65 6e
tab 0, row 9, @0x1dc8
tl: 16 fb: --H-FL-- lb: 0x0  cc: 3
col  0: [ 2]  c1 0b
col  1: [ 3]  c2 0a 64
col  2: [ 5]  67 72 65 65 6e
end_of_block_dump

其中行头lb指向的就是ITL索引

有几个事务,ITL就有几条记录

seg/obj:对象ID,查DBA_OBJECTS 可查到表名,进制转换to_char(123,’xxx’)、TO_NUMBER(’19F’,’XXX’)、bin_to_num(1,1,0,1)

bdba:数据块所在文件号和数据块号

         0x00414e2a换成二进制0000 0000 0100 0001 0100 1110 0010 1010,取前十位是文件号,后面部分表示块号,14e2a的十进制为85546

nrow 该块上数据行数量

tl: 16行大小字节数  cc: 3列数    字节值由 DUMP(1,'16')或者 DUMP('TOMMY','16')得到,[]里面为字节数

XID   0x0003.02d.0000ea56
          查V$TRANSACTION其中0003对应XIDUSN,02d对应XIDSLOT,0000ea56对应XIDSQN   
UBA  0x00c02d8a.0090.20 

        ->0000000011=3号文件,0x2d8a=11658号块,0x90=undo块被覆盖144次,0x20=第32条undo记录

-------------------------------------------------------------------UPDATE OVER-----------------------------------------------------------------------------

-------------------------------------------------------------------SELECT 开始-----------------------------------------------------------------------------

表TB1 9:00有两条记录都是ABC

9:10用户A改第一条为XYZ未提交

9:11用户B改第二条为UVW立即提交

9:15用户C查表结果为ABC、UVW

而数据块的记录很明显是XYZ、UVW

猜测,读取一行数据时,找到ITL,0自然就不管了,判断ITL提交状态,未提交时会进入UNDO BLOCK由此组织数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值