一致性读(Read Consistency)的深入解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 一致性读在Oracle中是一个非常重要的概念, 大家一起跟着我先来做下面的一个实验:

image.png

gyj@OCM> create table gyj (id int,name varchar2(10));
Table created.
gyj@OCM> insert into gyj values(1,'GGGGGG');
1 row created.
gyj@OCM> commit;
Commit complete.
gyj@OCM> select * from gyj;

    ID NAME

     1 GGGGGG

gyj@OCM> var x refcursor
gyj@OCM> exec open :x for select * from gyj;
PL/SQL procedure successfully completed.
gyj@OCM> update gyj set name='YYYYYY' where id=1;
1 row updated.
gyj@OCM> commit;
Commit complete.
gyj@OCM> update gyj set name='JJJJJJ' where id=1;
1 row updated.
gyj@OCM> commit;
Commit complete.
gyj@OCM> print :x

    ID NAME

     1 GGGGGG

能真正看懂为什么print所显示的这个结果是GGGGGG,而并不是JJJJJJ,那就说明你对一致性读已了解过了。

再往下分析深入分析:做一系列的dump:
gyj@OCM> select id,name,dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from gyj;

    ID NAME       DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)

     1 JJJJJJ                                        6                                  151

sys@OCM> alter system dump datafile 6 block 151;
System altered.
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.010.00000211 0x00c02d8a.0090.20 --U- 1 fsc 0x0000.00100118
0x02 0x0003.00d.000002db 0x00c02d16.00bc.06 C--- 0 scn 0x0000.00100109
bdba: 0x01800097

data_block_dump,data header at 0xd85664

tsiz: 0x1f98
hsiz: 0x14
pbl: 0x00d85664
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f8b
avsp=0x1f77
tosp=0x1f77
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f8b
block_row_dump:
tab 0, row 0, @0x1f8b
tl: 13 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [ 6] 4a 4a 4a 4a 4a 4a

gyj@OCM> select UTL_RAW.CAST_TO_VARCHAR2(replace('4a 4a 4a 4a 4a 4a',' ')) from dual;

UTL_RAW.CAST_TO_VARCHAR2(REPLACE('4A4A4A4A4A4A',''))

JJJJJJ

sys@OCM>alter system dump datafile 3 block 11658;
System altered.

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

  • Rec #0x20 slt: 0x10 objn: 74580(0x00012354) objd: 74580 tblspc: 7(0x00000007)
  • 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: 0x00c02d8a.0090.1d ctl max scn: 0x0000.000ffd42 prv tx scn: 0x0000.000ffd5a
txn start scn: scn: 0x0000.00100109 logon user: 91
prev brb: 12594569 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x04 ver: 0x01
compat bit: 4 (post-11) padding: 1
op: L itl: xid: 0x0007.003.0000021e uba: 0x00c02c50.00a7.3a
flg: C--- lkc: 0 scn: 0x0000.001000f5
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: 0x01800097 hdba: 0x01800092
itli: 1 ispac: 0 maxfr: 4858
vect = 3
col 1: [ 6] 59 59 59 59 59 59

gyj@OCM> select UTL_RAW.CAST_TO_VARCHAR2(replace('59 59 59 59 59 59',' ')) from dual;

UTL_RAW.CAST_TO_VARCHAR2(REPLACE('595959595959',''))

YYYYYY

gyj@OCM>alter system dump datafile 3 block 11542;
System altered.
*-----------------------------

  • Rec #0x6 slt: 0x0d objn: 74580(0x00012354) objd: 74580 tblspc: 7(0x00000007)
  • 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: 0x00c02d16.00bc.04 ctl max scn: 0x0000.000fff10 prv tx scn: 0x0000.000fff16
txn start scn: scn: 0x0000.001000f5 logon user: 91
prev brb: 12594451 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: 0x01800097 hdba: 0x01800092
itli: 2 ispac: 0 maxfr: 4858
vect = 3
col 1: [ 6] 47 47 47 47 47 47

gyj@OCM> select UTL_RAW.CAST_TO_VARCHAR2(replace('47 47 47 47 47 47',' ')) from dual;

UTL_RAW.CAST_TO_VARCHAR2(REPLACE('474747474747',''))

GGGGGG

一到性读的例子(看上图)
 事务T1提交时的SCN是30.
 事务T2提交时的SCN是31.
 事务T3执行了SELECT操作查询,SELECT时SNAP_SCN小于或等于30的数据,在查询到这个数据之前已
被修改过了。
 假设,在这个例子中,在数据缓存中数据块B1最佳的版本是当前的版本B1.事务T3对它之后所有的变
化是不可见的,需要回滚的。对于这个问题需要两个更新执行回滚,因为当T3开始T2还没有提交。

1、描述一致性读的概念?
image.png

image.png

image.png

image.png

2、解释ORA-01555快照过旧的原因,利用实验模拟重现ORA-01555错误?
(1)原因:
a. UNDO段太小,不足以在系统上执行工作
b.你的程序跨 commit获取
c.块清除
image.png
(2)实验步骤:
create undo tablespace undotbs2 datafile '/u01/app/oracle/oradata/ocp/undotbs2.dbf' size 10M;
alter system set undo_tablespace=undotbs2;
alter system set undo_retention=2 scope=both;
第1步、session1: 目标是让b表报快照过旧的报错
conn gyj/gyj

create table a (id int,cc varchar2(10));
insert into a values(1,'hello');
commit;
 create table b(id int,cc varchar2(10));
insert into b values(10,'AAAAAA');
commit;

select * from a;
select * from b;
var x refcursor;
exec open :x for select * from b;
第2步、session2:修改b表,字段cc前镜像"OK"保存在UDNO段中
update b set cc='BBBBBB' where id= 10;
commit;
第3步、session 3:该条语句就是刷新缓存
conn / as sysdba
SQL> alter session set events = 'immediate trace name flush_cache'; --9i提供强制刷缓存

 (alter system flush buffer_cache;--10g提供的一种刷缓存方法)

第4步、 session2: 在A表上行大的事务,多运行几次以确保,回滚段被覆盖
begin
for i in 1..20000 loop

update a set cc='HELLOWWWW';
commit;

end loop;
end;
/
第5步、session 1:在B表上执行查询(第一步的查询)
SQL> print :x
ERROR:
ORA-01555: snapshot too old: rollback segment number 21 with name "_SYSSMU21$" too small

(3)解决方法
a.加大undo表空间。
b.适当设置参数undo_retention.
c.减少SQL运行时间(修改SQL ,缩减where条件后面的查询范围)
d.收集相关对象统计信息(与块清除有关)

3、说说与一致性读相关的一些重要数据字典视图?
V$TRANSACTION
V$LOCK_OBJECT
X$BH
UNDO$
TS$
dba_undo_extents
v$undostat
在整个实验中最关键的是要看懂:
数据块中的事务槽:
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.010.00000211 0x00c02d8a.0090.20 --U- 1 fsc 0x0000.00100118
0x02 0x0003.00d.000002db 0x00c02d16.00bc.06 C--- 0 scn 0x0000.00100109

还有回滚块中的事务槽
op: L itl: xid: 0x0007.003.0000021e uba: 0x00c02c50.00a7.3a

                  flg: C---    lkc:  0     scn: 0x0000.001000f5

还有对UBA地址的解析:
0x00c02d8a.0090.20 ->0000000011=3号文件,0x2d8a=11658号块,0x90=undo块被覆盖144次,0x20=第32条undo记录
0x00c02d16.00bc.06 ->0000000011=3号文件,0x2d16=11542号块,0xbc=undo块被覆盖188次,0x06=第6条undo记录
0x00c02c50.00a7.3a ->0000000011=3号文件,0x2c50=11344号块,0xa7=undo块被覆盖167次,0x3a=第58第undo记录

相关文章
|
6月前
|
算法 Linux C++
【Linux系统编程】深入解析Linux中read函数的错误场景
【Linux系统编程】深入解析Linux中read函数的错误场景
311 0
|
架构师 数据库
深入探讨分布式事务:解析跨多个数据库的一致性
在现代应用程序中,分布式系统已经变得越来越普遍,但同时也带来了一系列的挑战。其中之一就是分布式事务管理,它涉及到在多个数据库或服务之间保持一致性和可靠性。本文将深入介绍分布式事务的概念,探讨不同的实现方式以及它们的优缺点。无论您是开发人员、系统管理员还是系统架构师,了解分布式事务是构建稳健分布式系统的关键一步。
|
5月前
|
存储 安全 Linux
深入解析Linux的`read`命令
`read`命令在Linux shell中用于从标准输入读取数据并赋值给变量。它可以用于交互式脚本,提供用户输入或读文件。关键选项包括`-p`(提示用户)、`-r`(禁用转义)、`-s`(静默模式,适合密码)、`-t`(超时)和`-n`(读取特定字符数)。示例包括基本输入、带提示的密码输入和设置超时的输入。注意安全处理密码和验证用户输入。
|
5月前
|
算法
[白话解析] 深入浅出一致性Hash原理
[白话解析] 深入浅出一致性Hash原理
|
6月前
|
缓存 NoSQL Redis
深度解析Redis的缓存双写一致性
【4月更文挑战第20天】
323 1
|
6月前
|
程序员
深入解析:分布式一致性的终极解决方案——XA协议
本文介绍了分布式系统中的两种一致性协议:2PC(两阶段提交)和3PC(三阶段提交)。2PC分为准备和提交两个阶段,确保所有参与者在提交前达成一致。3PC则在2PC基础上增加了一个CanCommit阶段,提高容错性和可用性,参与者在超时后可自行中断事务。选择协议需依据业务需求和系统特点,高一致性要求可选3PC,注重性能则选2PC。
88 0
|
存储 缓存 NoSQL
缓存面试解析:穿透、击穿、雪崩,一致性、分布式锁、Redis过期,海量数据查找
本文提供了一些保证数据一致性和设计分布式锁的策略。这些策略可以在实际应用中帮助开发人员解决相关的问题,确保系统的数据一致性和并发访问的正确性。同时,通过合理地使用缓存和分布式锁,可以提高系统的性能和可靠性。希望对你在面对Redis相关面试题时有所帮助!
423 0
|
关系型数据库 MySQL 数据库
数据的正确性和完整性:解析MySQL中的一致性
一致性是数据库事务的四个ACID特性之一,包括原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。在数据库管理中,一致性确保了事务的执行能够维持数据库的正确性和完整性。
1070 0
java202303java学习笔记第三十五天有差read方法解析1
java202303java学习笔记第三十五天有差read方法解析1
49 0
java202303java学习笔记第三十五天有差read方法解析2
java202303java学习笔记第三十五天有差read方法解析2
50 0

推荐镜像

更多