首页 > 数据库 > Oracle > 深入浅出-redo和undo记载01
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/ ,如需转载,请注明出处,否则将追究法律责任。