ITPub博客

首页 > 数据库 > Oracle > Oracle读一致性

Oracle读一致性

原创 Oracle 作者:mlx_861201 时间:2013-11-25 22:50:32 0 删除 编辑

Oracle读一致性

定义

         Oracle读一致性是指一个查询所获得的数据来自同一时间点。

分类

         Oracle读一致性分为语句级读一致性和事务级读一致性。


  
  

前提



区别



语句级读一致性



Oracle强制实现语句级读一致性。



一个查询语句(select、update、delete)只读取语句开始之前提交的数据。



事务级读一致性



隔离级别为SERIALIZABLE和read only的事务才支持事务级读一致性



事务中的所有查询语句(select 、update、delete)只读取事务开始之前提交的数据



语句级读一致性

         下面将主要讨论语句级读一致性的实现流程。语句级Oracle 读一致性是由构建CR(consistent read)块实现的,CR块就是传说中的一致性读块,CR块是将undo段中修改前映像(PRE IMAGE)和当前块结合而生成的,并会保存在buffer cache中,因为cr clock和 current block的dba是一致的所以会保存在同一个buffer cache chain中,一个 block的最大CR block大小由隐含参数_db_block_max_cr_dba控制。没构造一个CR块,数据库计数器cr block created就会自动加一。

         Oracle在下列很多情况下会生成CR块,下面列出三个比较常见的三种情况:

1、  数据块上有行级锁,并且该锁不是由当前事务加上去的。

2、  打开游标的SCN小于块的SCN。游标打开后数据块被修改。

3、  闪回查询要求查询SCN小于当前块SCN的数据信息。

ORACLE 生成CR块的过程

我们可以对oracle生成CR块的流程进行总结,下图为个人认为的CR生成流程图,当然与oracle生成CR块的实际逻辑相去甚远,仅仅是个人总结,后续试验将进行证明。


流程说明:

    Catch.jpg


1、  查看开始时本例为打开游标时,在PGA中记录打开游标的SCN,假如当前session中有事务则同事也记录XID。

2、  读block到buffer cache中。

3、  分析block的ITL槽,是否有未提交的事务。假如有则执行第四步,假如没有则执行第七步。

4、  假如有未提交的事务,再拿未提交事务的XID与PGA中的XID进行对比。假如相同则执行第七步,假如不相同则执行第五步。

5、  获得未提交事务UBA所指向的undo块,获得undo块中对数据行修改的前映像和对ITL修改的前映像。

6、  将获得的前映像与当前块结合生成临时CR块(该CR块不一定是最终CR块)。

7、  在该步骤中的数据块是没有未提交事务,可能是当前块也可能是临时CR块,获得该数据块的ITL中SCN最大的记录,将该记录的SCN与PGA中查询开始SCN进行对比,假如ITL中的SCN大于查询开始SCN,则继续执行第八步,否则返回该数据库。

8、  从ITL中获得SCN最大的记录,获得UBA,通过UBA获得undo块。

9、  假如undo块已经被覆盖,则返回ora-0155错误。没有被覆盖则继续执行第十步。

10、             获得UBA所指向的undo块,获得undo块中对数据行修改的前映像和对ITL修改的前映像。

11、             将获得的前映像与当前块结合生成临时CR块(该CR块不一定是最终CR块)。

12、             获得该数据块的ITL中SCN最大的记录,将该记录的SCN与PGA中查询开始SCN进行对比,假如ITL中的SCN大于查询开始SCN,则从新继续执行第八步,否则返回该数据库。


语句级一致性读实验数据准备

a)        创建表。


        

scott@ORCL>-- Create table

   

scott@ORCL>create table T

   

     2  (

   

     3    id   VARCHAR2(10),

   

     4    name VARCHAR2(10)

   

     5  );

   

Table created.

   

scott@ORCL>

    
   
   









b)        插入测试数据。


        

scott@ORCL>insert into t    values('1','A');

   

1 row created.

   

scott@ORCL>

    
   
   




c)            

        

scott@ORCL>select t.*,rowid from t;

   

ID         NAME       ROWID

   

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

   

1          A          AAAS5jAAQAAAACGAAA

    
   
  查看数据行ROWID





查看数据行所在的文件号和块号


        

scott@ORCL>select    dbms_rowid.rowid_relative_fno('AAAS5jAAQAAAACGAAA')    fileid,dbms_rowid.rowid_block_number('AAAS5jAAQAAAACGAAA') blockid from    dual;

   

       FILEID    BLOCKID

   

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

   

           16        134

    
   
可以看到该行数据在16号文件134号块。
SESSION1开启游标

a)        开启游标


        

scott@ORCL>var x refcursor;

   

scott@ORCL>exec open :x for select *    from t;

   

PL/SQL procedure successfully    completed.

    
   
   



b)        查看当前SCN


        

scott@ORCL>select T.CURRENT_SCN from    v$database t;

   

CURRENT_SCN

   

-----------

   

      17163033

    
   
   





可以看到当前的scn为17163033。



SESSION2更新数据并提交

a)        执行更新语句


        

scott@ORCL>update t set name='B'    where id = '1';

   

1 row updated.

    
   
   



b)        查看数据块ITL

手动设置系统检查点,dump出16号文件134号块。ITL信息如下:


        

Itl           Xid                  Uba         Flag  Lck           Scn/Fsc

   

0x01      0x0002.00b.000016de     0x00c01104.02f8.27  C-U-    0     scn 0x0000.0105d3ac

   

0x02      0x0009.001.000016d2  0x00c00497.03a6.3e     ----    1  fsc 0x0000.00000000

    
   
   




请留意这里的Xid(0x0009.001.000016d2),ORACLE构造CR块的时候,会取该事务对应的undo(0x00c01104.02f8.27)块中的前映象与当前数据块组合生成CR块。

而Xid(0002.00b.000016de)会在被覆盖,在构造临时CR块时被从新恢复。


c)        查看undo块信息

从Uba(00c00497.03a6.3e)可以知道undo数据块的地址为3号文件的4356块。Dump该块,查看undorecode信息。


        

Undo type:  Regular undo    Begin trans    Last buffer split:  No

   

Temp Object:  No

   

Tablespace Undo:  No

   

rdba: 0x00000000Ext idx: 0

   

flg2: 0

   

*-----------------------------

   

uba: 0x00c00497.03a6.3b ctl max scn:    0x0000.0105df00 prv tx scn: 0x0000.0105df02

   

txn start scn: scn: 0x0000.0105e32e    logon user: 84

   

prev brb: 12583150 prev bcl: 0

   

KDO undo record:

   

KTB Redo

   

op: 0x03  ver: 0x01     

   

compat bit: 4 (post-11) padding: 1

   

op: Z

   

Array Update of 1 rows:

   

tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0    ckix: 191

   

ncol: 2 nnew: 1 size: 0

   

KDO Op code:  21 row dependencies Disabled

   

     xtype: XAxtype KDO_KDOM2 flags: 0x00000080  bdba: 0x04000086  hdba: 0x04000082

   

itli: 2     ispac: 0  maxfr: 4858

   

vect = 2

   

col     1: [ 1]  41

    
   

     在这个undorecode中没有对ITL修改的前映项,因为这个ITL槽第一次被使用。

d)        提交修改


        

scott@ORCL>commit;

   

Commit complete.

   

scott@ORCL>

    
   
   





SESSION2更新数据不提交

a)        执行更新语句


        

scott@ORCL>update t set name = 'C'    where id = '1';

   

1 row updated.

   

scott@ORCL>

    
   
   




b)        查看数据块ITL

手动设置系统检查点,dump出16号文件134号块。ITL信息如下:


        

Itl           Xid                  Uba         Flag  Lck           Scn/Fsc

   

0x01      0x0009.01f.000016cf     0x00c00497.03a6.3f  ----    1     fsc 0x0000.00000000

   

0x02      0x0009.001.000016d2  0x00c00497.03a6.3e  C---       0  scn 0x0000.0105f2c2

    
   
   




可以看到前一个事务(0009.001.000016d2)已经被提交,并且提交的scn为(0105f2c2)。并产生了新的事务(0009.01f.000016cf),原旧事务被覆盖。

c)        查看undo块

从Uba(00c00497.03a6.3f)可以知道undo数据块的地址为3号文件的4356块。Dump该块,查看undo recode信息。


        

* Rec #0x3f  slt: 0x1f     objn: 77411(0x00012e63)  objd:    77411  tblspc: 4(0x00000004)

   

*          Layer:  11 (Row)   opc: 1      rci 0x00   

   

Undo type:  Regular undo    Begin trans    Last buffer split:  No

   

Temp Object:  No

   

Tablespace Undo:  No

   

rdba: 0x00000000Ext idx: 0

   

flg2: 0

   

*-----------------------------

   

uba: 0x00c00497.03a6.3e ctl max scn:    0x0000.0105df02 prv tx scn: 0x0000.0105df03

   

txn start scn: scn: 0x0000.0105f30b    logon user: 84

   

prev brb: 12584064 prev bcl: 0

   

KDO undo record:

   

KTB Redo

   

op: 0x04  ver: 0x01     

   

compat bit: 4 (post-11) padding: 1

   

op: L  itl: xid:     0x0002.00b.000016de uba: 0x00c01104.02f8.27

   

                      flg: C-U-    lkc:     0     scn: 0x0000.0105d3ac

   

Array Update of 1 rows:

   

tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0    ckix: 191

   

ncol: 2 nnew: 1 size: 0

   

KDO Op code:  21 row dependencies Disabled

   

     xtype: XAxtype KDO_KDOM2 flags: 0x00000080  bdba: 0x04000086  hdba: 0x04000082

   

itli: 1     ispac: 0  maxfr: 4858

   

vect = 2

   

col  1: [ 1]     42

    
   
   

  可以看到undo块中包括了对数据行修改的前映像也包括ITL的前映像。

      Session1打印游标

         通过print x 看到打印出来的为A,两个事务都没有对其产生影响。



Catch.jpg (93.73 KB, 下载次数: 1)


Catch.jpg

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/11693228/viewspace-1061072/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: Oracle 补充日志
请登录后发表评论 登录
全部评论

注册时间:2013-01-31

  • 博文量
    11
  • 访问量
    72194