ITPub博客

首页 > 数据库 > Oracle > 深入浅出-redo和undo记载01

深入浅出-redo和undo记载01

原创 Oracle 作者:dotaddjj 时间:2011-12-19 20:47:04 0 删除 编辑

Redo和undo可以说是oracle实例回滚和事务一致性的重要依据,好在自己对于oracle的这两个理解比shared pool理解透彻,结合eygle的深入浅出这两章再次回味一下redo和undo的特性!

Redo用于记录数据库的改变,redo特性有三个组件:redo log buffer重做日志缓存 lgwr后台进程用于把redo log buffer写入disk,redo log file(归档模式下arcn用于把写满的redo log file归档到归档日志下),redo中记录数据库的改变的信息以重做条目redo entries形式存储(又称redo records),redo entrie包含数据库改变的信息,其中有insert update的dml和alter grant的ddl等。

Redo entries内容被oracle数据库进程从用户内存空间复制到sga中的redo log buffer之中,redo entries在sga中占用连续顺序空间,后台进程lgwr不断把redo log buffer写入到disk上。

其实经常说数据库性能,sql的性能,更多的是I/O消耗,cpu解析和network,一个事务的结束后,oracle并不会把相应的dirty buffer直接写到disk上去,而是采取的redo的形式记录了这个事务的所有过程,而后在数据库实例异常关闭再次启动时,oracle会利用redo log file的重做条目前滚来恢复没有写入disk上的数据。Oracle引入redo机制,通过连续的 顺序的日志条目的写到redo log file中用于“推迟”dirty buffer的分散写入(dirty buffer写入会分散到各数据文件),当修改过数据达到一致数量后再次搞笑批量写入dirty buffer到disk提高性能。

在blog中记录了关于checkpoint,checkpoint检查点事件用于减少恢复时间,oracle会通知dbwr进程把checkpoint scn之前的dirty buffer写入disk,checkpoint完成后ckpt进程会相应地更新controlfile和dbf的文件头,记录检查点信息,实例崩溃后的恢复的过程也就是 low cache rba到 on disk rba,rba在数据文件也会记录。

Oracle利用redo顺序 快速将redo log buffer写出到redo log,除了顺序 快速写出还因为redo所记录的精简内容有关。

改变向量change vector

改变向量标识对数据库内某一个数据块所做的一次变更。包含了变更的数据块版本号,事务操作代码,变更从属数据块地址dba以及更新后的数据

重做记录redo record

重做记录通常由一组改变向量组成,是一个改变向量集合,构成数据库变更的最小恢复单位。

update test01 set id=45 where id=78

(1) 查找buffer cache中是否有相应数据块,有则直接读取,没有则从disk上读取到buffer cache中再读取(可能还需要从回滚段中获取回滚段而构造一致性读取cr块)

(2) 从回滚表空间的相应回滚段事务表上分配事务槽,需要记录redo

(3) 从回滚段读入或者在buffer cache中创建前镜像,产生redo

(4) 修改相应数据块,update数据变更,记录redo

(5) 用户commit,修改相应回滚段事务表为非激活inactive,在redo log buffer记录提交信息

同样可以dump log日志来查看事务的过程中redo所记录的具体信息

alter system dump logfile 'E:ORACLEPRODUCT10.2.0oradatatestredo03.log'

那么如何查找sql语句执行过程中产生了的redo,利用sql*plus的autotrace或者利用v$mystat等统计视图

SQL> set autotrace trace statistic;

SQL> insert into test01 select * from test01 where rownum<4;

已创建3行。

统计信息

----------------------------------------------------------

0 recursive calls

5 db block gets

4 consistent gets

0 physical reads

600 redo size

667 bytes sent via SQL*Net to client

590 bytes received via SQL*Net from client

4 SQL*Net roundtrips to/from client

1 sorts (memory)

0 sorts (disk)

3 rows processed

利用下列sql语句在sql语句执行前后取差值即为此session产生的redo

select name, value

from v$mystat a, v$statname b

where a.statistic# = b.statistic#

and b.name = 'redo size'

同样可以利用v$archived_log计算平均每天产生的归档redo log大小

Select trunc(completion_time),sum(blocks*block_size)/1024/1024 mb from v$archived_log group by trunc(completion_time)

TRUNC(COMPLETION_TIME) MB

---------------------- ----------

2011/10/4 20.4467773

2011/10/15 43.2182617

2011/11/16 18.5463867

2011/9/28 15.8808593

2011/10/3 4.26464843

2011/10/13 839.439941

2011/10/24 32.9848632

2011/10/30 24.1342773

2011/11/4 20.5214843

2011/11/8 11.9272460

[@more@]

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

下一篇: 丢失redo的solution
请登录后发表评论 登录
全部评论
  • 博文量
    220
  • 访问量
    1662981