oracle体系结构梳理---redo和undo解析1

undo用来干什么的? undo表空间 

1.事物回滚:rollback   

2. 查询一致性 

3.flash back 

实例的恢复时用到的回滚 ---undo读的是redo文件中的undo部分

Redo:是基于安全考虑的,会记录数据库的所有变化,主要用来做恢复

insert操作

undo:记录rowid即可

redo:记录rowid+value

delete操作

undorowid+value

redo:rowid

update操作

undo:操作之前的rowid+value

redo:操作之后的rowid+value

20:00 会话1开始了一个长达30分钟的查询

20:05 会话2开始了一个update并且提交了,其中的undo信息保存900s那么在20:20时候可以被覆盖

20:22 会话3update了会话2的那一行,导致会话2中的undo信息被覆盖

此时会话1在查询到会话2update的那一行数据是由于要查的是20:00开始的那一刻的数据,但是其undo又被覆盖了,此时就会产生ora-01555错误:快照过旧

普通数据块上面要留一个undo地址,如果地址被覆盖或则更改,假设普通数据快上面的数据被更改,但是还未提交,那么在查询普通块时,

会根据普通数据块记录的undo数据块进行一致读,但是undo块被覆盖,其上没有指向redo文件的指针,所以一致读失败。


create table t(x varchar2(10),y varchar2(10));

insert into t(x,y) values(1,1);------insert 语句。生成的undo足以使insert消失,生成的redo信息足以使这个插入再次发生

update t set x=x+1 where x=1;

delete from t where x=2;

select  force_logging from v$database;-----YES

select log_mode from v$database;----archivelog

-----------------------------------------ITL----------------------------

create table testblock1( 

id number

name varchar(4

) ;

插入3条数据然后提交: 

 insert into testblock1 values(1,'a'); 

 insert into testblock1 values(2,'b'); 

insert into testblock1 values(3,'c'); 

 commit

select rowid,dbms_rowid.rowid_relative_fno(rowid) rel_fno,dbms_rowid.rowid_block_number(rowid)   blockno from testblock1; 

alter system dump datafile 4 block 142998

oradebug setmypid

oradebug tracefile_name

SELECT      d.VALUE

            || '/'

            || LOWER (RTRIM (i.INSTANCE, CHR (0)))

            || '_ora_'

             || p.spid

             || '.trc'

                AS "trace_file_name"

     FROM   (SELECT   p.spid

                FROM   v$mystat m, v$session s, v$process p

             WHERE   m.statistic# = 1 AND s.SID = m.SID AND p.addr = s.paddr) p,

            (SELECT   t.INSTANCE

              FROM   v$thread t, v$parameter v

            WHERE   v.NAME = 'thread'

                      AND (v.VALUE = 0 OR t.thread# = TO_NUMBER (v.VALUE))) i,

            (SELECT   VALUE

             FROM   v$parameter

            WHERE   NAME = 'user_dump_dest') d;

  -----Oracle什么情况下select会产生redo ?

1)快速块清除或者叫commit cleanout。事务提交的时候,oracle针对内存里的块 

1)把数据块ITL  ENTRY里flag的标记为U 

2)设置commit scn在Scn/Fsc列。有了两个标记就可以告诉全世界这个事务已经提交。

但ITL ENTRY 的Lck标志和每个数据行头的lb(锁定位信息)并不会清除。

Oracle 做commit cleanout并不会产生日志,这个你可能会感到比较奇怪,

修改了块,但是却没产生日志。其实这个产生日志的过程在后面的完整的块清除的时候才做。

也就是我们下一次读取到这个数据块的时候。

2)延迟块清除。事务提交的时候,事务修改的块已经不在内存里了,

这个时候,Oracle不会再从磁盘把块读取到内存里做块清除,

而是在下一次读取数据块的时候,做块清除的动作。这个块清除的动作会产生Redo。

需要注意直接路径读取由于绕过了buffer_cache,读取过程直接在进程的私有PGA里来完成,

这个过程也会在进程私有的内存里构造CR块,虽然这个过程里也会有延迟块清除发生,

但是不会产生Redo,而且不会把“脏”数据写会到磁盘。这意味着,如果这个表一直被直接路径读取,

将会有许多的浪费的延迟块清除发生。11G针对大表的全表扫描,11G前并行扫描都会产生直接路径的读取。

但是直接路径读取即使遇到了需要做延迟块清除的块也不会产生Redo。

oracle 11g release 2新增的特性为--延迟段创建

这个时候使用create table 不会分配任何存储空间,一个区段都不会分配。要延迟到insert发生时才会真正创建段,回滚是,段将持久存储。

回滚过程中重不涉及重做日志,只有恢复和归档的时候才会读取重做日志。重做日志不是用来读的,是用来写的。oracle不会再正常的处理中读取重做日志。

ARCH读文件时,LGWR能写到另一个不同的设备中,就不存在重做日志竞争。

commit时,重做日志缓存组区就会被刷新输出,commit之后数据库做的操作就是:

为事务生成一个SCN

LGWR将所有余下的缓存重做日志条目写入磁盘,并把SCN记录到在线重做日志文件中,这是真正的commit,事务条目会从v$transaction中删除掉

v$lock记录的而所有的锁都会被释放

如果事务修改的某些块还在缓冲区中,则会议一种快速的模式访问并‘清理’

块清除就是指清除存储在块首部的锁相关的信息。

ROLLBACK之前,数据库可能已经完成的工作有:

已经在SGA生成UNDO段和已修改的块还有对应前两项的redo日志。同事也已经取得了全部锁

select force_logging from v$database;

在nologging状态的数据库并不是不生成redo信息,还是会有少量的redo信息来保护我们的数据字典,在一个archivelog模式下开启nologging一定要及时备份。

建立一个段或则索引时使用nologging那么以后再重建这些对象的时候将不会再生成redo信息。

块清除在commit时候一般会执行,如果未完成。那么在select的时候就会出现少量的redo信息,这将可能导致块变脏(因为本身并没有被修改,不脏),也将导致下一个检查点时将大量的块写至磁盘。

在OLTP数据库中一般不用考虑块清除,因为事务一般都很小,在commit时都会完成相应的块清除。

但是当你在数据仓库中,如果加载时候要对数据执行大量的update,那就要把块清除作为一个考虑对象了,认识到这一点就应该在update之后主动接触这些数据

日志竞争问题:commit太过于频繁,或则由于redo所在的设备硬件问题。

临时表:修改临时表中是的数据是不会记入到redo信息的,不过,会生成undo,所以临时表还会为undo信息生成一部分redo信息所以:

select 临时表和普通表产生的redo信息一个很少,一个很多

update 临时表和普通表 后者是前者的一半

delete 几乎相同

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30018455/viewspace-1416050/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/30018455/viewspace-1416050/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值