`

Oracle数据库通过undo保证一致性读和不发生脏读

 
阅读更多

不发生脏读,用户A对表更新了,没有提交,用户B对进行查询,没有提交的更新不能出现在用户的查询结果中。

实例模拟:表test中的数据如下

1,用户A查询:SQL> select * from test;
ID NAME
---------- ----------
1 A
2 B

2,用户B:update test set name='C' where id=1;没有提交

3,用户A再次查询:SQL> select * from test;
ID NAME
---------- ----------
1 A
2 B

查询到数据块的信息

select id, rowid, dbms_rowid.rowid_relative_fno(rowid) fn,dbms_rowid.rowid_block_number(rowid) bk from test order by id
这时候dump 数据块(内存中的数据块)alter system dump datafile 4 block 6717,

Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.02d.00000323 0x008001c5.0297.0d C--- 0 scn 0x0000.0022cf82
0x02 0x0006.020.00000320 0x0080048c.017d.03 ---- 1 fsc 0x0000.00000000

。。。。
block_row_dump:
tab 0, row 0, @0x1f90
tl: 8 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 02
col 1: [ 1] 43
tab 0, row 1, @0x1f88
tl: 8 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [ 1] 42
end_of_block_dump

发现id=1的值已经更改了,43(16进制对应的是C),那么A用户得到值为什么还是A呢

这是因为Oracle发现这条数据有lb: 0x2对应的是ITL,从ltl为0x02的记录看到flag为----,表示有事务标记,数据被加锁,需要从undo段的uba(undo block address)中读取。

在undo段中对应的块信息是0x0080048c,这里的数字是16进制的,先将其转为10进制:

select to_number('0080048c','XXXXXXXXXXXXXXX') from dual 得到值8389772

在通过下面的语句得到数据块信息:select dbms_utility.data_block_address_file(8389772), dbms_utility.data_block_address_block(8389772) from dual;

将其内容dump出来

。。。。

KDO Op code: 21 row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x01001a3d hdba: 0x01001a3b
itli: 2 ispac: 0 maxfr: 4858
vect = 3
col 1: [ 1] 41
End dump data blocks tsn: 1 file#: 2 minblk 1164 maxblk 1164

发现其值为41(16进制对应的是A),所以用户A看的值为A。


假设某一个用户A在6点对某一个表发出了一个查询数据量很大的数据,需要15分钟才能把结果完全查询出来,在这期间,6点10分用户B对数据进行了更新并提交了,用户A查询的结果仍然是6点时候的表的数据,用户B更新的数据不出现在用户A的查询结果中,这就是一致性读。

实例模拟:

1,用户查询一个需要长时间运行的报表:

SQL> variable c refcursor;

SQL> exec open :c for select * from test;
PL/SQL procedure successfully completed.

【这里打开cursor但是不取数据,暂停,然后让用户B更新数据】

2,用户B :update test set name='C' where id=1;并且提交。

3,SQL> print :c;
ID NAME
---------- ----------
1 A
2 B

用户B更新数据而且提交了,但是发现用户A得到的结果集仍然是刚开始执行是表中的数据结果。

其原理是用户A在执行开始的时候会保存当时的SCN,在每次从数据块读的时候,会比较保存的SCN和数据块的SCN,如果发现数据块的SCN比保存的SCN小,则数据没有变化,直接从数据块读,如果数据块的大,则需要从undo段中读取。select dbms_flashback.get_system_change_number from dual;可以看到当前的SCN.


一个查询如果耗费很长时间,而查询的结果在查询的阶段被更改了,而且对应着undo段的数据已经被清理了,就会发生Oracle中著名的ORA-013555: snapshot too old(快照太久)错误。


如果一条数据在一个时间段被更新多次并提交了,后放入undo段的块会记录相对以的块上次放在undo段中的块地址,从而可以一直寻找到比开始查询时候记录的SCN小的那个undo段中的数据块。



http://apps.hi.baidu.com/share/detail/23920116有更详细的解释

分享到:
评论

相关推荐

    构建最高可用Oracle数据库系统 Oracle 11gR2 RAC管理、维护与性能优化

    5.1.1数据读一致性与写一致性 5.1.2多版本数据块 5.1.3 ANSIISO事务隔离级别 5.1.4 Oracle事务隔离级别 5.1.5锁管理器 5.2 RAC资源的协调和管理 5.2.1 Cache Fusion的结构 5.2.2 Cache Fusion工作原理 5.2.3...

    Oracle 9i&10g编程艺术:深入数据库体系结构(全本)含脚本

    3.4.2 Oracle数据库中的存储层次体系 87 3.4.3 字典管理和本地管理的表空间 91 3.5 临时文件 93 3.6 控制文件 95 3.7 重做日志文件 95 3.7.1 在线重做日志 96 3.7.2 归档重做日志 98 3.8 密码文件 100 3.9 ...

    Oracle自学(学习)材料 (共18章 偏理论一点)

    目标 10-2 回滚段管理概述 10-3 回滚段 10-4 回滚段:用途 10-5 读一致性 10-6 回滚段的类型 10-7 自动回滚管理:概念 10-8 自动回滚管理:设置 10-9 自动回滚管理:初始化参数 10-10 自动回滚管理:UNDO 表空间 ...

    深入解析Oracle.DBA入门进阶与诊断案例

    8.3 并发控制和一致性读 349 8.4 回滚段的前世今生 350 8.5 Oracle 10g的UNDO_RETENTION管理增强 355 8.6 UNDO_RETENTION的内部实现 357 8.7 Oracle 10g In Memory Undo新特性 358 8.8 Oracle 11g UNDO表...

    深入解析OracleDBA入门进阶与诊断案例 3/4

     8.3 并发控制和一致性读   8.4 回滚段的前世今生   8.5 Oracle 10g的UNDO_RETENTION管理增强   8.6 UNDO_RETENTION的内部实现   8.7 Oracle 10g In Memory Undo新特性   8.8 Oracle 11g UNDO表...

    深入解析OracleDBA入门进阶与诊断案例 2/4

     8.3 并发控制和一致性读   8.4 回滚段的前世今生   8.5 Oracle 10g的UNDO_RETENTION管理增强   8.6 UNDO_RETENTION的内部实现   8.7 Oracle 10g In Memory Undo新特性   8.8 Oracle 11g UNDO表...

    深入解析OracleDBA入门进阶与诊断案例 4/4

     8.3 并发控制和一致性读   8.4 回滚段的前世今生   8.5 Oracle 10g的UNDO_RETENTION管理增强   8.6 UNDO_RETENTION的内部实现   8.7 Oracle 10g In Memory Undo新特性   8.8 Oracle 11g UNDO表...

    Oracle9i的init.ora参数中文说明

    Oracle9i初始化参数中文说明 Blank_trimming: 说明: 如果值为TRUE, 即使源长度比目标长度 (SQL92 兼容) 更长, 也允许分配数据。 值范围: TRUE | FALSE 默认值: FALSE serializable: 说明: 确定查询是否获取表级...

    [Oracle] 浅析令人抓狂的ORA-01555问题

    这个错误是由数据库的读一致性(Read consistency)引起的,当查询需要访问被修改的数据时,它会到undo里访问该数据的前镜像,如果该前镜像已被覆盖,查询语句就会返回ORA-01555的错误。 2. 导致ORA-01555错误的主要...

    Oracle 11g 新特性 Flashback Data Archive 使用实例

    对于某些重要的表可以自定义它的历史记录保存期限,它的的种种行为与undo表空间十分相似,使用的时候也是完全透明的,用户不知道它的查询一致性视图数据是来自undo还是Flashback Data Archive,现来分析它与undo的几...

    Oracle编程艺术

    3.4.2 Oracle数据库中的存储层次体系..............................................181 3.4.3 字典管理和本地管理的表空间..................................................186 3.5 临时文件..........

Global site tag (gtag.js) - Google Analytics