20151110 oracle事务 redo undo

oracle事务

一个事务是由一个回话顺序执行的一组DML语句的执行

事务由会话执行的一下语句开始

insert update delete merge select for update lock table 

事务必须显式的以commit 或rollback之一结束,除非进程失败 由pmon强制回滚

事务的特性(ACID属性)

a.原子性:一个事务中包含的所有DML语句都是一个不可分割的工作单元。事务所做的所有改变都必须一起提交

b.一致性:事务必须确保数据库的状态保持一致,即事务开始时数据库的状态是一致的,事务结束时数据库的状态也必须是一致的

c.隔离性:多个事务可以独立运行,而不会彼此产生影响。事务的结果在事务结束前对其他回话是不可见的

d.持久性,一旦事务被提交之后,数据库的变化就会被永远保留下来,即使数据库所在的机器以后发生崩溃也是如此


这两个概念对于初学者可能比较难理解
undo是记录更改前的一份copy,但你系统rollback时,把这份copy重新覆盖到原来的数据
redo是每次操作都先记录到redo日志中,当出现实例故障(像断电),导致数据未能更新到数据文件,则数据库重启时须redo,重新把数据更新到数据文件 

redo 记录了所有操作,用于恢复(redo records all the database transaction used for recovery) 
undo 记录了所有的前印象,用于回滚(undo is used to store uncommited data infor used for rollback)

redo 已递交的事务,实例恢复时要写到数据文件去的 
undo 未递交的事务. 

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

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

undo 也是也是datafile, 可能dirty buffer 没有写回到磁盘里面去。 
只有先redo apply 成功了,才能保证undo datafile 里面的东西都是正确的,然后才能rollback 

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

所以instance crash recovery 的时候总是先rollforward, 再rollback

select 语句产生redo日志的情况

当存在延迟块清除的时候:
数据块上有一个ITL事务槽的结构,每次进行一个事务的时候,需要在修改的块上申请到一个事务槽,事务槽记录着事务占用的回滚段,事务的状态等信息,事务所修改的记录还存在锁定位信息,因此在事务提交后,需要清除这些信息。清除的内容主要为在TIL事务槽里事务提交标志与提交SCN,清除记录的锁定位信息。
但是ORACLE有一个规则,如果修改的数据块超过BUFER CACHE的约10%,或者数据块已经不在BUFFER CACHE里了,那么会进行延迟块清除,清除的这个过程也会导致数据块的变化,因此会记录日志。
但不会产生undo日志

之所以能select会产生redo,是因为block cleanout:也就是,清除blcok上的部分itl(除flag、scn/fsc外)信息和lb(锁定信息)。

而以上的两部份信息,是不可能roll back、transaction recovery、consistent read、flashback的(undo就这4个功能),所以,是不会记录undo信息的。


只要block有change,就会记录redo信息,这是关系数据库设计的根本原则。

延迟块清除产生的redo其实对于“用户数据”的保护关系并不大,但是,既然block有了变化,Oracle仍然会记录redo信息,这样才能保证“数据是可恢复的”。

另外,块延迟操作时,这个block会变成dirty block而被挂到checkpoint queue上(实际上用户数据并没有改变,也没有发生transaction),这是块延迟的另外一个缺点。

你可能感兴趣的:(20151110 oracle事务 redo undo)