• oracle坏块修复处理#ocp试验#


    坏块分为物理坏块和逻辑坏块,前者是硬件问题产生,后者是oracle内部数据有问题,本次试验针对后者。


    需要归档模式,步骤

    1 create tablespace test 1m (table t1, insert)
    2 RMAN>backup tablespace test
    3 模拟坏块
    4 DBV
    5 ANALYZE TABLE
    6 RMAN BACKUP
    7 EXP
    8 DBMS_REPAIR
    9 BLOCKRECOVER

    1,sys用户下创建表空间

    SYS@jsce>create tablespace tbs1 datafile 'e:\tbs1.dbf' size 1m; --大小1M,容易填满(现在突然有疑惑:为什么要填满,才能制造坏块?)

    在tbs1中创建表tb1,数据来源是scott.emp

    SYS@jsce>create table tb1 tablespace tbs1 as select * from scott.emp;

    双倍递增插入表tb1,来源也是其自己

    SYS@jsce>insert into tb1 select * from tb1; --这里是select出来的东西插入到表,没有关键字values

    已创建15行。

    SYS@jsce>insert into tb1 select * from tb1;

    已创建30行。

    SYS@jsce>insert into tb1 select * from tb1;

    已创建60行。

    在插满之后,不要忘记commit,否则oracle不能shutdown,最后确认一下插入的数据量“15360”

    》给表增加索引,后面查询有坏块之后,坏块带来损失的数据ORPHAN_TABLE;

    SYS@jsce>create index i1 on tb1(ename);

    索引已创建。

    SYS@jsce>alter system checkpoint; --这一步是将插入的数据作检查点写入数据文件,下一步就要通过ultraedit修改数据文件,制造坏块。

    系统已更改。

    备注:如果表字段没有设置not null必输项,并且表字段很多,那么可以指定字段来插入一部分,比如emp表

    insert into emp(empno,ename,sal) values(22,'sumsen',8900);

    2,rman备份表空间tbs1,得到优良备份(下面还原使用)

    RMAN> backup tablespace tbs1 tag=ok;--增加tag

    3,shutdown之后,通过ultraedit修改数据文件 --修改的时候不要开头部,那里是数据文件名称,有可能导致oracle启动失败

    修改,保存之后,数据文件目录会多出一个TBS1.DBF.bak,说明修改过了,不知道为何

    启动oracle再次查询报错,坏块产生 --这里的select 是遇到第一个坏块就报错,因此如果有多个坏块,也是报出一个错误信息,需要用下面的REPAIR_TABLE查询所有的坏块。

    4,用dbv检测

    这里仅仅给出坏块数,没有给出坏块号和文件号

    5,使用 ANALYZE TABLE

    SYS@jsce>analyze table tb1 validate structure;

    6,rman的备份和exp导出有坏块的表空间

    exp导出sys下的

    E:\Documents and Settings\xs>exp userid='sys/sys as sysdba' file=e:\exptbs1.dmp tablespaces=tbs1

    导出表空间没有问题 

    导出表有坏块报错

    rman提示超过坏块限制

     

    通过设置坏块最大数来继续备份

    RMAN> run{set maxcorrupt for datafile 3 to 10;backup tablespace tbs1 tag=bad;} 要写在一块,让rman知道是一个事务

    因为最大坏块设置为了10,tbs1有两个坏块,可以通过备份

    7,包DBMS_REPAIR

    exec DBMS_REPAIR.ADMIN_TABLES('REPAIR_TABLE',1,1,'USERS');--表数据

    exec DBMS_REPAIR.ADMIN_TABLES('ORPHAN_TABLE',2,1,'USERS');--索引数据

    检查坏块:dbms_repair.check_object , 这里的schema_name是用户,比如我在sys下建立的表空间,这里就是sys,

    object_name是表不是表空间(查询的时候报错也是通过select * from tb1)

    declare
    cc number;
    begin
    dbms_repair.check_object(schema_name => 'SYS',object_name => 'TB1',corrupt_count => cc); 
    dbms_output.put_line(a => to_char(cc)); --这里a=>不明不白,可以去掉
    end;


    看到这里用dbms_repair.check,检查的结果corrupt_count=2,有2个块损坏,和dbv的结果一致。
    check完之后,在我们刚在创建的REPAIR_TABLE中查看块损坏详细信息:
     

    SELECT object_name,
           relative_file_id,
           block_id,
           marked_corrupt,
           corrupt_description,
           repair_description,
           CHECK_TIMESTAMP
      from repair_table;

    得到4个结果,不过就两个块(33,69),只是时间不一样,不解?

    我们注意看MARKED_CORRUPT的值,这里经过check_object后,已经标识为TRUE了。(

    》使用包的skip_corrupt_blocks过程来跳过坏块

    exec dbms_repair.skip_corrupt_blocks(schema_name => 'SYS',object_name => 'TB1',flags => 1);

    损失了15360-15020=340 条数据

    》处理index上的无效键值;dump_orphan_keys 

    declare
    cc number;
    begin
    dbms_repair.dump_orphan_keys(schema_name => 'SYS',object_name => 'I1',object_type => 2,
    repair_table_name => 'REPAIR_TABLE',orphan_table_name => 'ORPHAN_TABLE',key_count => CC);
    end;

    之后查询数据,我们根据这个结果来考虑是否需要rebuild index(?)

    和上面的损失数目一样

    9  BLOCKRECOVER 恢复坏块--前提是坏块事先有备份

    RMAN> blockrecover from tag=ok datafile 3 block 33,69;--必须要指定坏块号

    之后查询tb1,恢复

    这时候dbv检测也为0

    18:10 更新,使用oracle内部事件

    再次破坏了数据文件,可是查询时候仍然不报错,想到是前面执行了让oracle跳过坏块的过程

    exec dbms_repair.skip_corrupt_blocks(schema_name => 'SYS',object_name => 'TB1',flags => 1);

    直接将flag=>2

    SELECT tablespace_name, segment_type, owner, segment_name
    FROM dba_extents
    WHERE file_id = 3
    and 35 between block_id AND block_id + blocks - 1 --这里 35 between不懂

    ALTER SYSTEM SET EVENTS='10231 trace name context forever,level 10' ;

    之后

    SQL> ALTER SYSTEM SET EVENTS='10231 trace name context off' ;

    系统已更改。

    删除表空间

    SYS@jsce>drop tablespace tbs1 including contents and datafiles; --表空间物理文件也被删除

    之后导入

    演示省略。

  • 相关阅读:
    C#中的代理(Delegate)
    动态栈C语言
    AMS算法
    动态队列实现C语言
    带头结点的循环单链表C语言
    静态栈C语言
    不带头结点的单链表C语言实现
    带头结点的双向循环链表C语言
    带头节点的单链表C语言实现
    使用函数指针模拟C++多态
  • 原文地址:https://www.cnblogs.com/sumsen/p/2868740.html
Copyright © 2020-2023  润新知