目标:
确认以及解释和为block崩溃;
收集和解释相关的诊断信息;
实施正确的恢复操作;
何为block崩溃
当RDBMS从磁盘上读或者写一个block的时候,将进行以下的block一致性检查:
block版本
cache中的DBA值和block buffer中的DBA的值进行比较
在设置了的情况下,进行block校验和检查;
进行何种检查:
在oracle 7中:
在block头中的序列号和实例化;
在底部的IncSeq
block的类型
在oracle 8中:
在头部的SCNBase和seq
在底部的SCNBase和seq
block的类型
block类型存储在data block的第一个字节;
以下的几种错误是block崩溃的错误:
ora-600(4519):cache层的block类型不正确;
ora-600(4136):检查rollback segment block
ora-600(4154):检查rollback segment block
block崩溃的类型
物理崩溃
在oracle 7中:INC=0
在oracle 8中:SCM=0
软件崩溃:
oracle 7中:Seq=0
oracle 8中:SCN=XXX Seq=UB1MAXVAL,在这里,xxx表示一个最高的改变的SCN,是用来对整个block重建的,也可以应用到block上.
物理崩溃:block中的信息从磁盘读出后,没有任何意义;
软件崩溃:RDBMS在侦测到错误后,标记该block为崩溃;
在oracle 8中,seq的值中,最大的是UB1MAXVAL-1,因此,UB1MAXVAL用来标记一个block软件崩溃;
症状:ora-1578
ora-01578:”oracle data block corrupted”(file #%s,block #%s)
当一个崩溃的block被发现的时候,将引发这个错误;
该错误的返回一定会带上绝对的文件号好block号
检查alert.log文件
通常,ora-1578是一个硬件问题的结果,如果ora-1578一致返回的是同一个参数,那么很可能是发生了一个物理的block崩溃;
如果参数每次都改变,那么有可能是硬件问题,客户最好作一个内存和内存交换的检查,并且IO自系统检查是否有错误的控制器;
如果block号码是10进制的,可以使用unix的dd命令来尝试从磁盘上dump出这个block,如果得到一个读错误,那么肯定是硬件故障.同样,你也可以尝试多次dump同一个block,并且看看是否都是得到的同样的数据,这可以用来检查IO子系统和是否有坏的控制器;
症状:ora-600
ora-600[3374],[a],[b],[c],[d]
在写入的时候,block检查失败
在内存中崩溃了
检查dba,type,version和inc#
ora-600[kcbzpd_1],[d],[kind],[chk],[],[]
这个错误在oracle8中已经被ora-600[3374]所替代
ora-600[kcbzpd_1],[d],[kind],[chk]是当block在内存中崩溃的时候发出的信号.唯一的可能是一个非预期的存储在内存中损坏了block的头或者是尾.
同样,ora-600[3339]错误和ora-1578错误一起的时候,表示block被读取后在内存中崩溃了;
如何处理崩溃
检查alert文件和系统日志文件;
使用可用的诊断工具来找出崩溃的类型;
使用补丁包来看block是何种错误;
多次检查看错误是否是持续的;
必要的时候,对崩溃的对象进行恢复;
通常需要找出问题是否是永久的,因此要多次运行分析系命令.如果可能,作一个shutdown和startup来看看以前的操作是否还存在.
找出是否是多个崩溃,如果遭遇到的一个block崩溃,很可能其他的block也崩溃了,最好用DBVERIFY监测;
在你准备尝试修复block中的数据之前,执行block dump来确认引起崩溃的原因
对损坏的block使用一个16进制的dump,在unix上用dd和od-x
考虑对redo log作一个dump来检查所有在该block上的改动,以方便可以发现引起崩溃的原因;
注意:当你有block崩溃的时候,在硬件修复后执行一个介质恢复是推荐的方法.
解决硬件的问题
内存装载
磁盘控制器
磁盘
从崩溃的对象作备份恢复是必须的
如果硬件损坏,则没有办法继续工作.当遭遇到硬件问题,厂商应该先修复硬件问题,一个完全的硬件诊断应该被执行.
很多硬件问题可能发生:
坏的IO或者防火墙
操作系统IO或者cache问题
内存或者内存交换的问题
磁盘问题
DBVERIFY包
从oracle7.3开始引入的数据文件验证包
仅仅只对data file有效,不能检查redo log文件
检查block的一致性
采用只读的方式打开数据文件,因此可以在数据库运行的时候使用;
但是在数据库在运行的时候使用该包检测是不推荐的,因为cache中的block可能已经崩溃
页数目就是该data file中的block的数目
DBVERIFY使用标准的kcb程序来检查block的完整性
如果头和尾不匹配,DBVERIFY将再次读该block,如果匹配,则报告一个infulx block,否则报告崩溃
influx blocks就是分裂的blocks,如果DBVERIFY不报告崩溃意味这他是第一次读该block的时候DBW0正在写一个新的版本信息并且该block中有一些旧的信息,因此头和尾不匹配.
注意:DBVERIFY仅仅检查逻辑的崩溃,也就是说,他仅仅使用kcb.h中的程序来检查block的头/尾信息,因此,在高水位上的崩溃还是可能发生.
ALALYZE命令
执行一个逻辑的block检查
不会标记block为软件崩溃,仅仅只是报告
检查整个索引和表
cascade选项,将检查该对象的所有关联对象;
该选项的好处是可以在sql*plus中针对一个特定的对象,多次来作完整性检查,以确认错误是否是永久的.
对于分区表,oracle同样会验证正确分区的行,如果行不正确,则行会被记录到invallid_rows表中.
注意:一个简单的查询(select * from
)会进行全表扫描,这就意味着将读高水位以下的所有块,.你可以使用这个方法来进行一个数据表的快速崩溃检查;
诊断事件
event 10231:”skip corrupted blocks during a full tables scan”
event 10233:”skip corrypted data or index blocks on index range scans”
在参数文件中设置这两个事件的语法:
event=”10231 trace name context forever ,level 10”
event=”10233 trace name context forever ,level 10”
注意:当你基于一个值的范围查询数据库或者是使用非唯一索引查询的时候,会使用索引范围扫描.
event 10232:”dump corrupted blocks in a trace file”
event 10210:”force logical block checking”任何时候,一个表的block被改变,一致性检查就会作,坏的blocks被标记为软件崩溃
event 10211:也就是10210在索引上的事件
event 10212:也就是10210在聚合blocks上的事件
对于事件10210,10211,10121,当block一致性到坏block的时候,返回FALSE
将检查如下项目:
free slot list结构
block中的行位置
交迭行的位置
itl上事务锁的数目
这三种事务允许尽快的检测到潜在的错误,但是,由于其要拷贝block,所以性能受到影响.所有被检查出来的坏的block被标记为软件崩溃,这意味着这些block中的数据都丢失了.
在参数文件中使用如下语法启用他们:
event=”xxx trace name context forever,level 10”其中xxx表示10210,10211,10212.
注意:这些事件大家过高,记得在不需要的时候关闭他们,10231和10233事件仅仅只是跳过软件崩溃的blocks
初始化参数db_block_checking
在8i中引入
可以使用alter session或者是alter system deferred命令设置
取代了10210,10211,10212事件
默认值为false
db_block_checking初始化参数执行和10210,10211,10212事件一样的检查;
默认设置为false,是为了兼容早期版本为disable的
因为参数是动态的,所以比事件方便,在未来版本中,将完全取代三个事件.该参数的设置,将完全覆盖三个事件的设置.
export包
一个全的export可以用来检查数据库的逻辑一致性;
export在所有的的表上执行全表来提取数据
export不能侦测所有的崩溃
不能侦测在高水位以上的blocks的崩溃;
不能侦测索引上的崩溃,也不能侦测在空闲和临时段中的崩溃
当你执行export的时候,如果你只是想对数据进行一致性检查,你可以不创建一个dmp文件.在unix系统上,使用/dev/null作为文件名,在Open VMS上使用NULL,在windows上使用NULL.当你这么作的时候,export读取所有的数据,但是写入到空设备,也就是说没有写任何东西.这事一个检查数据库逻辑一致性和侦测崩溃的好的方法,并且可以检查物理崩溃(已经使用的blocks)和逻辑崩溃(数据字典中标示的)
export包仅仅读取
在高水位以下已经被使用的数据
和被导出数据有关的部分数据字典的信息
注意:因为export并不读取所有的数据字典,因此可能无法检测到SYSTEM表空间上的崩溃.
介质恢复
数据库必须在归档模式,执行以下步骤:
处理物理问题,例如更换磁盘;
找出那个数据文件包含了崩溃blocks
从备份中恢复该数据文件
恢复该数据文件
查询v$datafile和dba_data_files来得到那个数据文件包含了崩溃的blocks
在作恢复前,确认所有的硬件问题已经处理了.如果磁盘损坏,并且你有足够的空间在另外的磁盘上,通常应该把备份放到好的磁盘上,记得把数据文件重命名到新的位置并且恢复.
同样,在恢复后,你应该检查下恢复的数据文件的崩溃状况,如果你没有热备份,那么需要从一个全冷备中恢复.
那一个对象损坏了?
索引:drop掉,并重建该索引
rollback segment:看后面的课程
表:崩溃的block中的数据已经损坏.
drop表,并重建,从一个dmp文件中import数据
设置10231事件跳过该崩溃的blocks,并且export出来,drop表,然后使用dmp文件重建
使用sql或者pl/sql将数据传输到一个新表中.
如果不准备作恢复,可以使用如下的语句来发现是那个对象损坏了.
select segment_name,segment_type,relative_fno from dba_extents where file_id= and between block_id and block_id+blocks-1;
使用sql和pl/sql
如果崩溃的表有唯一索引,可以使用该索引
使用rowid提示,在崩溃的blocks附近作一个范围扫描
必须使用pl/sql来从包含long类型列的表中提取数据
行链接
如果在崩溃的block中有行链接,这些数据会丢失,你为了找出那些行必须跳过,使用WHERE子句查询ROWID,如果得到错误,看最后返回的rowid,你就可以知道下一个rowid是有问题的,然后再执行alter查询一次.
long列
如果包含long列,你必须写一个小的pl/sql块用来处理long列,这个有一些最大大小的限制的(例如,32k)
如果long的数据非常大,写一个pro*c或者是oci程序将是比较好的方法.
sql*plus可以在执行了longchunksize参数的情况下,使用COPY命令拷贝数据.但是,同样有一个对于long的大小的限制,并且是OS依赖的,具体可以查看用户手册.
dbms_repair包
在8i中被引入
在事务和数据层工作
在早期版本中,仅仅标记block为软件崩溃
dbms_repair报能侦测block损坏,但是不能修复,能在block未被标记为崩溃的时候提取有用的信息;
在block被标记为崩溃后,整个block必须被跳过;
admin_table:创建修复表
chech_object:装载有关崩溃和修复的修复表的信息
fix_corrupt_blocks:基于修复表的信息来修复特定的崩溃的block
dump_orphat_keys:报告在崩溃的数据block里面的行在索引上的入口(可选)
skip_corrupt_blocks:在索引和全表扫描的时候跳过崩溃的blocks
使用ORAPATCH补丁
ORAPATCH类似一个文件编辑器或者磁盘
ORAPATCH help列出所有命令
你可以用16查看和修改RDBMS支持的所有的文件和block类型
他可以作任何事,但是在重建block的过程中,非常的消耗资源
ORAPATCH是内部支持工具,不对客户开放
在你作block的patch前,应该获得客户的许可,让客户知道可能发生的事情.并且要知道客户是否能接收这样的时间消耗,通常,blocl中的数据丢失,是非常难重建整个block的.
使用BBED补丁
BBED类似一个block的编辑查看器
在数据库打开的状态下编辑和查看磁盘的数据结构
显示和编辑的时候支持物理和符号的接口
BBED在oracle 8版本中引入,包含所有ORAPATCH的功能,并且能显示block中的独立的数据结构.对于清除的检测block的错误是很有帮助的.相对于ORAPATCH,BBED可以保存前映象,因此你可以回滚任何操作.
在unix上,需要如下使用命令来重链接BBED
$make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
注意:link命令并非在所有平台上都可运行,必须编辑make文件来创建一个可执行文件.
在windows上BBED.EXE是可执行文件,并且有密码blockedit保护.
使用BBED或者ORAPATCH补丁
ORAPATCH和BBED潜在可能是数据库崩溃
永远不要使用客户的系统作为测试系统
在你作尝试前,一定明确客户的期望
注意:BBED和ORAPATCH只是对于逻辑崩溃有用,对于物理崩溃基本没有什么用处
Write a comment
You need tologin.