理解甲骨文重做与撤销

  

<强>重做——比;撤销,在外部
插入一条记录时,表跟撤销的信息都会放进重做中,在提交或之前,重做的信息会放进硬盘上。故障时,重做便可恢复那些已经提交了的数据。

  

<强>重做→每次操作都先记录到重做日志中,当出现实例故障(像断电),导致数据未能更新到数据文件,则数据库重启时须重做,重新把数据更新到数据文件
<强>撤销→记录更改前的一份拷贝,但你系统回滚时,把这份副本重新覆盖到原来的数据

  

<强>重做→记录所有操作,用于恢复(重做记录所有的数据库事务用于恢复)
<强>撤销→记录所有的前印象,用于回滚(撤销用于存储uncommited数据有限公司用于回滚)

  

<强>重做→已递交的事务,实例恢复时要写到数据文件去的
<强>撤销→未递交的事务。

  

<强>重做的原因是:每次提交时,将数据的修改立即写到联机重做中,但是并不一定同时将该数据的修改写到数据文件中。因为该数据已经提交,但是只存在联机日志文件中,所以在恢复时需要将数据从联机日志文件中找出来,重新应用一下,使已经更改数据在数据文件中也改过来!

  

<强>撤销的原因是:在甲骨文正常运行时,为了提高效率,假如用户还没有提交,但是空闲内存不多时,会由DBWR进程将脏块写入到数据文件中,以便腾出宝贵的内存供其它进程使用。这就是需要撤销的原因,因为还没有发出提交语句,但是甲骨文的DBWR进程已经将没有提交的数据写到数据文件中去了。

  

撤销也是也是丢失,可没能脏缓冲区有写回到磁盘里面去。
只有先重新申请成功了,才能保证撤销功能里面的东西都是正确的,然后才能回滚

  

做撤销的目的是使系统恢复到系统崩溃前(关机前)的状态,再进行重做是保证系统的一致性。
不做撤销,系统就不会知道之前的状态,重做就无从谈起

  

所以实例崩溃恢复的时候总是先滚,再回滚

  

撤销
回退段中的数据是以“回退条目”方式存储。
回退条目=块信息(在事务中发生改动的块的编号)+在事务提交前存储在块中的数据

  

在每一个回退段中oracle都为其维护一张“事务表“
在事务表中记录着与该回退段中所有回退条目相关的事务编号(事务SCN&回退条目)

  

重做
重做记录由一组“变更向量”组成。
每个变更变量中记录了事务对数据库中某个块所做的修改。
当用户提交一条提交语句时,LGWR进程会立刻将一条提交记录写入到重做日志文件中,然后再开始写入与该事务相关的重做信息。

  

#事务提交成功后,甲骨文将为该事备生成一个系统变更码(SCN)。事务的SCN将同时记录在它的提交记录和重做记录中。

  

<强>提交
提交事务前完成的工作:
·在SGA区的回退缓存中生成该事务的回退条目。在回退条目中保存有该事务所修改的数据的原始版本。
·在SGA区的重做日志缓存中生成该事务的重做记录。重做记录中记载了该事务对数据块所进行的修改,并且还记载了对回退段中的数据块所进行的修改。缓存中的重做记录有可能在事务提交之前就写入硬盘中。
·在SGA区的数据库缓丰中记录了事务对数据库所进行的修改。这些修改也有可能在事务提交之前就写入硬盘中。

  

提交事务时完成的工作:
·在为该事务指定的回退段中的内部事务表内记录下这个事务已经被提交,并且生成一个惟一的SCN记录在内部事务表中,用于惟一标识这个事务。
·LGWR后进进程将SGA区重做日志缓存中的重做记录写入联机重做日志文件。在写入重做日志的同时还将写入该事务的SCN。
·甲骨文服务进程释放事务所使用的所有记录锁与表锁。
·甲骨文通知用户事务提交完成。
·甲骨文将该事务标记为已完成。

  

<强>
回滚退事务完成的工作:
·甲骨文通过使用回退段中的回退条目,撤销事务中所有SQL语句对数据库所做的修改。
·甲骨文服务进程释放事务所使用的所有锁
·甲骨文通知事务回退成功。
·甲骨文将该事务标记为已完成

  

举个例子:
插入(id)值(1),(重做)
这条记录是需要回滚的。
回滚的语句是删除从一个id=1;(撤销)

  

试想想看。如果没有做插入(id)值(1),(重做)
那么删除从一个id=1;(撤销)这句话就没有意义了。

  

现在看下正确的恢复:
先插入(id)值(1),(重做)

理解甲骨文重做与撤销