技术开发 频道

如何处理Oracle数据库中的坏块问题

    4. 具体处理方法的介绍

    ? 恢复数据文件方法:

    如果数据库是归档方式下,并且有完整的物理备份,就可以使用此方法来恢复。

    步骤如下:

    1) 先offline受影响的数据文件,执行以下的语句:

ALTER DATABASE DATAFILE 'name_file' OFFLINE;

    2) 保留有坏块的数据文件,然后拷贝备份的数据文件。如果恢复的数据文件要求路径不同,执行以下的语句:

ALTER DATABASE RENAME FILE 'old_name' TO 'new_name';

    3) 恢复数据文件,执行以下语句:   

RECOVER DATAFILE 'name_of_file';

    4) Online恢复后的数据文件,执行以下的语句:

ALTER DATABASE DATAFILE 'name_of_file' ONLINE;

    ? 只恢复坏的block(9i以上版本可用)

    使用这种方法要求数据库版本是9.2.0以上,要求配置了Rman的catalog数据库,数据库为归档方式,并且有完整的物理备份。

    步骤如下:

    使用RMAN的BLOCKRECOVER命令 :

    Rman>run{blockrecover datafile 5 block 11,16;}

    也可以强制使用某个SCN号之前的备份,恢复数据块。

    Rman>run{blockrecover datafile 5 block 11,16 restore until sequence 8505;}

    ? 通过ROWID RANGE SCAN 保存数据

    1) 先取得坏块中ROW ID的最小值,执行以下的语句:

SELECT dbms_rowid.rowid_create(1,<OBJ_ID>,<RFN>,<BL>,0) from DUAL;

    2)取得坏块中的ROW ID的最大值,执行以下的语句:

SELECT dbms_rowid.rowid_create(1,<OBJ_ID>,<RFN>,<BL>+1,0) from DUAL;

    3)建议一个临时表存储那些没有坏块的数据,执行以下的语句:

CREATE TABLE salvage_table AS SELECT * FROM corrupt_tab Where 1=2;

    4)保存那些不存在坏块的数据到临时表中,执行以下的语句:

 INSERT INTO salvage_table SELECT/*+ ROWID(A) */* 
FROM <owner.tablename> A WHERE rowid < '<low_rid>'
INSERT INTO salvage_table SELECT/*+ ROWID(A) */*
FROM <owner.tablename> A WHERE rowid >= '<hi_rid>';

   5) 根据临时表中的数据重建表,重建表上的索引,限制。

    ? 使用10231诊断事件,在做全表扫描的时候跳过坏块

    可以在session级别设定:   

ALTER SESSION SET EVENTS '10231 TRACE NAME CONTEXT FOREVER, LEVEL 10';

    也可以在数据库级别上设定,在初始化参数中加入:event="10231 trace name context forever, level 10" ,然后重启数据库。

   然后从存在坏块的表中取出不存在坏块的数据,执行以下的语句:

CREATE TABLE salvage_emp AS SELECT * FROM corrupt_table;

   最后rename生成的corrupt_table为原来表的名字,并重建表上的索引和限制。

   ? 使用dbms_repair包进行恢复

   使用dbms_repair标记有坏块的表,在做全表扫描的时候跳过坏块,执行以下的语句:

Execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('<schema>','<tablename>');

    然后使用exp工具或者createtable as select的方法取出没有坏块数据,然后重建表,表上的索引和限制。

    五:坏块的预先发现的方法

    1.如果要检测数据库中所有的表,可以利用exp工具导出整个数据库可以检测坏块。不过这个工具有一些缺陷,对以下情况的坏块是检测不出来的:

    ? HWM以上的坏块是不会发现的
    ? 索引中存在的坏块是不会发现的
    ? 数据字典中的坏块是不会发现的

    2.如果只是对数据库中比较重要的表进行坏块检查,可以使用ANALYZE TABLE tablename VALIDATE STRUCTURE CASCADE 的方法来检测坏块,它执行坏块的检查,但是不会标记坏块为corrupt,检测的结果保存在USER_DUMP_DEST目录下的用户trace文件中。

    3.使用Oracle的专门工具dbv来检查坏块,具体的语法如下:

    FILE 要验证的文件 (无)
    START 起始块 (文件的第一个块)
    END 结束块 (文件的最后一个块)
    BLOCKSIZE 逻辑块大小 (2048)
    LOGFILE 输出日志 (无)
    FEEDBACK 显示进度 (0)
    PARFILE 参数文件 (无)
    USERID 用户名/口令 (无)
    SEGMENT_ID 段 ID (tsn.relfile.block) (无)

    例如:

    Dbv file=system01.dbf blocksize=8192
    DBVERIFY: Release 9.2.0.5.0 - Production on 星期六 11月 27 15:29:13 2004
    Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
    DBVERIFY - 验证正在开始 : FILE = system01.dbf
    DBVERIFY - 验证完成
    检查的页总数 :32000
    处理的页总数(数据):13261
    失败的页总数(数据):0
    处理的页总数(索引):2184
    失败的页总数(索引):0
    处理的页总数(其它):1369
    处理的总页数 (段) : 0
    失败的总页数 (段) : 0
    空的页总数 :15186
    标记为损坏的总页数:0
    汇入的页总数 :0

    注:因为dbv要求file后面跟的必须是一个文件扩展名,所以如果用裸设备存储的,就必须使用ln链接裸设备到一个文件,然后再用dbv对这个链接文件进行检查。

0
相关文章