暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

深入内核:Oracle数据提交与事务隔离的深度解析

崔华 2016-03-08
413


崔华,网名 dbsnake

Oracle ACE Director,ACOUG 核心专家

编辑手记:感谢崔华授权我们独家转载其精品文章,也欢迎大家向“Oracle”社区投稿。

大家都知道的一个常识是 - Oracle 里未 commit 的数据除了当前 session 之外,其他 session 是看不到的


我这里演示了一个有趣的例子,在这个例子里我们可以看到,Oracle里未成功 commit 的数据我们也可能能看到

我同时启4个 session。

 

先在 session 1里创建一个表t1,插入一条数据但不 commit:

Session 1:

Connected to Oracle Database 11g

 Enterprise Edition Release 11.2.0.1.0

Connected as scott

SQL> create table t1(id number, name varchar2(10));

Table created

 

SQL> insert into t1 values(1,’CUIHUA’);

1 row inserted

 

SQL> select * from t1;

        ID NAME

———- ———-

         1 CUIHUA

 

此时跳到 session 2,因session 1里刚插入的那条数据还未commit,所以这个时候 session 2是看不到这条数据的:

Session 2:

SQL> select * from t1;

 

        ID NAME

———- ———-

 

接着我们跳到 session 3,把lgwr进程suspend住:

Session 3:

SQL> select spid from v$process where pname=’LGWR’;

 

SPID

————————

2316

 

SQL> oradebug setospid 2316

Oracle pid: 11, Windows thread id: 2316,

 image: ORACLE.EXE (LGWR)

SQL> oradebug suspend

已处理的语句

 

现在我们回到 session 1,执行commit命令,因为 lgwr 进程已经被我们 suspend 住了,所以当前 session 1里要执行的 commit 操作一定会被hang住:

Session1:

SQL> commit;

……这里 hang 住了

 

Oracle 里 commit 操作的流程是这样的:

1、Oracle 先去改这个 transaction 所对应的 undo segment header 中 slot 的状态;

2、改完状态后再 flush log buffer;


现在我们把lgwr hold住了,所以上述步骤2 Oracle是没法做了,但步骤1还是可以做的。

而只要步骤1做完了,其他的 session 就能看到这个transaction所做的改变了(通过ITL中记录的 transaction id 去 check相应的 undo segment header 中 slot 的状态),也就是说对于其他 session 而言,这个 transaction 已经 commit 了,虽然这个 transaction 其实并没有成功commit。

 

好了,我们现在回到session 2,看一下我们现在能否看到刚才insert的那条记录:

Session 2:

SQL> select * from t1;

        ID NAME

———- ———-

         1 CUIHUA

 

从结果里可以看到,刚才看不到的那条记录现在我们已经能看到了,即 session 1对于 session2而言已经 commit 了,虽然 session1的 commit 操作其实并没有成功的做完。

 

现在我们跳到 session 4,执行shutdown abort:

Session 4:

SQL> shutdown abort

ORACLE 例程已经关闭。

 

然后我们再在 session 4中执行 startup,startup 后我们从 alert log 里可以很明显的看到 

Oracle做了 instance recovery:


 

等待上述库成功startup后,我们再次回到session 1,看一下刚才我们已经commit的那条数据是否还在:

Session 1:

SQL> select * from t1;

 

        ID NAME

———- ———-

 

从结果里可以看到,刚才我们 insert 且执行了 commit 操作的那条记录现在已经丢失了。


建议大家动手操作一下,以深入理解Oracle的事务隔离机制,事务恢复原理。


如何加入"云和恩墨大讲堂"微信群

搜索 盖国强(Eygle) :eeygle,或者扫描下面二维码,备注:云和恩墨大讲堂,即可入群。每周与千人共享免费技术分享,与讲师在线讨论。


近期文章

成就卓越:云和恩墨大讲堂期刊第三期

新年贺礼:云和恩墨大讲堂期刊第二期

删繁就简-云和恩墨的一道面试题解析

用SQL解一道数学题:Gauss和Poincare

新年贺礼:云和恩墨大讲堂期刊发行

2015 Oracle 十大热门文章精选

Oracle 12c ASM 防火防盗新特性揭秘

DBA入门之路:学习与进阶之经验谈

DBA入门之路:关于日常工作的建议

云和恩墨

数据驱动,成就未来。整合业界顶尖的技术与合作伙伴资源,围绕数据及相关领域,提供解决方案和专业服务。(业务联系电话: 01059003186-8019 )
业务架构
电子渠道(网络销售)分析系统、数据治理
IT基础架构
分布式存储解决方案 | zData一体机 | 容灾环境建设
数据架构
Oracle DB2 MySQL NoSQL
专项服务:架构/安全/容灾/优化/整合/升级/迁移
运维服务:运维服务  代维服务
人才培养:个人认证  企业内训
软件产品:SQL审核、监控、数据恢复
应用架构
应用软件和中间件:数据建模 | SQL审核和优化 | 中间件服务


文章转载自崔华,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论