oracle中数据是怎样前滚和回滚的
保持数据一致性和完整性,是每一款成功商业数据库软件都必须要做到的基本要求。从故障中恢复,保证ACID原则,保证事务完整性,一直是Oracle数据库核心功能组成部分。本篇主要介绍Oracle实例意外终止(断电或者强制关闭)之后,重新启动时发生的恢复过程,也可以称作“前滚和回滚”。
专注于为中小企业提供成都网站制作、做网站、外贸营销网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业袁州免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了1000+企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
基础知识说明
为了更明确的说明问题,笔者首先介绍一下本文涉及到的一些重要知识。
数据库实例失败
我们经常说的数据库服务器failure是有多层含义的。Oracle数据库是一个由多进程组件共同构成的结构体系。最重要的部分包括监听器、Oracle数据库实例两个部分,当然还包括各类文件,更广义的还有硬件和操作系统OS。不同部分的Failure现象和处理方法都有所不同。本文所阐述的过程是Oracle实例失败后的自动恢复过程。
在实例失败的时候,往往是突然性的终止。此时Oracle数据库可能在进行一系列完成或者未完成的事务。实例失败恢复,就是要将这些状态进行还原,恢复到数据完整性的状态。
写日志(RedoLog)在先机制
Oracle数据库是采用“日志在先”机制的。当我们对数据库数据进行修改时,并不是立即将修改写入到文件中,而是写入到共享内存SGA空间中的BufferCache里。同时,将修改的日志不断的写入到SGA中另一块Log Buffer缓存中。有一个后台进程LGWR不断的将LogBuffer缓存中的日志内容写入到online redo log文件中。
写入LogBuffer缓存和LGWR写入文件的过程是异步进行的。那么LGWR会在哪些情况下将日志缓冲区(全部内容)转储到日志文件呢?如下:--参考OCA认证考试指南(1Z0-052,P40)ü 用户进行直接的commit操作;
ü RedoBuffer数据超过1/3;
ü DBWn启动,将BufferCache中的脏数据写入到文件中;ü 距离上次LGWR写入操作超过三秒(三秒超时,DBWn每三秒钟会对一些缓冲区清理一次,这个时候,刚好符合触发LGWR的第三点);而数据文件写入进程DBWn工作的触发点(此处注意:DBWn会将高速缓冲区的脏缓冲区,即脏数据块写入数据文件,而不是缓冲区里头的全部内容---参考OCA认证考试指南(1Z0-052,P38))。
因为考虑到磁盘I/O会降低性能,DBWn采用的是极懒算法执行写入。如果对于经常变脏的缓冲区,即这边缓冲区处于十分忙碌的状态,那么DBWn不会将缓冲区写入磁盘的。反而一段时间来,任何会话都未曾关注的一些缓冲区,DBWn会将其写入到磁盘。因此DBWn写脏缓冲区比较平缓和低频率。但如果出现检查点的情况例外:DBWn会将所有脏缓冲区全部写入磁盘。---参考OCA认证考试指南(1Z0-052,P38中,P39)。
ü 当BufferCache中没有任何可用缓冲区;ü 脏缓冲区过多;
ü 遇到三秒超时(DBWn每三秒钟会对一些缓冲区清理一次)ü 遇到检查点
综合DBWn和LGWR工作的特点,我们可以得到日志文件的几个特点:
首先,日志文件的写入是很频繁的。LGWR会不断将日志信息从LogBuffer中写入Online Redo Log;其次,在日志文件上,可以有三个类型的事务事件。
1、事务结束,已经被commit,之后打过checkpoint检查点。这种事务记录在LogFile上,但是变化信息已经被DBWn写入进数据文件;2、事务结束,已经被commit,之后没有打入checkpint检查点。这种情况下,LogFile已经写入了日志项目,数据文件可能包括脏数据,也可能没有写入脏数据;3、事务未结束,没有commit。这种时候,数据块DirtyBlock上面是有事务槽信息,表示未结束事务,是不会将数据写入到数据文件中。但是,日志LogBuffer可能将部分未提交的DML操作项目写入到Log File中;检查点Checkpoint
检查点Checkpoint是数据库一致性检查的一个标记。简单的说,就是在这个点上,Oracle保证各个文件(数据、控制、日志等)是一致的。检查点的作用就是在进行实例恢复的时候,告诉SMON进程,这个点之前的内容不需要进行恢复。
前滚和回滚介绍
“前滚和回滚”是Oracle数据库实例发生意外崩溃,重新启动的时候,由SMON进行的自动恢复过程。下面通过模拟实例和讲解介绍这个过程。
失败前场景说明
日志中记录过程如下:
1、事务A进行之后,结束commit。之后系统进行了一次checkpointA;2、Checkpoint之后,进行事务B,结束commit;3、进行事务C,C事务量较大,其中进行了一定量的RedoLog文件写入。之后系统断电;--按照LGWR的工作机制,C事务量比较大,所以应用程序将在几分之一秒内的时间里生成足以填充1/3秒的重做内容,因此这会触发LGWR将日志缓冲区的内容转储到日志文件,但始终得不到针对C事务的提交记录,这是需要回滚的。
4、还有种可能,事务B和D,事务D所用的缓冲区处于高速缓冲区不活跃的位置,而且事务B已提交,但其所用的缓冲区处于高速缓冲区活跃的位置。因此DBWn会将D事务缓冲区数据写入数据文件,而没将B事务的数据写入。此种情况需要回滚D事务,保留B事务。---参考OCP认证考试指南全册(P358下半部分内容).
1、系统启动过程,进入实例恢复阶段
当实例意外中断的时候,各类型文件,包括控制文件、数据文件和日志文件上,会存在不一致的问题。这种不一致主要体现在SCN值的差异上。
实例在启动的时候,经过三阶段(nomount、mount和open)。在open之前,会进行这种不一致现象的检查,如果出现不一致,要启动SMON进程的恢复流程。
SMON是Oracle实例的一个后台进程,主要负责进行系统监控恢复。进行恢复的依据主要是RedoLog记录。
2、前滚进程
SMON首先找到最后SCN记录的Redo LogFile。寻找最后一个打入的Checkpoint。
顺序找到CheckPointA之后,表示A之前的所有事务都是完全写入到数据文件中,不存在不一致性问题。恢复过程从CheckpointA开始,Oracle开始依据重做日志Redo Log的系列条目,进行推进。
首先遇到了事务B信息,由于事务B已经commit,所以事务B所有相关的Redo Log条目已经全都写入到Redo LogFile中。所以,按照日志继续条目推进,完全可以重演replay,并且应用apply事务B的全部过程。
这样,事务B全部实现,最终将通过DBWn完全写入到数据文件中。所以,实例失败之前提交commit的事务B,完全恢复。
进入事务C的范畴,由于一部分事务C的RedoLog条目已经进入Redo LogFile中(根据LGWR和DBWn的工作机制,事务C有可能将部分数据块写入日志文件和数据文件,但这时候C事务始终没提交,这是比较严重的讹误,所以需要回滚),所以在进行前滚的时候,一定会replay到这部分的内容。不过,这部分内容中不可能出现commit的标记。所以,前滚的结果一定是遇到实例突然中断的那个时点。此时replay的结果是,事务C没有提交。这样结束了前滚过程,进入回滚阶段。
3、回滚过程(与普通的回滚一样(当事务执行失败后自动回滚或者命令:ROLLBACK.)---参考OCP认证考试指南全册)对事务C(针对DML的update,当然其他同理),要进行回滚过程,释放所有相关资源。在前滚中,利用日志填充了的撤销块和表数据块的值,然后在回滚的时候,会将撤销块的值复制回表数据块中(因为此事务没提交记录),以此来进行SGA中BufferCache数据块恢复。
4、说说恢复过程的损耗
很多时候,由于我们事务规模较大,当出现实例崩溃的时候,重启所需要的时间很多。有一种经验说法是,事务有多长,前滚和回滚所消耗的时间有多长×2。而且,如果不能完成SMON恢复过程,数据库是不能算作正常的Open的。
SMON的恢复过程是Oracle强制进行的一个过程,即使恢复中发生断电或者其他中断失败事件。Oracle在下一次启动的时候,还是会继续这个过程,只有耐心等待。
通过检查一些内部视图(X$视图),可以观察到恢复进程和速度,但是丝毫不能影响到最终恢复的过程。
这个过程虽然可以保证数据一致性,但是也带来了系统不能启动,影响生产环境的问题。我们可以通过两个方式进行缓解:
首先,我们在设计开发系统时,要保证事务规模的可控性,不要让事务规模在技术层面上过大。避免一旦发生崩溃,大规模强制回滚的发生;其次,一旦出现了这个强制回滚,要注意对生产环境的影响。可以采用备库standby进行顶替,让主库安静的慢慢恢复;
oracle 如何通过事务回滚。
如果你的数据是相互不影响,就是没有业务关联的话,就回滚一条
如果相互有关系的话
那估计就回滚所有了
个人意见
希望对你有帮助
Oracle8i中回滚段使用和ORA-1555
回滚段中保存的回滚数据有 个作用 一致读和回滚 回滚段是由连续block组成的区间extent组成 回滚段有顺序的循环的使用这些区间 当当前区间写满的时候 oracle移向下一个区间 如一个回滚段有 个区间A B C D;当区间C被写满的时候 oracle将写区间D 而当D写满的时候 oracle将尝试重新写区间A 这样循环的有顺序的使用区间
事务必须将回滚信息写到回滚段中 事务的当前新产生的回滚信息写在该回滚段的位置叫做回滚段的head 而在该回滚段上最早发生的尚未提交的事务最早产生的回滚信息所在位置叫做回滚段的tail 当前区间写满的时候 oracle移动head到下一个区间
i时每个事务只能使用一个回滚段 Oracle会根据回滚段workload 平均将事务分配给各个回滚段 在回滚段使用上的一些规则
一个事务只能使用一个回滚段
多个事务可以共用一个区间 但Active的事务不能共用一个block
回滚段的current extent写满的时候 回滚段的Head不能够移动到回滚段tail所在的区间
区间总是被有顺序的循环的时候 当head移动的时候 不会跳跃区间 只能移动到下一个区间
如果head不能够使用下一个区间(如tail在下一个区间) 将会分配一个新的区间extent 并将新区间extent插入到这个循环使用的extent圈中 这叫做回滚段的扩展
ORA snapshot too old主要是在一致读和延迟块清除delay block cleanout的时候产生
[参考]一致读的步骤
Read the Data Block
Read the Row Header
Check the Lock Byte to determine whether theres an ITL entry
Read the ITL entry to determine the Transaction ID (Xid)
Read the Transaction Table using the Transaction ID If the transaction has been mitted and has a System Commit Number less than the querys System Change Number update the status of the block (block cleanout) and start over at step
第 步细分
IF 在Transaction Table 中根据Transaction ID 找到transaction
IF transaction 已经mit
IF query scnmit scn
则接受该块 进行clean out 返回
ELSEIF query scn
则进行一致性读 从第 步向后执行
ELSEIF transaction 没有mit
也进行一致性读 从第 步向后执行
ELSEIF 在Transaction Table 中没有找到transaction(undo header中的transaction slot被覆盖了 也说明事务已经提交 因为只有提交后所在的transaction slot才能被覆盖 这样query scn则去比较control scn 在该回滚段上control scn以前的transaction都已经被提交 也就是事务表中所能找到的最小的mit scn了)
IF query scn
则无法知道query scn和mit scn得大小关系 出现ORA 错误
IF query scncontrol scn
则query scn肯定mit scn
则接受该块 进行clean out 并将block 中ITL标记上 U 表示 upper bound mit 并返回
Read the last undo block (Uba)
Compare the block transaction ID with the transaction table transaction ID If the Transaction ID in the undo block doesnt equal the Transaction ID from the Transaction Table then issue ORA Snapshot Too Old 表示回滚段中回滚信息被覆盖 无法为一致读提供必需的before image
If the Transaction IDs are identical make a copy of the data block in memory Starting with the head undo entry apply the changes to the copied data block
If the tail undo entry (the actual first undo entry in the chain or the last in the chain going backwards!) indicates another data block address read the indicated undo block into memory and repeat steps and until the undo entries dont contain a value for the data block address
When theres no previous data block address the transaction has been pletely undone
If the undo entry contains:
a a pointer to a previous transaction undo block address read the Transaction ID in the previous transaction undo block header and read the appropriate Transaction Table entry Return to step
b an ITL record restore the ITL record to the data block Return to step
出现 的时候 首先判断是哪个原因导致 可以设置event 如果因为transaction slot被覆盖导致 则增加回滚段数目 如果因为回滚信息被覆盖 则增加回滚大大小 错误比较复杂 通常需要考虑很多问题
event = trace name processstate forever level
lishixinzhi/Article/program/Oracle/201311/17091
oracle断网后事务无法回滚
1、表存储引擎不是InnoDB。
2、java调用数据库代码中,手动添加了tray....catch,造成未抛出异常。
3、spring回滚默认是RuntimeException异常,可指定回滚异常,@Transaction(RollbackFor=Exception.class)。
4、如果使用代理方式,应指定代理使用CGLib@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS)。
如何使用Oracle回滚段
Oracle缺省用的是专用服务器模式,也就是说一个用户连接进程对应一个服务器的进程.
记得某大医院刚启用的时候,我们曾经试过MTS.因为听说MTS在不增加内存和CPU的情况下连接更多的客户端,结果并不是我们预期的那样.
因为我们对MTS不了解,并不是它有问题,而是它不是用来在这种情况下做这件事的.
分享题目:oracle事务怎么回滚 oracle回滚是什么意思
网页链接:http://scgulin.cn/article/hgchoc.html