问下:关于回滚段以及跟undo有啥关系,还有在oracle体系中什么时候用到回滚段呢等等?网上的东西挺乱的,都说的不一样,这里oracle板块的兄弟能交流下自己的看法不?谢谢了!

解决方案 »

  1.   

    UNDO表空间用于存放UNDO数据,当执行DML操作(INSERT,UPDATE和DELETE)时,oracle会将这些操作的旧数据写入到UNDO段,在oracle9i之前,管理UNDO数据时使用(Rollback Segment)完成的.从oracle9i开始,管理UNDO数据不仅可以使用回滚段,还可以使用UNDO表空间.因为规划和管理回滚段比较复杂,所有oracle database 10g已经完全丢弃用回滚段.并且使用UNDO表空间来管理UNDO数据.
    UNDO数据也称为回滚(ROLLBACK)数据,它用于确保数据的一致性.当执行DML操作时,事务操作前的数据被称为UNDO记录.UNDO段用于保存事务所修改数据的旧值,其中存储着被修改数据块的位置以及修改前数据,UNDO数据的作用.1,回退事务当执行DML操作修改数据时,UNDO数据被存放到UNDO段,而新数据则被存放到数据段中,如果事务操作存在问题,旧需要回退事务,以取消事务变化.假定用户A执行了语句UPDATE emp SET sal=1000 WHERE empno=7788后发现,应该修改雇员7963的工资,而不是雇员7788的工资,那么通过执行ROLLBACK语句可以取消事务变化.当执行ROLLBACK命令时,oracle会将UNDO段的UNDO数据800写回的数据段中.2,读一致性用户检索数据库数据时,oracle总是使用用户只能看到被提交过的数据(读取提交)或特定时间点的数据(SELECT语句时间点).这样可以确保数据的一致性.例如,当用户A执行语句UPDATE emp SET sal=1000 WHERE empno=7788时,UNDO记录会被存放到回滚段中,而新数据则会存放到EMP段中;假定此时该数据尚未提交,并且用户B执行SELECT sal FROM emp WHERE empno=7788,此时用户B将取得UNDO数据800,而该数据正是在UNDO记录中取得的.3,事务恢复事务恢复是例程恢复的一部分,它是由oracle server自动完成的.如果在数据库运行过程中出现例程失败(如断电,内存故障,后台进程故障等),那么当重启oracle server时,后台进程SMON会自动执行例程恢复,执行例程恢复时,oracl会重新做所有未应用的记录.回退未提交事务.4,倒叙查询(FlashBack Query)倒叙查询用于取得特定时间点的数据库数据,它是9i新增加的特性,假定当前时间为上午11:00,某用户在上午10:00执行UPDATE emp SET sal=3500 WHERE empno=7788语句,修改并提交了事务(雇员原工资为3000),为了取得10:00之前的雇员工资,用户可以使用倒叙查询特征.
    使用UNDO参数1,UNDO_MANAGEMENT该初始化参数用于指定UNDO数据的管理方式.如果要使用自动管理模式,必须设置该参数为AUTO,如果使用手工管理模式,必须设置该参数为MANUAL,使用自动管理模式时,oracle会使用undo表空间管理undo管理,使用手工管理模式时,oracle会使用回滚段管理undo数据,需要注意,使用自动管理模式时,如果没有配置初始化参数UNDO_TABLESPACE,oracle会自动选择第一个可用的UNDO表空间存放UNDO数据,如果没有可用的UNDO表空间,oracle会使用SYSTEM回滚段存放UNDO记录,并在ALTER文件中记载警告.2,UNDO_TABLESPACE该初始化参数用于指定例程所要使用的UNDO表空间,使用自动UNDO管理模式时,通过配置该参数可以指定例程所要使用的UNDO表空间.在RAC(Real Application Cluster)结构中,因为一个UNDO表空间不能由多个例程同时使用,所有必须为每个例程配置一个独立的UNDO表空间.3,UNDO_RETENTION该初始化参数用于控制UNDO数据的最大保留时间,其默认值为900秒,从9i开始,通过配置该初始化参数,可以指定undo数据的保留时间,从而确定倒叙查询特征(Flashback Query)可以查看到的最早时间点.
      

  2.   

    回滚段原理请参考:http://www.skyuu.com/Edu/class5/class1/200608/13556.html【感悟】:
    回滚段是实现了oracle数据库中的恢复复原功能,是存在于数据文件的一段区域,存储已经正在执行的dml操作的前数据的备份image。(1):当dml事务操作失败的话会rollback,这个时候就会去回滚段里取数据覆盖原来的数据块。(2):当意外断电或者系统down机的情况下,将正在执行的dml操作(SCN号不一致的,没有写到数据文件、日志文件、控制文件的)所涉及的回滚段数据信息(包括数据等)存放在online日志文件里面,在数据库重启的时候,利用回滚操作从online日志文件里面恢复到dml操作之前的数据。(3):回滚段分为系统回滚段以及私有回滚段,都在数据库实例启动的时候分配好的。
      

  3.   

    关于2楼说的第二点,一定要注意,执行update 语句和执行是select语句的是两个用户,也就是说两个session。
    如果A用户执行了update ,直接select,那此时读取的是数据段内容,而不是回滚段内容,是脏数据。这点一定要注意,我最早接触oracle的时候这块老弄错。
      

  4.   

    回滚段原理下:http://www.newasp.net/tech/data/941.html
      

  5.   


    关于脏数据的问题,有网友说道:脏数据写磁盘 
    checkpoint进程通知dbwr写脏数据到磁盘上,或者dbbuffer不够用的时候,也会触发dbwr写脏数据。 如何保持一致性: 
    ckpt会统一写scn,lgwr也会写scn。需要保持一致性的是controlfile记录的scn,datafile和datablock头的scn,还有日志文件里面的scn。另外会利用回滚段来保持读一致性。 比方说你做一条update语句,oracle会把这条语句读入到dbbuffer(其实是先查询dbbuffer里面是否存在,接着做一系列的词法语法分析,生成执行计划等等很多事情),读入后开始更新数据,首先会加锁,为了保持commit之前的读一致性,会将block读入回滚段。用户修改,修改时oracle回家数据依次写入redolog,databuffer,scn此时分别由dbwr和lgwr记录(对回滚段的更改也会记录redolog),dbwr首先是触发lgwr,将更改的数据信息记录redolog。然后就将脏数据写入磁盘。 
      
      

  6.   

    网友luocb1980说的:checkpoint发生时会启动dbwr进程,dbwr进程会把dirty数据写入到数据文件中,checkpoint后发生的修改的数据也应该是dirty,我觉得脏数据的定义应该是,脏数据肯定是存在于buffer中,不管是否commit,只要存在于buffer中的数据被修改就被标记为脏,直到dbwr进程写为止。我觉得可以接受这个观点,不知道这里的朋友怎么看的?
      

  7.   


    我在网上看到:dirty data 不一定只在buffer中啊,寫回datafile 的也可能是dirty data, 但是dirty data 寫回datafile 的時候,一定會觸發 LGWR去寫logfile ,所以 , dirty data不能以是否在buffer中來界定, 而且,其實,commit和DBWR,沒有什麼必然聯繫的呢!这个又怎么理解呢?
      

  8.   


    假如用户A在11:00执行UPDATE emp SET sal=1000 WHERE empno=7788,原来员工7788的薪资是800,到11:03再执行commit提交数据;
    用户B在11:02用select语句读取员工7788的薪资,此时用户读取到的数据是800而不是1000
    为什么呢?因为在11:02时用户A未提交数据,所以用户B读取出来的是脏数据;关于这一点,你们可以在sqlplus里面打开两个窗口,一边执行update语句,但未提交;而另一边窗口在提交前执行select语句,然后又试在提交后再执行一次select语句,结果是什么?你们就会明白了;
      

  9.   

    回滚段建立在undo表空间中回滚段管理:http://tech.it168.com/oldarticle/2007-06-06/200706061345015.shtml