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

简介:


崔华,网名 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的事务隔离机制,事务恢复原理。


本文出自数据和云公众号,原文链接


相关文章
|
7月前
|
存储 Oracle 关系型数据库
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
在YMP校验过程中,从yashandb同步至Oracle的数据出现timestamp(0)字段不一致问题。原因是yashandb的timestamp(x)存储为固定6位小数,而Oracle的timestamp(0)无小数位,同步时会截断yashandb的6位小数,导致数据差异。受影响版本:yashandb 23.2.7.101、YMP 23.3.1.3、YDS联调版本。此问题会导致YMP校验数据内容不一致。
|
8月前
|
Oracle 关系型数据库 Linux
【YashanDB 知识库】通过 dblink 查询 Oracle 数据时报 YAS-07301 异常
客户在使用 YashanDB 通过 yasql 查询 Oracle 数据时,遇到 `YAS-07301 external module timeout` 异常,导致 dblink 功能无法正常使用,影响所有 YashanDB 版本。原因是操作系统资源紧张,无法 fork 新子进程。解决方法包括释放内存、停掉不必要的进程或增大进程数上限。分析发现异常源于 system() 函数调用失败,返回 -1,通常是因为 fork() 失败。未来 YashanDB 将优化日志信息以更好地诊断类似问题。
|
7月前
|
Oracle 关系型数据库 Java
【YashanDB知识库】Flink CDC实时同步Oracle数据到崖山
本文介绍通过Flink CDC实现Oracle数据实时同步至崖山数据库(YashanDB)的方法,支持全量与增量同步,并涵盖新增、修改和删除的DML操作。内容包括环境准备(如JDK、Flink版本等)、Oracle日志归档启用、用户权限配置、增量日志记录设置、元数据迁移、Flink安装与配置、生成Flink SQL文件、Streampark部署,以及创建和启动实时同步任务的具体步骤。适合需要跨数据库实时同步方案的技术人员参考。
【YashanDB知识库】Flink CDC实时同步Oracle数据到崖山
|
7月前
|
数据采集 JSON 数据可视化
JSON数据解析实战:从嵌套结构到结构化表格
在信息爆炸的时代,从杂乱数据中提取精准知识图谱是数据侦探的挑战。本文以Google Scholar为例,解析嵌套JSON数据,提取文献信息并转换为结构化表格,通过Graphviz制作技术关系图谱,揭示文献间的隐秘联系。代码涵盖代理IP、请求头设置、JSON解析及可视化,提供完整实战案例。
438 4
JSON数据解析实战:从嵌套结构到结构化表格
|
7月前
|
存储 Oracle 关系型数据库
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
|
7月前
|
Oracle 关系型数据库 Linux
【YashanDB知识库】通过dblink查询Oracle数据时报YAS-07301异常
【YashanDB知识库】通过dblink查询Oracle数据时报YAS-07301异常
|
7月前
|
JSON 监控 网络协议
Bilibili直播信息流:连接方法与数据解析
本文详细介绍了自行实现B站直播WebSocket连接的完整流程。解析了基于WebSocket的应用层协议结构,涵盖认证包构建、心跳机制维护及数据包解析步骤,为开发者定制直播数据监控提供了完整技术方案。
|
7月前
|
机器学习/深度学习 JSON 算法
淘宝拍立淘按图搜索API接口系列的应用与数据解析
淘宝拍立淘按图搜索API接口是阿里巴巴旗下淘宝平台提供的一项基于图像识别技术的创新服务。以下是对该接口系列的应用与数据解析的详细分析
|
8月前
|
Oracle 关系型数据库 Linux
【YashanDB 知识库】通过 dblink 查询 Oracle 数据时报 YAS-07301 异常
某客户在使用 YashanDB 通过 yasql 查询 Oracle 数据时,遇到 `YAS-07301 external module timeout` 异常,导致 dblink 功能无法正常使用,影响所有版本。问题源于操作系统资源紧张,无法 fork 新子进程。解决方法包括释放内存、停掉不必要的进程或增大进程数上限。分析发现异常原因为系统调用 fork() 失败。经验总结:优化日志记录,提供更多异常信息。
|
7月前
|
存储 Oracle 关系型数据库
【YashanDB知识库】YMP校验从yashandb同步到oracle的数据时,字段timestamp(0)出现不一致
【YashanDB知识库】YMP校验从yashandb同步到oracle的数据时,字段timestamp(0)出现不一致

推荐镜像

更多