当前位置: 首页 > 科技观察

Oracle数据库出现坏块问题如何处理?

时间:2023-03-12 02:23:14 科技观察

本文主要介绍如何处理Oracle数据库中的坏块问题。不同对象上产生的坏块处理方法会有所不同。本文将粗略介绍这些方法。由于数据库长期运行,由于硬件设备老化,出现坏块的概率会增加。因此,作为DBA,如何解决数据库中的坏块问题就成为了一个重要的课题。一:什么是数据库坏块?首先,让我们看一下数据库块的格式和结构。数据库中的数据块具有固定的格式和结构,分为三层:缓存层、事务层和数据层。当我们读写数据块时,数据库会检查要读写的数据块的一致性,包括:数据块的类型,数据块的地址信息,数据块的SCN号,以及数据块头和尾。如果发现不一致的信息,数据库会将数据块标记为坏块。数据库中有两种坏块,逻辑坏块和物理坏块。二:坏块对数据库的影响如果数据库中有坏块,数据库的告警日志文件中会有一些错误信息:Ora-1578和Ora-600以及bdump目录下的trace文件,其中Ora-600错误第一个参数值的范围是[2000]-[8000]。不同的值代表数据块不同层的问题,如下表所示:范围块层缓存层2000-4000事务层4000-6000数据层6000-8000坏块影响的对象可能是数据字典表、回滚段表,临时段,用户数据表和索引等。不同的对象在产生坏块后有不同的处理方法。三:坏块产生的原因Oracle调用标准的C系统函数读写数据块。因此,坏块可能是由以下原因引起的:1.硬件I/O错误2.操作系统I/OO错误或缓冲问题3内存或分页问题4磁盘修复工具5数据文件的一部分正在被覆盖6Oracle尝试访问未格式化的系统块失败7数据文件部分溢出8Oracle或操作系统错误四:坏块的处理1.首先收集坏块的相应信息。从AlertSID.log文件或跟踪文件中搜索,可以找到一些信息,例如:Ora-1578file#(RFN)block#Ora-1110file#(AFN)block#Ora-600file#(AFN)block#*whereRFN表示relative_fno*AFN表示file_idSelectfile_name,tablespace_name,file_id"AFN",relative_fno"RFN"fromdba_data_files;Selectfile_name,tablespace_name,file_id,relative_fno"RFN"Fromdba_temp_files;2。确定有坏块的对象是什么:SELECTtablespace_name,segment_type,owner,segment_name,partition_nameFROMdba_extentsWHEREfile_id=andbetweenblock_idANDblock_id+blocks–1;通过上面的查询语句,可以查出当前有坏块的对象是什么,是什么类型的对象。需要注意的是,如果临时文件中存在坏块,则不会返回任何记录。3、根据2中查询到的对象类型确定相应的处理方式,常见的有坏块的对象有:1、Sys用户下的对象2、回滚段3、临时段4、索引或分区索引5、常见的处理方式fortables包括:1.恢复数据文件2只恢复坏块(9i以上版本可用)3通过ROWIDRANGESCAN保存数据4使用DBMS_REPAIR5使用EVENT4。具体加工方法介绍。恢复数据文件的方法:如果数据库是归档模式,并且有完整的物理备份,可以使用这种方法进行恢复。步骤如下:1)先将受影响的数据文件离线,执行如下语句:ALTERDATABASEDATAFILE'name_file'OFFLINE;2)保留有坏块的数据文件,然后复制备份数据文件。如果恢复的数据文件需要不同的路径,执行下面的语句:ALTERDATABASERENAMEFILE'old_name'TO'new_name';3)要恢复数据文件,执行下面的语句:RECOVERDATAFILE'name_of_file';4)Onlinethe恢复数据文件,执行如下语句:ALTERDATABASEDATAFILE'name_of_file'ONLINE;*只恢复坏块(9i以上版本可用)。使用该方法需要数据库版本在9.2.0以上,并且需要配置rman的catalog数据库。数据库是一种归档方式,并有完整的物理备份。步骤如下:使用RMAN的BLOCKRECOVER命令:rman>run{blockrecoverdatafile5block11,16;}也可以强制使用某个SCN号之前的备份来恢复数据块。rman>run{blockrecoverdatafile5block11,16restoreuntilsequence8505;}*通过ROWIDRANGESCAN保存数据1)首先获取坏块中ROWID的最小值,执行如下语句:SELECTdbms_rowid.rowid_create(1,,,,0)来自DUAL;2)获取坏块中ROWID的最大值,执行如下语句:SELECTdbms_rowid.rowid_create(1,,,+1,0)fromDUAL;3)建议临时表将无坏块的数据存入临时表,执行如下语句:CREATETABLEsalvage_tableASSELECT*FROMcorrupt_tabWhere1=2;4)将无坏块的数据存入临时表,执行如下语句:插入salvage_tableSELECT/*+ROWID(A)*/*FROMAWHERErowid<'';INSERTINTOsalvage_tableSELECT/*+ROWID(A)*/*FROMAWHERErowid>='';5)根据临时表表中的数据重建,重建表上的索引,limit。*使用10231诊断事件,可以在会话级别设置在全表扫描期间跳过坏块:ALTERSESSIONSETEVENTS'10231TRACENAMECONTEXTFOREVER,LEVEL10';也可以在数据库级别设置,在初始化参数中添加:event="10231tracenamecontextforever,level10",然后重启数据库。然后从有坏块的表中取出没有坏块的数据,执行如下语句:CREATETABLEsalvage_empASSELECT*FROMcorrupt_table;***rename生成的corrupt_table为原表名,重建索引和limit。*使用dbms_repair包进行恢复。使用dbms_repair将表标记为坏块。全表扫描时,跳过坏块,执行如下语句:ExecuteDBMS_REPAIR.SKIP_CORRUPT_BLOCKS('','');然后用exp工具或者createtableasselect的方法把没有坏块的数据取出来,然后重建表,表上的索引和限制。五:坏块预发现的方法1、如果要检测数据库中的所有表,可以使用exp工具导出整个数据库来检测坏块。然而,这个工具有一些缺陷。在以下情况下无法检测到坏块:1.HWM以上的坏块将无法检测到;2、索引中的坏块不会被发现;3.数据字典中的坏块是不会发现的2.如果只是在数据库中的重要表上检查坏块,可以使用ANALYZETABLEtablenameVALIDATESTRUCTURECASCADE方法来检测坏块。它执行坏块检查,但不会将坏块标记为已损坏。检测结果保存在USER_DUMP_DEST目录下的用户trace文件中。3、使用Oracle的专用工具dbv检查坏块,具体语法如下:关键字说明(默认)------------------------------------------------FILE要验证的文件(无)START起始块(文件的第一个块)END结束块(文件的最后一个块)BLOCKSIZE逻辑块size(2048)LOGFILE输出日志(none)FEEDBACKshowprogress(0)PARFILE参数文件(none)USERID用户名/密码(none)SEGMENT_ID段ID(tsn.relfile.block)(None)示例:dbvfile=system01.dbfblocksize=8192DBVERIFY:版本9.2.0.5.0-生产于2004年11月27日星期六15:29:13版权所有(c)1982,2002,OracleCorporation。保留所有权利。DBVERIFY-验证开始:FILE=system01.dbfDBVERIFY-验证完成检查的总页数:32000处理的总页数(数据):13261失败的总页数(数据):0处理的总页数(索引):2184失败的总页数(索引):0处理的总页数(其他):1369处理的总页数(段):0失败的总页数(段):0空的总页数:15186标记为损坏的总页数:0导入的总页数:0注意:因为dbv要求file后面要有文件扩展名,所以如果是存放在rawdevice上,必须先用ln把rawdevice链接到一个文件,然后再用dbv来要检查的链接文件