iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >恢复数据块坏块
  • 194
分享到

恢复数据块坏块

2024-04-02 19:04:59 194人浏览 独家记忆
摘要

2014.7.22研究恢复数据库坏块:oracle调用标准C的系统函数,对数据块进行读写操作,因此,坏块是有可能由以下几种原因产生:硬件的I/O错误操作系统的I/O错误或缓冲问题内存或paging问题磁盘修

2014.7.22研究恢复数据库坏块:

oracle调用标准C的系统函数,对数据块进行读写操作,因此,坏块是有可能由以下几种原因产生:

硬件的I/O错误

操作系统的I/O错误或缓冲问题

内存或paging问题

磁盘修复工具

一个数据文件的一部分正在被覆盖

Oracle试图访问一个未被格式化的系统块失败

数据文件部分溢出

Oracle或者操作系统的bug

 

遇到“ORA-01578:ORACLE data block corrupted”错误

处理方法:1.rman的recover命令可以在数据库保持open状态下只恢复受损的数据块

        2.如果没有备份,万不得已之下也可以采用DBMS_REPaiR包的存储过程将受损坏块隔离,同时尽可能地挽救部分数据。

rman backup命令也是检查坏数据块的好工具  一旦读取ORA-19566  即可有问题

此时可用backup validate tablespace user观察详细的信息,可查看到坏块数与跟踪文件

grep‘corrupt’/u01/app/oracle/diag/rdbms/br/br/trace/**.trc

恢复数据块:rman》recover datafile 5 block 203;

批量恢复受损的数据块:recover corruption list;

数据块坏块一号坏块,需要做:

run{

sql 'alter database datafile 5 offline';

 restore datafile 5;

 recover datafile 5;

sql'alter database datafile 5 online'

}

 

 

  1. 使用exp/imp恢复
    在这种情况下肯定会造成数据的丢失,在这种情况下应采取将数据导出然后重建表再进行导入的方法,来尽量恢复损坏数据块中的数据,但是在有坏块的情况下是不允许导出的,如下命令:Exp test/test file=t.dmp tables=t;
    导出命令在执行中会报ORA-01578错误,在这错误提示中会提示那个文件号的文件以及这个文件中的哪个块被损坏,如:ORA—01578:ORACLE 数据块损坏(文件号 4,块号 35)
    针对以上的提示首先查询那些对象被损坏:
    Select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=4 and 35 between block_id and block_id+blocks-1;
    如果被损坏的块是索引,通常可以通过索引重建来解决,如果损坏的是数据(segment_type为table),那么通过设置如下内部事件使得Exp操作跳过坏块。
    Alter session set events=’10231 trace name context forever,level 10’;
    然后重新执行导出命令,导出相关的表,然后执行Drop Table命令删除相关表,之后重建表最后导入数据。
    使用DBMS_REPAIR恢复
    用DBMS_REPAIR当然也会丢失数据。这里不做详细的介绍,有兴趣的可以查看oracle的在线文

     


  2. 3、使用dbms_repair包进行坏块处理
    1)首先建立repair_table,用于存放dbms_repair.check_object检测出来的坏块信息
    SQL> declare
    2begin
    3Dbms_repair.admin_tables
    4(table_name => 'REPAIR_TABLE',--表名
    5table_type => dbms_repair.repair_table,
    6action => dbms_repair.create_action,
    7tablespace => 'USERS');--用于指定该表存放的表空间
    8end;
    9/
    PL/SQL 过程已成功完成。
    SQL> col owner fORMat a10
    SQL> col object_name format a20
    SQL> col object_type format a20
    SQL> select owner, object_name, object_type
    2from dba_objects
    3where object_name like '%REPAIR_TABLE';

    OWNEROBJECT_NAMEOBJECT_TYPE
    ---------- -------------------- --------------------
    SYSREPAIR_TABLETABLE
    SYSDBA_REPAIR_TABLEVIEW
    Oracle自动创建了一个DBA_REPAIR_TABLE视图。
    2)使用dbms_repair.check_object进行坏块检测
    SQL> set serveroutput on size 100000;
    SQL> declare
    2rpr_count int;
    3begin
    4rpr_count := 0;
    5dbms_repair.check_object(
    6schema_name => 'SYS',--指定对象模式,也就是对象的所有者
    7object_name => 'TEST',--指定对象名,也就是表名
    8repair_table_name => 'REPAIR_TABLE',
    9corrupt_count => rpr_count);
    10dbms_output.put_line('repair block count: '
    11||to_char(rpr_count));
    12end;
    13/
    repair block count: 4
    PL/SQL 过程已成功完成。
    SQL> select object_name, block_id, corrupt_type, marked_corrupt,
    2corrupt_description, repair_description
    3from repair_table;

    OBJECT_NAMEBLOCK_ID CORRUPT_TYPE MARKED_COR
    -------------------- ---------- ------------ ----------
    CORRUPT_DESCRIPTION
    -------------------------------------------------------------------------------
    REPAIR_DESCRIPTION
    -------------------------------------------------------------------------------
    TEST196148 TRUE
    mark block software corrupt
    TEST206148 TRUE
    mark block software corrupt
    TEST236148 TRUE
    mark block software corrupt
    TEST316148 TRUE
    mark block software corrupt
    通过运行dbms_repair.check_object,将坏块信息存放到了repair_table表中,其中有个字段marked_corrupt,用于标识该块是否被标识为坏块,当被标识为true时,即该块被标识为坏块。其中这一步跟oracle文档中的描述有点进入,根据oracle文档,当执行完dbms_repair.check_object时,并不会进行坏块标识,也就是marked_corrupt列的值应该为false,而只有当执行dbms_repair.fix_corrupt_blocks过程后才会进行坏块标识。
    3)使用dbms_repair.fix_corrupt_blocks进行坏块标识
    SQL> declare
    2fix_block_count int;
    3begin
    4fix_block_count := 0;
    5dbms_repair.fix_corrupt_blocks (
    6schema_name => 'SYS',
    7object_name => 'TEST',
    8object_type => dbms_repair.table_object,
    9repair_table_name => 'REPAIR_TABLE',
    10fix_count => fix_block_count);
    11dbms_output.put_line('fix blocks count: ' ||
    12to_char(fix_block_count));
    13end;
    14/
    fix blocks count: 0
    PL/SQL 过程已成功完成。
    我们可以见到到fix blocks count=0,即在上一步进行check_object时已经进行了坏块标识了,这一步其实可以省略。(不过没有测试过!)
    SQL> select count(*) from test;
    select count(*) from test
    *
    第 1 行出现错误:
    ORA-01578: ORACLE 数据块损坏 (文件号 7, 块号 19)
    ORA-01110: 数据文件 7: 'G:\ORACLE\PRODUCT\10.2.0\ORADATA\ORA10G\TEST01.DBF'
    此时进行查询仍然报错,因为我们只是将坏块进行了标识,当进行全表扫描的时候,仍然会查询到坏块而报错。
    4)使用dbms_repair.dump_orphan_keys过程来保存坏块的索引键值,然后再执行skip_corrupt_blocks过程之后,我们才能重建索引,不然重建索引时新的索引仍然会引用坏块。首先要建立ORPHAN_KEY_TABLE,此表就是用来存放坏块的索引键值。
    SQL> declare
    2begin
    3dbms_repair.admin_tables
    4(table_name => 'ORPHAN_KEY_TABLE',
    5table_type => dbms_repair.orphan_table,
    6action => dbms_repair.create_action,
    7tablespace => 'USERS');
    8end;
    9/

    PL/SQL 过程已成功完成。
    然后执行过程dbms_repair.dump_orphan_keys将坏块键值存放到上面所创建的表中:
    SQL> declare
    2orph_count int;
    3begin
    4orph_count:= 0;
    5dbms_repair.dump_orphan_keys (
    6schema_name => 'SYS',
    7object_name => 'ID_INX',--索引的名字
    8object_type => dbms_repair.index_object,
    9repair_table_name => 'REPAIR_TABLE',--从这个表中获得坏块的信息
    10orphan_table_name => 'ORPHAN_KEY_TABLE',
    11key_count => orph_count);
    12dbms_output.put_line('orphan-index entries: ' || to_char(orph_count));
    13end;
    14/
    orphan-index entries: 491

    PL/SQL 过程已成功完成。

    SQL> declare
    2orph_count int;
    3begin
    4orph_count:= 0;
    5dbms_repair.dump_orphan_keys (
    6schema_name => 'SYS',
    7object_name => 'NAME_INX',
    8object_type => dbms_repair.index_object,
    9repair_table_name => 'REPAIR_TABLE',
    10orphan_table_name => 'ORPHAN_KEY_TABLE',
    11key_count => orph_count);
    12dbms_output.put_line('orphan-index entries: ' || to_char(orph_count));
    13end;
    14/
    orphan-index entries: 491
    PL/SQL 过程已成功完成。
    对每个索引都要进行dump_orphan_keys。
    SQL> select index_name, count(*) from orphan_key_table
    2group by index_name;

    INDEX_NAMECOUNT(*)
    ------------------------------ ----------
    ID_INX491
    NAME_INX491
    5)使用skip_corrupt_blocks,使查询或者DML时跳过坏块
    SQL> declare
    2begin
    3dbms_repair.skip_corrupt_blocks (
    4schema_name => 'SYS',
    5object_name => 'TEST',
    6object_type => dbms_repair.table_object,
    7flags => dbms_repair.skip_flag);
    8end;
    9/

    PL/SQL 过程已成功完成。

    SQL> select table_name, skip_corrupt from dba_tables
    2where table_name = 'TEST';

    TABLE_NAMESKIP_COR
    ------------------------------ --------
    TESTENABLED
    6)使用dbms_repair.rebuild_freelists重建freelists,使得该块不再被放到freelists,当中,也就是该块将不会再被使用。
    SQL> declare
    2begin
    3dbms_repair.rebuild_freelists (
    4schema_name => 'SYS',
    5object_name => 'TEST',
    6object_type => dbms_repair.table_object);
    7end;
    8/
    declare
    *
    第 1 行出现错误:
    ORA-10614: Operation not allowed on this segment
    ORA-06512: 在 "SYS.DBMS_REPAIR", line 400
    ORA-06512: 在 line 3
    不过我们可以看到,对于SYS用户下面的对象好像不能进行此操作。
    4、重建索引
    SQL> select count(id) from test;
    COUNT(ID)
    ----------
    19998
    SQL> select count(name) from test;
    COUNT(NAME)
    -----------
    19998
    SQL> select count(*) from test;
    COUNT(*)
    ----------
    19507
    我们可以看到上面的三个查询,对于第1和第2个使用索引进行查询和不使用索引进行查询的结果是不一样的。下面我们使用rebuild试试。
    SQL> alter index id_inx rebuild;
    索引已更改。
    SQL> alter index name_inx rebuild;
    索引已更改。
    SQL> select count(id) from test;
    COUNT(ID)
    ----------
    19998
    SQL> select count(name) from test;
    COUNT(NAME)
    -----------
    19998
    SQL> select count(*) from test;
    COUNT(*)
    ----------
    19507
    可以是不能通过rebuild来重建索引的。只能通过DROP然后再CREATE。
    SQL> drop index id_inx;
    索引已删除。
    SQL> drop index name_inx;
    索引已删除。
    SQL> create index id_inx on test(id);
    索引已创建。
    SQL> create index name_inx on test(name);
    索引已创建。
    SQL> select count(id) from test;
    COUNT(ID)
    ----------
    19507
    SQL> select count(name) from test;

    COUNT(NAME)
    -----------
    19507
    SQL> select count(*) from test;
    COUNT(*)
    ----------
    19507
    到此该表已经可以正常使用了,但同时也丢失了一些数据,所以在使用dbms_repair进行恢复的时候要充分考虑到数据的重要性和恢复的后果。同时也应该考虑是否有其它别的恢复方法,不然贸贸然的行事最后可能得不偿失。

您可能感兴趣的文档:

--结束END--

本文标题: 恢复数据块坏块

本文链接: https://www.lsjlt.com/news/38380.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 恢复数据块坏块
    2014.7.22研究恢复数据库坏块:Oracle调用标准C的系统函数,对数据块进行读写操作,因此,坏块是有可能由以下几种原因产生:硬件的I/O错误操作系统的I/O错误或缓冲问题内存或paging问题磁盘修...
    99+
    2022-10-18
  • Oracle数据库文件坏块损坏的恢复方法
    数据恢复故障描述:打开oracle数据库报错 “system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。工程师检测数据库文件发现sysaux01.dbf有坏块,sysaux01.dbf文件损坏...
    99+
    2022-10-18
  • 基于rman的坏块恢复
    转载请注明出处 http://blog.csdn.net/guoyjoe/article/details/30965303  实验步骤如下:1、使用rman备份全库Recovery Ma...
    99+
    2022-10-18
  • RMAN深入解析之--BlockRecover恢复坏块
    RMAN深入解析之--BlockRecover恢复坏块案例环境:操作系统:RedHat EL5Oracle:  Oracle 11gR2案例描述:   通过块介质恢复(Bloc...
    99+
    2022-10-18
  • Oracle数据块损坏之10231内部事件不完全恢复
    什么是块损坏: 所谓损坏的数据块,是指块没有采用可识别的 Oracle 格式,或者其内容在内部不一致。通常情况下,损坏是由硬件故障或操作系统问题引起的。Oracle 数据库将损坏的块标识为“逻辑损坏”或“介...
    99+
    2022-10-18
  • 基于RMAN实现坏块介质恢复(blockrecover)
    http://blog.csdn.net/leshami/article/details/10500997 对于物理损坏的数据块,我们可以通过RMAN块介质恢复(BLOCK MEDIA RECOVERY)...
    99+
    2022-10-18
  • 如何进行BBED标记坏块以及修复坏块
    如何进行BBED标记坏块以及修复坏块,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 ...
    99+
    2022-10-19
  • 检测数据块损坏(Block Corruption)
    数据块的损坏分两种情况,第一种是物理性的,第二种是逻辑性的。物理性一般指数据块头部不可以访问、数据块校验值不合法。逻辑性一般是在物理性结构完整的情况下,数据的内容在含义上不正确,比如保存了不允许的字段值。 ...
    99+
    2022-10-18
  • Oracle中基于RMAN如何实现坏块介质恢复
    小编给大家分享一下Oracle中基于RMAN如何实现坏块介质恢复,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! ...
    99+
    2022-10-18
  • Oracle Rman修复逻辑坏块
    RMAN 实现数据块恢复试用Rman可以实现数据块级的数据恢复,在传统恢复手段中即某个数据文件的一个数据块被损坏,就造成整个数据文件无法试用,此时必须通过备份恢复整个数据文件。显然这样的方法会会时间较长,而...
    99+
    2022-10-18
  • oracle ora-01578 ORACLE 数据块损坏 (文件号 4, 块号 840339)
    ORA-01578是 数据块物理坏块/损坏的一种,不同于逻辑损坏/坏块,一般 会伴随ORA-1110出现,一旦ORACLE读取到存在损坏的块就会报出Caused by: java.sql.SQLExcept...
    99+
    2022-10-18
  • Oracle 11g dataguard主库坏块修复
    最理想的情况是开启redo日志实时传输,可利用备库来修复主库的坏块:查看DG模式:alter database recover managed standby&nbs...
    99+
    2022-10-18
  • Oracle 修复坏块,关掉闪回
    RMAN 修复报错:RMAN> recover datafile 2 block 410352;Starting recover at 05-OCT-15using target database c...
    99+
    2022-10-18
  • 设置10231事件并结合导入导出工具恢复坏块
    1.模拟表、及表空间 SQL> create tablespace test datafile '/u01/app/oracle/oradata/DBdb/test01.dbf' size 30m; ...
    99+
    2022-10-18
  • oracle检查数据文件是否有坏块
    通过dbv命令查看oracle数据文件是否有坏块, [oracle@jw PROD]$ **dbv file=users01.dbf** DBVERIFY: Release 11.2.0.4.0 - Pro...
    99+
    2022-10-18
  • Oracle 学习之RMAN(十三)恢复实战--数据块修复
      在很多情况下,数据库只是某个数据文件的些许数据块发生损坏。这种情况,我们当然可是使用数据库恢复或者数据文件恢复的方式来解决问题。但是有点高射炮打蚊子的感觉。幸好RMAN提供了块级别的恢复。下面...
    99+
    2022-10-18
  • oracle中ORA-01578和ORA-01110数据文件出现坏块时跳过损坏的块怎么办
    小编给大家分享一下oracle中ORA-01578和ORA-01110数据文件出现坏块时跳过损坏的块怎么办,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面...
    99+
    2022-10-18
  • 怎么恢复PostgreSQL数据文件损坏
    本篇内容介绍了“怎么恢复PostgreSQL数据文件损坏”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在数...
    99+
    2022-10-18
  • MySQL修复坏块参数innodb_force_recovery的解释是什么
    MySQL修复坏块参数innodb_force_recovery的解释是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 ...
    99+
    2022-10-18
  • Oracle中如何使用 DBMS_REPAIR 修复坏块
    这篇文章主要为大家展示了“Oracle中如何使用 DBMS_REPAIR 修复坏块”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Oracle中如何使用 DBMS...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作