Undo Segment Corruption and Recovery

来源:互联网 发布:java 国际化 编辑:程序博客网 时间:2024/06/05 19:30

Transaction Internals: 概述

首先,只有当在回滚段头(head of an undo segment)中分配得一个slot之后,一个事务(transaction)才能开始。这是一个事务(transaction)的物理表现(physical manifestation)。事务对应一个事务ID(txid),这个txid就是指向这个slot的一个指针。Txid的结构如下:

Txid = usn.slot.wrap

(undo_segment_number.transactionslot id.SCN wrap)

       在一个事务(transaction)开始insert、update或者delete一个表中的数据行之前,包含此数据行的Block将被分配得一个ITL,这个ITL用于标志此数据行被锁定——直到事务提交或回滚。ITL中包含txid信息。

       当事务修改数据快时,undo信息也同时创建并存储在回滚段中,回滚段头中对应于此事务的slot存储了指向这些undo信息的指针。

       注:当查询v$lock视图时,id1字段——usn.slot;id2字段——SCN Wrap

 

Transaction Internal: Read Consistency

    一致性读取(Read Consistency):

 

       假设,前一个事务正在修改一数据块(事务还没有提交、回滚)时,另一个会话(session)要求读取此数据快中的数据。

       后一个会话在读取数据块时(可能此数据快正在内存中),将发现数据快中的被打开的ITL。它检查事务的状态(通过读取回滚段头信息),将发现事务仍然是active状态。这就意味着,这个会话必须回推正在执行事务所作的操作,以获得此数据快在活动事务开始修改之前的内容。这被称为创建一个CR(ConsistentCopy) Copy。

       从上面的描述中我们获致,一致性读取(Read Consistency)需要访问数据快、回滚段头、回滚段记录。任何一个部分出现Corruption,一致性读取都会受到影响。

 

Transaction Internal: Locking

Locking

       继续上文中的例子,假设一个会话修改一个数据行,但是此数据行正在被前一个事务修改中,而且第一个事务还没有提交或回滚事务。

       后一个会话在读取数据块时(可能此数据快正在内存中),将发现数据快中的被打开的ITL。它检查事务的状态(通过读取回滚段头信息),将发现事务仍然是active状态。这就说明这个时候不能更新此数据块,必须等待前一个事务结束(提交或回滚)。

       由上文描述可知,Locking过程必须要能够访问回滚段头,如果回滚段头出现corruption,将会影响Locking。

 

 

Transaction Internal:Commit

Commit and Delayed Block Cleanout

       我们继续前面的例子,假设第一个会话现在提交了(Committed)。这个将立即触发回滚段头中Transaction Table slot被标记为Inactive状态;但是,数据快本身可能并不会被立即修改以记录事务已经提交——这也就是说,在提交之后一段时间,数据快中的ITL可能仍然是打开(Open)的。

       当RDBMS再去读取此数据快时,如我们前文所说的,将会去检查回滚段头中的Transaction Table中的slot,RDBMS此时会确认事务已经关闭了,这时候数据快中的ITL才会被RDBMS关闭。这就是所谓delayed block cleanout。如果这时候回滚段此时已经被删除,RDBMS会使用undo$中存储的SCN信息来确认事务是否被关闭。

       注:由于RDBMS必须去读取回滚段头中的信息来确认事务是否已经被关闭,所以如果回滚段头中出现corruption,delayed block cleanout将会受到影响。

      

 

Transaction Recovery

       事务恢复(回滚事务的处理过程)有下述几种情况:

l  当rollback 语句显示的被调用,由shadow process 执行Transaction Recovery。

l  当一个会话异常中断,由PMON执行Transaction Recovery。

l  在数据库打开时,由SMON或shadow process执行

 

Transaction Recovery:Rollback

 

       当执行一个rollback语句,RDBMS将查找所有跟事务相关的undo记录,并且应用到数据库中。当语句结束后,事务所有的修改都被undone,并且ITL将会被清除。在rollback的时候没有delay。

       Rollback操作需要访问回滚段头,undo records,数据快。任何一个出现corruption,rollback操作都会受到影响。执行回滚的操作会产生新的redo,将会被写到redo log中。

 

Transaction Recovery after a Process Crash

       如果一个shadow process进程在事务处理中crash掉,PMON会探测到并立即回滚事务。可通过如下两个event来监测此操作:

       10012tracename context forever,level 1

       10246tracename context forever,level 2

 

Transaction Recovery: Instance Crash

       如果RDBMS实例在某个事务还没有提交前crash掉,事务将没有机会回滚。在下次打开数据库的时候,crashrecovery将数据库rollforward,使得其恢复到实例crash之前的状态。然后由rollback recovery负责清除不一致的事务。

 

Transaction Recovery:Database Open

l  在system回滚段中的活动事务将会被立即rollback;

l  其他回滚段中的活动事务会被标记为dead;

l  稍后,SMON进程会再次搜索回滚段,将标记为dead的回滚段信息回滚;

 

在一次非正常的shutdown之后,RDBMS会经可能块的start up。这有利于减少宕机时间。另外一个好处时:如果一个新的事务试图更新被一个dead事务锁定的数据行时,新的事务会去回滚dead事务,而不必必须等待SMON进程。

       此特性的一个侧面影响是:即使一个回滚段Corrupt了,数据库仍然能够打开,只是在alert日志中记录错误信息,由SMON进程产生一trace文件。

       可用下述SQL语句查询deadtrasaction:

       Select * from x$ktuxe where ktuxecfl=’DEAD’;

       或者直接将回滚段头dump出来分析:

       Alter system dump undo header R01;

 

 

Undo Segment Acquisition

l  在transaction recovery之后,实例会尝试获取回滚段:

n  在rollback_segments参数中指定的回滚段会被最先获取(acquisition)。

n  公共回滚段也会在需要的时候被获取。

l  获取如果出现错误,典型的是Ora-1545

 

如果回滚段的状态是‘Needs Recovery’,此回滚段将不能被实例获取,所以如果rollback_segments参数指定的回滚段中,如存在这样的回滚段,数据库将不能打开。

       回滚段中存在dead transaction的可以被获取,用于记录新事务。

 

诊断事件:

10013——在startup时,监测Transaction Recovery

10015——在Transaction Recovery之前、之后分别dump回滚段头信息

 

 

使用隐藏参数:

_offline_rollback_segments

_corrupted_rollback_segments

 

System回滚段和已经在rollback_segments中列出的回滚段不能使用上述隐藏参数。

 

使用隐藏参数对RDBMS的影响

对打开数据库的影响

       在打开数据库时,任何在这两个隐藏参数中出现的回滚段:

1.      不会被扫描,任一个活动的事务既不会被标记为dead也不会被回滚

2.      在dba_rollback_segs中标记为offline

3.      不能被实例获取,接受新的事务

4.      任何与_corrupted中出现的回滚段相关的分布式事务将被标记为’forced commit’

5.      通过更新pending_trans$和 dba_2pc_pending实现

 

对CR和Cleanout的影响

       如果发现存在ITL和_offline中指定的回滚段相关,那么该回滚段将会被读取以获得事务的状态。

l  如果状态为Committed,cleanout。

l  如果状态是Active,并且你想读取数据快,将使用回滚段创建一个CR Copy。

l  如果状态是Active,并且你想Lock数据行,歇菜了,可能会死循环的。

 

如果发现存在ITL和_corrupted中指定的回滚段相关,回滚段不会被读取,事务状态不会被获取。

l  效果会和回滚段被drop一样,事务会被假定为committed,将执行delayed block cleanout。

l  如果事务并不是已经被提交的,那么logical corruption就出来了

 

所以,如果使用_corrupted参数,一定要重建数据库。

 

注:如果ITL在cleanout之后,我们去除_corrupted参数,如果你想roll back你刚才已经提交的数据快,测试证明,会导致数据快corruption

 

回滚段Corruption的恢复

l  任何情况下,介质恢复(Media Recovery)都是最好的选择,因为它保证一致性

当介质恢复不可用,才尝试使用其他手段,但是由此带来的危险性,最好在做之前有清楚的认识
原创粉丝点击