oracle规定:保证重做记录先于对应的脏数据块写入持久层
内存层面:Oracle先写日志缓冲数据后写数据缓冲数据
物理层面:oracle先写redo log后写datafile
Redo中包含undo
DDL操作虽然无法产生rollback,但是仍会产生redo和undo
Redo:记录所有操作,因为先写redo后写datafie,所以实例恢复时需要把redo中信息读取出来再判断是否需要写入datafile中
redo的原因是:每次commit时,将数据的修改立即写到online redo中,但是并不一定同时将该数据的修改写到数据文件中。因为该数据已经提交,但是只存在联机日志文件中,所以在恢复时需要将数据从联机日志文件中找出来,重新应用一下(前滚),使已经更改数据在数据文件中也改过来!非commit时,因redo log先于datafile写入持久层,所以重启时需要先前滚redo log中修改的数据,如果这些数据没有commit再从undo中回滚回去。
实验验证:
一次性写入400M数据记录为10万条,但是不commit,发现很多8个在线日志都归档了,并且发现数据文件也增长了400M,删除其中一个归档日志后shutdown abort并且startup后,数据文件大小不变(不会减少400M),但是记录为0,说明前滚不会用到归档日志(理论解释:因为归档日志切换的时候会触发checkpoint再出发dbwr写,所以数据必须先写入datafile才会做日志归档操作),但是回滚数据就全部用到了,因为回滚数据中只要事务标记为未提交,就会用做回滚。
instance crash recovery 的时候总是先rollforward, 再rollback
实例恢复顺序:先redo,再undo(在redo范围之内的才undo)
例子:
两个块,值分别是A和1
A修改为B,并且commit提交了,说明写到了redo日志
1修改为2没有提交,写入到了undo,不一定写到了redo日志,事务槽状态一定是未提交
如果1修改为2写到了redo日志,则恢复是:
实例恢复的时候利用redo先前滚到a->b,1->2,再利用undo回滚2->1,结果两个块的值分别B和1
如果1修改为2没写入redo日志,则恢复是:
实例恢复的时候是利用redo先前滚到a->b,结果两个块的值分别B和1(虽然1->2有undo,但是undo不在redo的范围,故不用回滚)
多个日志组的好处
归档比较慢,切换比较快,比如ABC三组日志,A在归档,lgwr从A切换到了B,B也写满了需要切换到C,C也写满了需要切换到A,而A可能还没有归档完,导致数据库等待
Alter system switch logfile对单实例数据库或RAC中的当前实例执行日志切换;
Alter system archive log current对数据库中的所有实例执行日志切换。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30126024/viewspace-2109196/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/30126024/viewspace-2109196/