commit 流程
COMMIT是一个非常快的操作,当我们发布commit命令时,真正困难的动作已经完成,
在数据库中已经执行了数据更改,所以已经完成了99%的任务,例如:下列操作已经产生:
1.在SGA(Buffer Cache)中已经生成了undo块;
2.在SGA(Buffer Cache)中已经生成了产生改变的数据块和索引块;
3.在REDO LOG BUFFER生成了前面两项的redo信息;
4.依赖于前三项产生的数据量大小以及操作需要的时间,buffer中的数据可能已经
有一部分输出到了磁盘;
5.所有需要的锁已经获得;
当执行COMMIT命令时,只执行如下操作:
1.为事务生成SCN:SCN是ORACLE数据库的一种计时信息,用以保证事务的顺序性,
同时还用于失败恢复和保证数据库的读一致性和检查点,无论何时何人提交,SCN
自动加1;
2.将事务相关的未写入redo log file中的redo信息从redo log buffer写入到redo log
file,这才是真实的COMMIT,这步操作完成,说明我们已经完成COMMIT,事务从
V$TRANSACTION中移除;
3.V$LOCK中记录的SESSION关于该事务的锁会释放,其他需要这些锁的事务被唤醒;
4.执行块清理,清理块头保存的事务信息;
Oracle Commit
Oracle还是比较常用的,于是我研究了一下Oracle COMMIT,在这里拿出来和大家分享一下,希望对大家有用。只有当SQL语句影响的所有行所在的最后一个块被读入DB BUFFER并且重做信息被写入REDO LOG BUFFER之后,用户才可以发出COMMIT,Oracle COMMIT触发LGRW,但并不强制立即DBWN来释放所有相应的DB BUFFER块上的锁,但在随后的一段时间内DBWN还在写这条语句涉及的数据块的情形,表头部的行锁,并不是在COMMIT一发出就马上释放,实际上要等到相应的DBWN进程结束才会释放。
一个用户请求锁定另一个用户已COMMIT的资源不成功的机会是存在的。Oracle COMMIT发出后会将回滚段中的"前映像"标识为已提交.DML语句会产生一个SCN号,DBWN触发时写入到数据块的头部,COMMIT时也会产生一个SCN号,也会被写入数据块的头部。在数据块的头部只存储一个最新的SCN号,
COMMIT之后这个事务插槽可以被另外一个事务使用。如果用户ROOLBACK,则服务器进程会根据数据文件块和DB BUFFER中块的头部的事务列表和SCN以及回滚段地址重构出相应的修改前的副本,并且用这些原值来还原当前数据文件中已修改但未提交的改变。如果有多个"前映像",服务器进程会在一个"前映像"的头部找到"前前映像"的回滚段地址,一直重构出同一事务下的最早的一个"前映像"为止。一旦发出了COMMIT,用户就不能ROLLBACK,这使得COMMIT后DBWN进程还没有全部完成的后续动作得到了保障。
下面我们要提到检查点的作用,ckpt的触发,有以下几种情况:
1.当发生日志组切换的时候
2.当满足log_checkpoint_timeout、log_checkpoint_interval、fast_start_io_target、fast_start_mttr_target参数设置的时候
3.当运行alter system switchlogfile的时候
4.当运行alter systemckeckpoint的时候
5.当运行altertablespacetbs_namebegin backup[end backup]的时候
6.当运行altertablespace[datafile] offline的时候
7.系统正常关闭时
只有在4.7两种情况下发生完全检查点。发生完全检查点时,首先系统记录检查点对应的Checkpoint SCN,并记录下该时刻修改的DB BUFFER对应的日志文件的最新的重做字节地址(Redo Byte Address (RBA)),然后DBWN进程将这个重做字节地址(RBA)之前已发生的DB BUFFER中的脏缓冲写入数据文件(之所以要以重做字节地址(RBA)为标志是因为在检查点发生到检查点完成之间的时间内,系统还在一直不断的产生修改,这些修改所产生的DB BUFFER脏缓冲,以及日志条目将不会影响这次检查点最后确认的一致性结果,也就是最后确认这个Checkpoint SCN之前的系统是一致的)。
最后把Checkpoint SCN和RBA更新至控制文件,Checkpoint SCN更新至每个数据文件头部,表明当前数据库是一致的。日志切换并不导致一个完全检点的发生,比如有三个日志文件组,当发生日志切换时发生检查点,而发生日志切换一般是因为当前的LGWR正在写重做日志,也就是LGWR当刚写满2号日志就立即触发检查点,于是系统开始核对3号日志中记录的REDO项目所对应的数据是否已经从DB BUFFER中写入数据文件(不管事务是否已提交),如果没有写入,检查点就触发DBWN进程将这些缓冲块写入数据文件,显然LGWR因此而发生等待,除此以外,检查点还让DBWN进程将在2号日志中对应修改的DB BUFFER块写入数据文件,然后继续LGWR进程,直到LGWR进程将LGWR触发之前存在于REDO LOG BUFFER中的所有缓冲(包含未提交的重做信息)写入重做日志文件,检查点再更新数据文件,控制文件头部SCN。其实LGWR等待的并不是CKPT的完成,而是等待CKPT触发的DBWN进程的完成。
可以想像断电时可能既有未COMMIT的事务,也可能同时存在已COMMIT但DBWN未完成的情况,如果断电时有一个已COMMIT但DBWN动作没有完成的情况存在,因为已经COMMIT,COMMIT会触发LGWR进程,所以不管DBWN动作是否已完成,该语句将要影响的行及其产生的结果一定已经记录在重做日志文件中了,则实例重启后,SMON进程从控制文件中记录的上一次重做字节地址(RBA)开始,按照重做日志文件中的条目对数据文件和回滚段重新做一遍即前滚,注意这些条目的操作在断电之前有的已经被DBWN写入了数据文件,有的还没有来得及写,不管有没有写进数据文件,前滚时都会再重新写一次(9I之前是这样的),9I之后,由于也在日志中记录了DBWN改写的块信息,系统会过滤掉已写入的条目而只重做那些未写入的条目。对于一个未提交事务,分几种情况来描述:
1)LGWR与DBWN一致的情况即一个语句执行完成后很长时间也没有COMMIT,这种情况一般不存在DBWN来不及完成的情况。只是没有Oracle COMMIT而已。那么SMON将在前滚完成后,利用回滚段重构出具有最小SCN的前映像,并把它的值写回原位。
2)事务执行中断电,即可能存在LGWR与DBWN不同步的情况(因为DBWN之前会触发LGWR,所以DBWN对数据文件的修改一定会被先记录在重做日志文件中。因此只可能存在已写入重做日志而未来得及写入数据文件的情况存在。而不可能存在已写入数据文件却没有写入日志文件的情况。),这种情况下SMON也会先前滚一点(即把数据文件与相应的日志文件先同步再回滚,之所以说前滚一点,是指仅LGWR与DBWN之间进度的差距,而不是把这条语句进行到底再回滚,因为日志文件中记录的是执行语句操作的一个个块的修改信息,而不只是记录一条执行语句的字面内容),然后利用回滚段重构出具有最小SCN的前映像,并把它的值写回原位。由此可见,实例失败后用于恢复的时间由两个检查点之间的间隔大小来决定,我们可以通个四个参数设置检查点执行的频率,LOG_CHECKPOINT_IMTERVAL决定了两个检查点之间写入重做日志文件的系统物理块的大小,LOG_CHECKPOINT_TIMEOUT决定了两个检查点之间的时间长度,FAST_START_IO_TARGET决定了用于恢复时需要处理的块的大小,FAST_START_MTTR_TARGET直接决定了用于恢复的时间的长短。
检查点的作用就是不断的确认LGWR与DBWN之间的同步情况,以便实例失败后从上一个检查点开始恢复,问题是两个检查点之间LGWR与DBWN大部分的操作是同步的,只是一小部分没有同步,这种传统的检查点使实例恢复做了比较多的无用功,因此,ORACLE引入了增量检查点,增量检查点会在上一次传统检查点发生后到下一次传统检查点发生之前,不断的更新记录在控制文件中重做字节地址(RBA)(CKPT进程每三秒更新一次,见下面DBWN讲述),这样实例失败后将直接从控制文件中记录的最后更新的重做字节地址(RBA)开始进行前滚和回滚,这就省略掉了恢复时大部份的重做日志的重做(即使在9I以后的版本里也省略掉了大部分的过滤重做日志条目的时间)。(对以上描述做一个简单的比喻:比如一个贸易公司下设经营部、货运部、监督部,经营部负责贸易合同的签订与记录,货运部负责按合同号的顺序把货物送达,监督部负责定期检查确认经营部签订的合同与货运部货物送达情况之间的同步情况,监督部每月检查一次,每次检查时,先确认当时正在装车的货物的合同号,并要求货运部把在这个合同号之前的所有还存在临时仓库中的未送货物全部送达。等货运部完成监督部下达的任务后,监督部在检查本上记录下本次开始检查时那票正在装车的货物的合同号,本次检查完成。如果这个公司发生了一次人事大换血,公司重新开业后,监督部就会从检查本上记录的合同号开始,检查在这之后所有发生的合同及货物送达情况,要求货运部把所有客户确认的但还未送达的货物送达。以上介绍Oracle COMMIT。
commit 流程的更多相关文章
- React源码 commit阶段详解
转: React源码 commit阶段详解 点击进入React源码调试仓库. 当render阶段完成后,意味着在内存中构建的workInProgress树所有更新工作已经完成,这包括树中fiber节点 ...
- 【分布式】Zookeeper请求处理
一.前言 在前面学习了Zookeeper中服务器的三种角色及其之间的通信,接着学习对于客户端的一次请求,Zookeeper是如何进行处理的. 二.请求处理 2.1 会话创建请求 Zookeeper服务 ...
- MYSQL复制
今天我们聊聊复制,复制对于mysql的重要性不言而喻,mysql集群的负载均衡,读写分离和高可用都是基于复制实现.下文主要从4个方面展开,mysql的异步复制,半同步复制和并行复制,最后会简单聊下第三 ...
- Galera集群server.cnf参数调整--前言
文档安排: 前言部分会简述下galera集群,正文中会针对我们线上的环境,在不断业务的情况下,进行参数调整的话,有些参数不能够进行配置,会以#***的形式写入配置文件中,文档也会进行进一步说明. 如果 ...
- mysql metadata lock(三)
前言 MDL锁主要用来保护Mysql内部对象的元数据,通过MDL机制保证DDL与DML以及SELECT查询操作的并发.MySQL Meta Lock(一)和MySQL Meta Lock(二)已经讲了 ...
- MySQL锁机制总结(二)
前言: Mysql是一个支持插件式存储引擎的数据库系统,本文讨论的锁机制也主要包含两部分SERVER层的锁和存储引擎的锁,存储引擎是指innodb,其它存储引暂不讨论. 1. 数据库中锁相关的基本概念 ...
- mysql源码解读之事务提交过程(一)
mysql是一种关系型数据库,关系型数据库一个重要的特性就是支持事务,这是区别于no-sql产品的一个核心特性.当然了,no-sql产品支持键值查询,不能支持sql语句,这也是一个区别.今天主要讨论下 ...
- ubifs核心功能 -- 垃圾回收
可回收空间的分类 垃圾回收的目的是再利用(回收后的空间大小能写入有效的node),如果再利用的价值越低,其回收的必要性越低.为了进行有效的垃圾回收,UBIFS对可回收空间做了2个层次的水线划分: 死空 ...
- ubifs性能优化分析
本文通过分析ubifs的mount.read.write和commit流程,挖掘ubifs背后的设计决策和性能优化手段,并结合自身产品的特点,给出一些读写性能改进方案. 1. ubifs ...
随机推荐
- python中的update
update()批量写入批量更新字典,举个例子: 1 a = { 2 "name":"dlrb", 3 "age":25, 4 " ...
- CentOS 7 救援模式启用网卡及重新获取IP地址
重新自动获取IP地址命令: dhclient 启用网卡命令 ifconfig ens33 up https://blog.csdn.net/hongmin118/article/details/782 ...
- FLEX中一组基于button的组件
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...
- <记录> Ubuntu16.04 安装Redis以及phpredis扩展
Linux下安装Redis 1.获取redis资源 wget http://download.redis.io/releases/redis-4.0.8.tar.gz 2.解压 tar xzvf re ...
- Shell 编程 (变量和条件测试)
变量: 1 . 变量声明 直接使用变量 + 赋值 #!/bin/bash NAME='HELLO WORD' echo $NAME 使用 declare 关键字声明 declare(选项)(参数) + ...
- HTTP 错误 403.6 - Forbidden 解决方案
MSDN 的解决方案 原因 1 Ip 安全的 XML 元素的allowUnlisted属性的值为 false.此外,客户端计算机的 IP 地址不在ip 安全XML 元素之下 IP 地址的列表中.IIS ...
- js弹出div层,弹出层页面底部出现UL出现一条线问题
整个弹出div层,列表满一页时:底部会出现一条横线 原因:ul固定写在页面中了 解决方法: 将ul代码与li列表一样写在js中,如下 var newhtml = '<ul class=" ...
- java 使用jsoup处理html字符
依赖的jar <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artif ...
- centos7,进程最大打开文件数 too many open files错误
遇到一问题,tomcat最近发生几次异常,查看日志,发现一直报 too many open files,熟悉的同学都知道这是用户打开文件数过多导致的, 再用命令ls /proc/20861/fd/ | ...
- zookeeper和dubbo的关系
Dubbo建议使用Zookeeper作为服务的注册中心. 1. Zookeeper的作用: zookeeper用来注册服务和进行负载均衡,哪一个服务由哪一个机器来提供必需让调用者知 ...