oracle_回滚

为了保证数据库中多个用户间的读一致性和能够回退事务。
一、在一个简单的更新语句中,对于回滚段的操作存在多处,在事务开始时,首

先需要在回滚表空间获得一个事务槽,分配空间,然后创建前镜像,此后事务的

修改才能进行,oracle必须以此来保证事务是可以回滚的。如果用户提交了事务

,oracle会在日志文件记录提交,并且写出日志,同时会在回滚段中把事务标记

为已提交;如果用户回滚事务,则oracle需要从回滚段中把前镜像数据读取出来

修改数据缓冲区,完成回滚,这个过程本身也要产生redo,所以回退这个操作是

很昂贵的。
二、回滚段存储的内容
     1、对于insert
操作,回滚段只需要记录插入记录的rowid,如果回退,只

需要将该记录根据rowid删除即可。
     2、对于update操作:回滚段只需要记录被更新字段的旧值即可,回退时通

过旧值覆盖新值即可完成回退。
     3、对于delete操作,oracle则必须记录正行的数据,在回退时,oracle通

过一个反向操作恢复删除的数据。
三、并发控制和一致性读
     1、一方面oracle通过锁定机制实现数据库的并发控制;一方面通过多版本

模型来进行并发数据访问。通过多版本架构,oracle实现了读取和写入的分离,

使得写入不阻塞读取,读取不阻塞修改。这是oracle数据库区别于其他数据库的

一个重要特征。oracle一方面不允许其他用户读取未提交数据,一方面要保证用

户读取数据要来自同一时间点。


假设员工scott的薪水为3000那么:
   1)在t1时间,在session1查询可以得到这个结果
   2)在t2时间session2进行更新,将scott的薪水增加3000,并为提交
   3)在t3时间session1再次查询,注意此时,oracle不会允许其他用户看到未提交数据,所以此时,oracle需要通过回滚段记录的前镜像进行一致读,将3000恢复出来供给用户,这是一致性读的作用。
   4)在t4时间,session2提交更改,此时数据修改被永久化;
   5)在t5时间,其他用户再次查询,将会看到变化后的数据,也就是4000.
      oracle内部使用scn作为时钟,在这里查询结果集就是根据scn来进行判断的,每个数据块头部都会记录一个提交scn,当数据更改提交后,提交scn同时被修改,这个scn在查询时可以用来进行一致性读判断。
四、在自动undo管理表空间,oracle随之引入了几个新的初始化参数
    undo_management:用来定义数据块使用的回滚段是否使用自动管理模式。该参数有两个选项,auto表示自动管理,manual表示手工管理。
    undo_tablespace:用来定义在自动管理模式下,当前实例使用哪个undo表空间。
    undo_retention:表示在自动管理模式下,当回滚段变得非激活之后,回滚段中的数据在被覆盖前保留的时间,该参数单位是秒。
五、回滚机制的深入研究
    1、获取事务信息:
       v$transaction动态视图
         xidusn:回滚段号
         xidslot:事务槽
         xidsqn:事务的序列号
         ubafil:undo
block address
filenum
         ubablk:UBA
block
number
         ubarec:UBA
record
number
       v$rollstat动态视图
         usn:回滚段标识
         rssize:回滚段默认大小
         xacts:活动事务数
         writes:回滚段写入数
         shrinks:回滚段收缩次数
         extends:回滚段扩展次数
         gets:获取回滚段头次数
         waits:回滚段头等待次数
     2、转储undo段
         在undo段头的转储文件中,dba指向的就是包含这个事务的前镜像的数据块地址。前十位代表文件号,后22位代表block号。转储文件中的irb:指的是回滚段中记录的最近未提交变更开始之处,如果回滚,这是起始的搜索点。rci:该参数代表的是undo
chain(同一事务中的多次修改,根据chain连接关联)的下一个偏移量。在x$BH中class字段中4表示的是段头,1表示的是数据块,state为3的就是一致读构造的前镜像。
select
b.segment_name ,a.file#,a.dbarfil,a.dbablk,a.class,a.state
from
x$bh a,dba_extents b
where
b.relative_fno=a.dbarfil
and
b.block_id<=a.dbablk
and
b.block_id+b.blocks>a.dbablk
and
b.owner=‘SCOTT‘
and
b.segment_name=‘EMP‘
      3、转储数据块信息
         ITL事务槽指interested
transaction
list,事务必须获得一个ITL事务槽才能够进行数据修改ITL内容包括:
           xid:事务的id
           uba:undo块的地址
           lck:lock
status
        xid=undo.segment.number+transaction.table.slot.number+wrap

事务的内部流程
        1)首先当一个事务开始时,需要在回滚段事务表上分配一个事务槽
        2)在数据块头部获取一个ITL事务槽,该事务槽指向回滚段头的事务槽
        3)在修改数据之前,需要记录前镜像信息,这个信息以undo
record的形式存储在回滚段中,回滚段头事务槽指向该记录。
        4)锁定修改行,修改行锁定位指向ITL事务槽。
        5)数据修改可以进行。
4、块清除(block
cleanouts)
         在事务需要修改数据时,必须分配ITL事务槽,必须锁定该行,必须分

配回滚段事务槽和回滚空间记录前镜像。当事务提交时,oracle需要将回滚段上

的事务表信息标记为非活动,以便空间可以重用;那么还有ITL事务信息和锁定信

息需要清除,以记录提交。由于oracle在数据块上存储了ITL和锁定等事务信息,

所以oracle必须在事务提交之后清除这些事务数据,这就是块清除。块清除主要

清除的数据有行级锁、ITL信息(包括提交标志、SCN等)。如果提交时修改过的

数据块仍然在buffer
cache之中,那么oracle可以清除ITL信息,这叫做快速块清

除,如果事务提交时修改过的数据块已经被写回到数据文件上,oracle会等到下

次访问该block时再来清除ITL锁定信息,这就是延迟块清除。
      5、产生ora-01555错误的原因
        1)由于回滚段是循环使用的,当事务提交以后,该事务占用的回滚事务表被标记为非活动,回滚段空间可以被覆盖重用。那么当一个查询需要使用被覆盖的回滚段构造前镜像实现一致读,此时就会出现oracle著名的ora-01555错误
        2)因为延迟块清除。当一个查询触发延迟快清除时,oracle需要去查询回滚段获得该事务的提交scn,如果事务的前镜像信息已经被覆盖,并且查询scn也小于回滚段中记录的最小scn,那么oracle将无法判断查询scn和事务提交scn的大小,此时就会出现延迟块清除导致的ora-01555错误。
        3)使用sqlldr直接加载数据时。
     alter
tablespace tablespace_name retention
guarantee;
      oracle提供一个内部事件(10203事件)可以用来跟踪数据库的块清除操作,10203事件可以通过以下命令设置,设置后需要重新启动数据库该参数才能生效
      alter
system set event="10203 trace name context forever"
scope=spfile;
     
        alter
database datafile ‘.....‘ offline
drop;
六、回滚段的空间过大
    1)通过查询试图v$dba_data_file和v$dba_temp_files确定临时表空间和undo表空间的大小
    2)新建一个undo表空间
        create
undo tablespace
tablespace_name;
    3)切换undo表空间
        alter
system set undo_tablespace=undotbs2
scope=both;
    4)等待原表空间所有undo
segment
offline;
    5)删除原undo表空间
         drop
tablespace undotbs1 including
contents;
七、特殊情况的恢复
    在很多情况下,特别是在使用隐含参数强制打开数据库之后,可能会在ora-006004194错误,在alert文件中,记录主要错误日志,出现此种错误时,最好的办法是通过备份进行恢复,如果没有备份,那么可以通过特殊的初始化参数进行强制启动,
     1)从当前的日志文件中找到对应的AUM(auto
undo
management)下的回滚段名称。
     2)修改init<sid>.ora参数文件,使用oracle隐含参数_corrupted_rollback_segments将回滚段标记为损坏,oracle会跳过对于这些回滚段的相关操作,强制启动数据库。
     3)使用init<sid>.ora参数文件启动数据库
        startup
pfile=initconner.ora
     4)重新创建新的undo表空间,删除出现问题的表空间,修改参数文件,由参数文件生成新的spfile,重新启动数据库。
        create
undo tablespace undotbs1 datafile ‘.......‘ size
10m;
        alter
system set undo_tablespace=undotbs1
scope=both;
        drop
tablespace
undotbs2;
        修改参数文件,变更undo表空间,并取消_corrupted_rollback_segments设置。
        有参数文件创建spfile;
         打开数据库即可;

oracle_回滚,布布扣,bubuko.com

时间: 2024-12-15 06:54:47

oracle_回滚的相关文章

spring事务没回滚

最近遇见一个问题,用spring管理实务,在service层处理数据,保存数据时出现异常,但没有回滚,检查了一下,发现是因为我用try catch将异常进行捕获了,没有抛出导致的:默认spring事务只在发生未被捕获的 runtimeexcetpion时才回滚. 处理发法一:捕获异常后,新生成runtimeexcetpion: try { userDao.save(user); userDao.update(user); } catch (Exception e) { logger.info("

回滚的意义---JDBC事务回滚探究

JDBC手动事务提交回滚的常见写法一直是rollback写在commit的catch之后: try{ conn.setAutoCommit(false); ps.executeUpdate(); ps.executeUpdate(); conn.commit(); }catch(Exception e){ conn.rollback(); } 但是,这种回滚是没有意义的: 一旦commit前出错, 就不提交了, 回滚无用 一旦commit了, 说明没错, 不用回滚 找到一篇和我观点相同的文章:

Spring中@Transactional事务回滚实例及源码

一.使用场景举例 在了解@Transactional怎么用之前我们必须要先知道@Transactional有什么用.下面举个栗子:比如一个部门里面有很多成员,这两者分别保存在部门表和成员表里面,在删除某个部门的时候,假设我们默认删除对应的成员.但是在执行的时候可能会出现这种情况,我们先删除部门,再删除成员,但是部门删除成功了,删除成员的时候出异常了.这时候我们希望如果成员删除失败了,之前删除的部门也取消删除.这种场景就可以使用@Transactional事物回滚. 二.checked异常和unc

springmvc事务回滚失效

转载:http://blog.csdn.net/z69183787/article/details/37819831 前文提到,最新换了框架,新项目用SpringMVC + Spring JdbcTemplate.搭框架时,发现了一个事务无法正常回滚的问题,记录如下: 首先展示问题: Spring applicationContext.xml配置: [html] view plaincopy <bean id="dataSource" class="org.spring

上线代码、回滚代码

上线脚本 #!/bin/bash FWDIR="$(cd `dirname "${BASH_SOURCE-$0}"`; pwd)" bin=`dirname "$0"` bin=`cd "$bin"; pwd` now=`date "+%Y%m%d_%H%M%S"` tag_release=di.release.${now} [email protected]:bdp-server/bdp-di.git e

web代码发布脚本以及回滚3.0

由于web服务器上的代码更新速度非常快,所以备份回滚变的非常重要,在源服务器在代码更新之前要做好备份 #!/bin/bash TODAY=`date +'%Y%m%d%H%M%S'` BACKUP_DIR=/home/path_to_file/publish/FILENAMEback FILE_DIR=/PATH/TO/FILE find $FILE_DIR/ -type f > /home/publish_file.list sed -i 's/\/PATH\/TO\/FILE\>//g' 

Spring 实现部分事务回滚

例如有业务需求,在catch异常后,catch块内把异常的信息存入到数据库,而catch外的数据全部回滚 try { ....... aaaService.save(); }catch(RuntimeException e) { bbbService.save(e.getMessage()); throw new RuntimeException(e.getMessage()); } 确保aaaService.save()的数据回滚,而 bbbService的save不回滚. 只能在bbbSer

关于oracle实例恢复的前滚和回滚的理解

关于oracle实例恢复的一些理解,一直都有误区,今天通过查看相关资料和与同学探讨,发觉了自己的错误,探讨结果如下: 实例恢复:当数据库非正常关闭的时候(断电或者shu  abort等等非一致性关闭),当你从新启动数据库的时候,数据库相关进程自动进行实例恢复,无须人工干预. 什么时候需要实例恢复 在shutdown normal or shutdown immediate下,也就是所谓的clean shutdown,checkpoint也会自动触发,并且把SCN纪录写回. 当发生checkpoi

spring 事务控制 设置手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

1 //假设这是一个service类的片段 2 3 try{ 4 //出现异常 5 } catch (Exception e) { 6 e.printStackTrace(); 7 //设置手动回滚 8 TransactionAspectSupport.currentTransactionStatus() 9 .setRollbackOnly(); 10 } 11 //此时return语句能够执行 12 return xxx; 如上: 当我们需要在事务控制的service层类中使用try cat