目标:
确认以及解释何为回滚段崩溃;
收集和分析相关的诊断信息;
明确的实施合适的恢复操作;

对于RDBMS来说,回滚段是非常重要的,在构建数据库的一致性读和事务回滚的时候有非常重要的作用.当他们损坏的时候,数据库的可用性将受到影响,如果没有事先作正确的预防,恢复数据到一致性可能是无法完成的
当用户请求支持的时候,通常是在一个恢复操作失败以后.他们有将数据库工作正常和受控的压力.因此必须应用RDBMS的知识尽快恢复.如果全部达到一致不可能,必须能解释原因和威海
本课讲述事务管理,数据库启动以及回滚段获取以及回滚段损坏将如何影响这些工作.这些将帮助你明白回滚段的损坏的症状,附加的诊断以及如何通过文档没有记载的参数来改变RDBMS的行为

回滚段内部:概述
事务的开始是当在回滚段的头部的事务表中获得一个槽.这是一个事务的物理表现.事务标示(txid)是指向这个槽的一个标示.事务标示有如下的结构:
txid=usn.slot.wrap(undo_segment_number.transaction slot id.SCN wrap)
在一个事务对一个表进行插入,更新以及删除记录前,一个ITL在该记录的块中被分配.ITL在事务提交和回滚前会对行加锁.ITL中包含了事务标示.
当改变应用到块,回滚信息也被获得,并存储在回滚段中.事务表的槽包含指向回滚的指针.

回滚段内部:读一致性
假定一个不同的session想读同一个块,并且第一个session还没有提交.
读的session读块的时候,发现了一个打开的ITL.他将检查事务的状态(通过读回滚段头)并且判断是否依然为活动状态.这就意味着事务必须得到活动事务改变前的信息.这就称之为一致性读,这个时候要从回滚段中克隆块,并且应用回滚记录回滚最后的更新.
注意,一致性读要访问数据块,回滚头以及回滚记录.任何一个损坏,一致性读将受到影响.

事务内部:锁定
继续刚才的例子,假定另外一个session想更改(更新或者删除)第一个事务更改的记录,第一个事务没有提交.
这个新的session读块的时候将发现打开的ITL.他通过读回滚段头来得到事务状态.并且会发现事务是活动的.这个时候,他将无法完成,必须等第一个事务完成(提交或者回滚)
注意:必须读回滚段头来得到ITL的状态,如果回滚段头损坏,则锁定会受到影响.

事务内部:提交
继续刚才的例子,假定第一个事务现在提交,该事件将立即在事务表槽中标记为非活动的,因此数据块自己并不会马上被更新.这也就是说,在块中的ITL将在提交后保持打开一段时间.
当RDBMS下次读到这个块的时候,事务表被检查,提交已经得到确认,ITL也被关闭.这称之为块清理延迟.如果回滚段被删除,记录在undo$中的SCN记录将被用来确认提交的完成.
注意:RDBMS必须读回滚段头来执行块清理延迟.如果回滚损坏,块清理延迟将受到影响.

事务恢复
事务回滚的执行者:
当回滚语句发现,通过影子进程处理
当程序中的事务崩溃,通过PMON来处理
当运行数据库的活动事务的影子进程崩溃,通过SMON处理

事务恢复:回滚
当一个回滚语句发出,RDBMS以倒序扫描当前事务的回滚记录并且应用到数据库中.当语句返回,该块中的所有操作将被回滚并且ITL被清理.回滚的时候,没有延迟.
回滚操作需要访问回滚段头,回滚记录以及数据块.任何一个损坏,回滚将受到影响
注意:回滚操作会产生新的redo,并且被记录到redo log中.

事务恢复:进程崩溃
如果活动事务的RDBMS的影子进程崩溃,PMON侦测到失败将立即回滚该事务.可以通过改变初始化参数或者是设置事件来监测这个操作.
10012 trace name context forever,level 1(abort transaction)
10246 trace name context forever,level 1(trace PMON actions to trace file+IO slave trace)

事务恢复:实例崩溃
如果在失去提交前,实例崩溃,这个时候没有时间来作事务回滚.下次数据库打开的时候,崩溃恢复执行数据库前滚,将数据库恢复到崩溃前的状态.这个操作的职责是事务(回滚)恢复来移除所有未完成的事务.

事务恢复:数据库打开
在SYSTEM回滚断中的活动事务将立即被回滚;
在其他回滚段中的活动事务标记为死的.
稍后,SMON将再次扫描段,并且对标记为死的事务进行回滚
在一个非预期的关闭之后,RDBMS将尽快的启动起来.这对于减少宕机时间是特别有用的.如果一个新的事务向更新被标记为死事务的事务锁住的数据,新的事务将回滚标记为死的事务而不必等待SMON.
在7.2以前的版本中,所有的活动事务在数据库打开前被回滚.因此损坏的回滚段将导致数据库打开困难.
在7.3中,大多数情况下,回滚段损坏,会被记录到alert.log文件以及trace文件.这样就可以方便的诊断失败内容,因为你可以去访问数据库.但是,可能会导致客户运行了很久都不知道问题发生.注意,在oracle 8中如果服oracle不能读到回滚段头,则不能打开数据库.
所有的回滚段(在undo$中记录的),并不是要在rollback_setments参数中写的,在数据库打开的时候要检查活动事务.
在oracle8中,可以通过以下的查询列出标记为死的事务:
select * from x$ktuxe where ktuxecfl=’DEAD’;
也可以通过dump出回滚段头来查看cflags列看那些事务标记为死的
dump的方法用如下的命令:
alter system dump undo header R01;
这里R01标示回滚段的名字,死事务的cflags=’0×10’

回滚段的获取
在事务回滚后,回滚段被实例获得
  首先被获得的是在rollback_segments中指定的段
  必要的时候,共用回滚也将被获得.
获取失败的经典错误是ora-1545”rollback segment %s s[ecified not available”
一个实例应该获得的回滚段的数目由初始化参数tansactions和transactions_per_rollback_segment决定,要求为:
1(for system)+transactions/transactions_per_rollback_segment
当数据库打开的时候,状态为”Need Recovery”的段将无法获得,如果被指定在rollback_segment中,则实例无法打开.
包含死事务的回滚段将被在新事务要求获取的时候可用.

诊断事件
event 10013:在启动的时候监控事务回滚,在初始化参数中如下设置:
10013 trace name context forever,level 10
event 10015:在事务回滚前后,将在undo$中列出的回滚段的段头dump出来.在初始化参数中如下设置:
10015 trace name context forever,level 10

隐含参数:概述
offlinerollback_segments
corruptedrollback_segments
隐含参数以及不支持的初始化参数,作为恢复的最后一步
使用逗号分隔每个回滚的名字,例如
offlinerollback_segments(r01,r02,r03)
在rollback_segments中的不管是SYSTEM回滚段还是普通段都可以被指定到隐含参数中.
注意:不支持的含义是:
  oracle并没有设计为对这些参数工作;
  参数没有被测试过,因此你必须在各种环境下测试他们;
  数据库的一致性将不能保证;
  对数据库有重大的风险

使用初始化参数_offline_rollback_segments以及_corrupted_rollback_segments将在以下时刻改变数据库的行为:
打开数据库;
执行一致性读和块清理延迟
删除回滚段

隐含参数:在数据库打开的时候
当打开数据库的时候,_offline或者是_corrupted隐含参数:
不扫描,并且任何活动事务即不标记为死的也不标记为回滚;
在dba_rollback_segs(undo$)中表现为offline
不能被实例中的新事务获取
当使用了隐含参数的时候,数据库打开后,事务表不被读取,因此事务不能被标记为死的或者是回滚的.因此是十分危险的,因为如果这个时候在段中有活动事务,将是非常反常的.他们不会标记为死的,虽然在实例启动前他们是属于一个活动的事务.
不可预期的事情将会发生,记住,数据库处于不被支持的状态.

当打开一个数据库的时候,_corrupted中标记了的回滚段上的所有分布式事务被标记为”forced commit”
这些本来应该是通过更新pending_trans$和dba_2pc_pending(两个不同阶段的commit)来完成的
在分布式事务环境中,回滚段自己不被更新,oracle执在pending_trans$和dba_2pc_pending中执行更新.

隐含参数:一致性读和清理
如果打开的ITL被发现在一个_offline的段中,段将被读,用来查看事务状态.
如果事务提交了,块被清理;
如果事务活动的,并且想读块,一个一致性读的块从这个段中的信息来构建出来;
如果活动的,并且你想锁定记录,不可预知的行为将会发生.
注意,虽然回滚段是_offline的,oracle还是可以读段来找出事务状态来获得回滚记录执行回滚,如果损坏的块被发现,oracle将依然失败;
当你更新一个包含有活动死事务的块,影子进程循环识别,很消耗cpu,这也就是为什么老的进程表现为活动,但是oracle事务却尝试等待一个TX锁.你可以立即得到锁,因为老的进程并不会长期持有.oracle将再次检查块并且他依然是活动的,因此处理器一次又一次的重复.

如果一个打开的ITL发现被属于标记为_corrupted的段,段将不会被读来查看事务状态.
如果回滚段被删除,事务将被标记为提交并且块延迟清理被执行.
如果事务被提交,逻辑损坏将发生
非常重要的是,oracle在这种情况下,不会读段.他当做段已经被drop了,这也是_offline和_corrupted的区别.
注意,如果一些ITL被清理并且这些回滚段通过移除参数_corruped再次引入到数据库中,你应该尝试回滚你刚才提交的块.
测试显示,通常数据块已经损坏,为了防止这些发生,如果你使用了_corrupted参数,最好删除这些回滚段.

隐含参数:删除回滚段
通常,如果回滚段中包含活动事务,是不能被删除的
当删除一个_offline或者_corrupted回滚的时候,检查不会被执行
作为一个结果,段将被删除,不论其是否包含活动事务.
如果你删除了_offline或者_corrupted段,丢失逻辑数据的风险就存在,甚至可能是丢失数据字典中的数据
因此为了改变你的数据库到一个可支持的状态来处理这个问题,应该移除参数,关闭实例并且正常的启动实例.

从损坏中恢复
在所有的例子中,介质恢复是首选的恢复路径,因为他是被支持的并且可以保证一致性
当介质恢复不可能的时候,选择一个方法和风险评估

恢复步骤
回滚段损坏可能被一致性读,行锁,块清理以及回滚发现
如果回滚段头损坏,则数据库被阻止打开.
隐含参数可能可以恢复,但是,他们仅仅是作为最后一步,并且是在向客户解释清楚了风险的情况下



 


Write a comment

You need tologin.