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

如何格式化不属于任何段的损坏块

时间:2023-03-17 00:31:28 科技观察

1、问题症状:1、rman备份失败,显示ORA-19566错误,报坏块不属于任何对象2、dbverify显示有坏块3.坏块不属于任何对象2.原因分析:RMAN和DBV在被重用重新格式化之前,还是会报坏块。3.解决方案:解决此类问题的可能方法如下。请注意,它不能保证解决问题,但已知在几种情况下可以解决问题。如果一个数据文件报很多block损坏,请在第6步的blocknumber提示中输入最近报告的badblocknumber将成为自由空间。它们在那里等待重新分配给需要额外空间的对象。一旦它们被重新分配以用于对象上的新范围,它们将被更改,只有在使用这些块时才会被任何DML操作使用(即使现在需要分配空闲空间中的损坏块)。在重新格式化之前阻止。请注意,扩展区的简单分配不会格式化块。第7步分配的extent和第8步进行的DML操作,使用第7步分配的块,这样的坏块被重用和格式化。在本文档中,我们尝试手动重新格式化坏块。第1步-识别损坏的数据文件损坏可以在应用层报告,例如DBV和RMAN,或alert.log。例如,您可以在RMAN备份期间收到以下消息:RMAN-03009:04/29/200509:44:41nm4501通道上的备份命令失败ORA-19566:超出文件E:\的0个损坏块的限制xxxx\测试.ORA。坏块位于文件E:\xxxx\test.ORA中。第2步-在受影响的数据文件上运行DBV/Rmanverify并检查坏块在报告坏块的数据文件上运行dbverify。#dbvuserid={system/password}file={fullpathfilename}logfile={outputfilename}Step3-检查块是否是对象的一部分-对于损坏块号较小的情况查询dba_extents确认坏块是否属于任何对象。SQL>selectsegment_name,segment_type,ownerfromdba_extentswherefile_id=andbetweenblock_idandblock_id+blocks-1;如果该块不属于任何对象,则查询dba_free_space确认坏块是否属于数据文件的可用空间。SQL>Select*fromdba_free_spacewherefile_id=andbetweenblock_idandblock_id+blocks-1;第4步-找到受影响的块并验证它属于任何段易于使用和方便。如果你在第2步运行了rmanverify,直接进入下面给出的sqlplus脚本来确认对象。$rmantarget/nocatalogor$rmantargetsys/nocatalogrun{allocatechanneld1typedisk;allocatechanneld2typedisk;----------------------------------------------------------------------多个通道可以分配用于并行化目的--取决于:RMAN-Min(MAXOPENFILES,FILESPERSET)--默认值:MAXOPENFILES=8,FILESPERSET=64----------------------------------------------------------------allocatechanneldntypedisk;backupchecklogicalvalidatedatabase;注意:如果RDBMS小于11g并且处于非归档模式,则数据库必须处于挂载模式***RMAN命令“备份检查逻辑验证数据库”*必须*运行并完成,然后才能继续进行。***“v$database_block_corruption”视图将在此命令完成后填充(基于文件)。***如果不这样做,您可能会在接下来的步骤中获得无效/不完整的信息。Step5-以SYS或SYSTEM以外的用户创建虚拟表(用户)SQL>connectscott/password在包含坏块数据文件的表空间中创建虚拟表,并使用nologging选项防止重做记录产生:SQL>createtables(nnumber,cvarchar2(4000))nologgingtablespace;可以使用不同的存储参数来适应特定的环境。我们使用PCTFREE99来加速块的格式化以确认表是在正确的表空间中创建的,通过查询user_segments:QL>selectsegment_name,tablespace_namefromuser_segmentswheresegment_name='S';请注意,在11gR2中,由于延迟创建段的概念,从上面提到的user_segments查询可能不会报告。在这种情况下查询USER_TABLESSQL>selectsegment_name,tablespace_namefromuser_tableswheresegment_name='S';第6步-在虚拟表上创建触发器,一旦坏块被重新使用就会抛出异常以sysdba身份连接并创建以下触发器:请注意,当提示输入文件编号时,输入相关文件编号(rfile#valueinv$datafile)CREATEORREPLACETRIGGERcorrupt_triggerAFTERINSERTONscott.sREFERENCINGOLDASp_oldNEWASnew_pFOREACHROWDECLAREcorruptEXCEPTION;BEGINIF(dbms_rowid.rowid_block_number(:new_p.rowid_rowid_row)=&blockms_rowid_rowid_rowid)=&blockms_rowid_block_number(:new_p.rowid_rowid)=&blockms(:new_p.rowid)=&filenumber)THENRAISEcorrupt;ENDIF;EXCEPTIONWHENcorruptTHENRAISE_APPLICATION_ERROR(-20000,'Corruptblockhasbeenformatted');END;/出现块号提示时,输入坏块的块号。当提示输入文件编号时,输入损坏数据文件的相关文件编号(v$datafile中rfile#的值)。第7步-为受影响的数据文件中的表分配空间。注意:1)如果这是一个ASSM表空间,你可能需要重复这个步骤几次。即创建多个表,分配多个extent。并定期检查dba_extents以确保可用空间现在已分配给虚拟表。这是因为ASSM会自动判断下一个extent的大小2)建议确保数据文件AUTOEXTEND为OFF,防止其增长。首先通过查询dba_free_space找到extent大小SQL>SelectBYTESfromdba_free_spacewherefile_id=andbetweenblock_idandblock_id+blocks-1;BYTES---------------------------------------------------------------------65536在这个例子中,它的大小是64K。所以按照下面的方法分配extent:SQL>altertablescott.sallocateextent(DATAFILE'E:\xxxx\test.ORA'SIZE64K);如果这个数据文件中有多个64K空闲区,你可能需要使用这个循环:BEGINforiin1..1000000loopEXECUTEIMMEDIATE'altertablescott.sallocateextent(DATAFILE'||'''E:\xxxx\test.ORA'''||'SIZE64K)';endloop;end;/Continuetoallocatespaceuntilthebadblockbecomepartofscott.s—检查以下查询:SQL>selectsegment_name,segment_type,ownerfromdba_extentswherefile_id=andbetweenblock_idandblock_id+块-1;第8步-将数据插入虚拟表以格式化块大小,循环次数可能会有所不同):BEGINFORiIN1..1000000000LOOPINSERT/*+APPEND*/INTOscott.sselecti,lpad('REFORMAT',3092,'R')fromdual;commit;结束循环;结束;或BEGINFORiIN1..1000000000LOOPINSERTINTTOscott。sVALUES(i,'x');ENDLOOP;END;/或将以下代码用于2个循环:BeginFORiIN1..1000000000loopforjIN1..1000loopInsertintoscott.sVALUES(i,'x');endloop;commit;ENDLOOP;END;everyInserting表中的一行会触发触发器,一旦第一行数据插入坏块,就会产生ORA-20000异常。第9步-通过运行DBV和Rman备份识别数据文件中的坏块运行dbverify或RMAN以再次验证损坏的数据文件(或整个数据库)。它不会显示块损坏。确保执行两次手动日志切换或检查点,以便将内存中的信息写入磁盘。RMAN备份不会报告此块上的任何错误。在运行真正的备份操作之前,您可以在数据文件上重新运行RMANvalidate命令并检查v$database_block_corruption是否不再显示块被标记为已损坏。对于数据库版本<=10gR2Rman>Backupvalidatechecklogicaldatafile,;对于数据库版本>=11gR1Rman>Backupvalidatechecklogicaldatafile;或Rman>validatedatafileblock,;一旦完成SQL>SELECT*FROMV$DATABASE_BLOCK_CORRUPTION;第10步-删除在第4步中创建的虚拟表SQL>DROPTABLEscott.s;如果版本是10gr1及以上,使用purge选项清空回收站Step11-执行手动日志切换和检查点执行两次日志切换和检查点将内存格式化块写入磁盘,让dbverify不再报错SQL>Altersystemswitchlogfile;-->DothiscoupleoftimeSQL>Altersystemcheckpoint;第12步-删除第6步中创建的触发器SQL>DROPtriggercorrupt_trigger;