zoukankan      html  css  js  c++  java
  • Oracle 数据库坏块处理

     

    情形一,有RMAN备份


    1.构造坏块


    SQL> select segment_name , header_file , header_block,blocks
    2 from dba_segments where segment_name ='TESTC' and owner='SCOTT';

    SEGMENT_NA HEADER_FILE HEADER_BLOCK BLOCKS
    ---------- ----------- ------------ ----------
    TESTC          4            154         8


    [oracle@prim scripts]$ dd of=/oradata/orcl/users01.dbf bs=8192 conv=notrunc seek=155 <<EOF
    > Corrupt me!
    > EOF

    dd of=/oradata/orcl/users01.dbf bs=8192 conv=notrunc seek=157 <<EOF
    Corrupt me!
    0+1 records in
    0+1 records out
    12 bytes (12 B) copied, 0.0145481 s, 0.8 kB/s
    [oracle@prim scripts]$
    [oracle@prim scripts]$ dd of=/oradata/orcl/users01.dbf bs=8192 conv=notrunc seek=157 <<EOF
    > Corrupt me!
    > EOF
    0+1 records in
    0+1 records out
    12 bytes (12 B) copied, 0.00138089 s, 8.7 kB/s
    [oracle@prim scripts]$
    [oracle@prim scripts]$
    [oracle@prim scripts]$ dd of=/oradata/orcl/users01.dbf bs=8192 conv=notrunc seek=159 <<EOF
    > Corrupt me!
    > EOF
    0+1 records in
    0+1 records out
    12 bytes (12 B) copied, 0.00227023 s, 5.3 kB/s


    2.查询有坏块的表
    SQL> select * from scott.TESTC;
    select * from scott.TESTC
    *
    ERROR at line 1:
    ORA-01578: ORACLE data block corrupted (file # 4, block # 155)
    ORA-01110: data file 4: '/oradata/orcl/users01.dbf'


    3.RMAN 利用 DRA 修复坏块

    [oracle@prim scripts]$ rman target /

    Recovery Manager: Release 11.2.0.4.0 - Production on Thu Jul 2 11:21:04 2020

    Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.

    connected to target database: ORCL (DBID=1570665551)

    RMAN> validate datafile 4;

    Starting validate at 02-JUL-20
    using target database control file instead of recovery catalog
    allocated channel: ORA_DISK_1
    channel ORA_DISK_1: SID=24 device type=DISK
    allocated channel: ORA_DISK_2
    channel ORA_DISK_2: SID=400 device type=DISK
    allocated channel: ORA_DISK_3
    channel ORA_DISK_3: SID=25 device type=DISK
    allocated channel: ORA_DISK_4
    channel ORA_DISK_4: SID=405 device type=DISK
    channel ORA_DISK_1: starting validation of datafile
    channel ORA_DISK_1: specifying datafile(s) for validation
    input datafile file number=00004 name=/oradata/orcl/users01.dbf
    channel ORA_DISK_1: validation complete, elapsed time: 00:00:07
    List of Datafiles
    =================
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    4 FAILED 0 37031 46597 2127979
    File Name: /oradata/orcl/users01.dbf
    Block Type Blocks Failing Blocks Processed
    ---------- -------------- ----------------
    Data 0 5819
    Index 0 912
    Other 3 2798

    validate found one or more corrupt blocks
    See trace file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_27968.trc for details
    Finished validate at 02-JUL-20

    RMAN> list failure;

    List of Database Failures
    =========================

    Failure ID Priority Status Time Detected Summary
    ---------- -------- --------- ------------- -------
    622 HIGH OPEN 02-JUL-20 Datafile 4: '/oradata/orcl/users01.dbf' contains one or more corrupt blocks


    RMAN> advise failure;

    List of Database Failures
    =========================

    Failure ID Priority Status Time Detected Summary
    ---------- -------- --------- ------------- -------
    622 HIGH OPEN 02-JUL-20 Datafile 4: '/oradata/orcl/users01.dbf' contains one or more corrupt blocks

    analyzing automatic repair options; this may take some time
    using channel ORA_DISK_1
    using channel ORA_DISK_2
    using channel ORA_DISK_3
    using channel ORA_DISK_4
    analyzing automatic repair options complete

    Mandatory Manual Actions
    ========================
    no manual actions available

    Optional Manual Actions
    =======================
    1. Shut down, mount the database and try flush redo using ALTER SYSTEM FLUSH REDO TO 'standby name' command. Then perform a Data Guard role change (failover). Available standbys: orcl_std.

    Automated Repair Options
    ========================
    Option Repair Description
    ------ ------------------
    1 Recover multiple corrupt blocks in datafile 4
    Strategy: The repair includes complete media recovery with no data loss
    Repair script: /u01/app/oracle/diag/rdbms/orcl/orcl/hm/reco_2285196485.hm

    RMAN> repair failure;

    Strategy: The repair includes complete media recovery with no data loss
    Repair script: /u01/app/oracle/diag/rdbms/orcl/orcl/hm/reco_2285196485.hm

    contents of repair script:
    # block media recovery for multiple blocks
    recover datafile 4 block 155, 157, 159;

    Do you really want to execute the above repair (enter YES or NO)? yes
    executing repair script

    Starting recover at 02-JUL-20
    using channel ORA_DISK_1
    using channel ORA_DISK_2
    using channel ORA_DISK_3
    using channel ORA_DISK_4
    searching flashback logs for block images until SCN 2123598
    finished flashback log search, restored 3 blocks

    starting media recovery
    media recovery complete, elapsed time: 00:00:01

    Finished recover at 02-JUL-20
    repair failure complete

    4.验证坏块修复后的结果:

    RMAN> validate datafile 4;

    Starting validate at 02-JUL-20
    using channel ORA_DISK_1
    using channel ORA_DISK_2
    using channel ORA_DISK_3
    using channel ORA_DISK_4
    channel ORA_DISK_1: starting validation of datafile
    channel ORA_DISK_1: specifying datafile(s) for validation
    input datafile file number=00004 name=/oradata/orcl/users01.dbf
    channel ORA_DISK_1: validation complete, elapsed time: 00:00:01
    List of Datafiles
    =================
    File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
    ---- ------ -------------- ------------ --------------- ----------
    4 OK 0 37031 46597 2128902
    File Name: /oradata/orcl/users01.dbf
    Block Type Blocks Failing Blocks Processed
    ---------- -------------- ----------------
    Data        0        5822
    Index        0        912
    Other        0        2795

    Finished validate at 02-JUL-20

     

    情形二,无任何备份

     

    使用 DBMS_REPAIR 修复(跳过)坏块
     
     
    create table testc(
    col1 number primary key,
    col2 varchar2(20),
    col3 number(11));
     
    insert into testc values(1,'AAAAAA',13012345678);
    insert into testc values(2,'BBBBBB',13112345678);
    insert into testc values(3,'CCCCCC',13212345678);
     
     
     
     
    col SEGMENT_NAME for a10
    select segment_name , header_file , header_block,blocks
    from dba_segments where segment_name ='TESTC' and owner='SCOTT';
     
    SEGMENT_NA HEADER_FILE HEADER_BLOCK     BLOCKS
    ---------- ----------- ------------ ----------
    TESTC                4          154          8
     
    dd of=/oradata/orcl/users01.dbf bs=8192 conv=notrunc seek=155 <<EOF
    Corrupt me!
    EOF
     
    dd of=/oradata/orcl/users01.dbf bs=8192 conv=notrunc seek=157 <<EOF
    Corrupt me!
    EOF
     
     
    dd of=/oradata/orcl/users01.dbf bs=8192 conv=notrunc seek=159 <<EOF
    Corrupt me!
    EOF
     
    alter system flush buffer_cache;
     
     
    select * from scott.TESTC;
     
    SQL> select * from scott.TESTC;
    select * from scott.TESTC
                        *
    ERROR at line 1:
    ORA-01578: ORACLE data block corrupted (file # 4, block # 155)
    ORA-01110: data file 4: '/oradata/orcl/users01.dbf'
     
     
    4、使用DBMS_REPAIR修复坏块
     
     
    step a 创建修复表对象
     
    drop table REPAIR_TABLE purge;
    begin
    -- Create repair table
    dbms_repair.admin_tables (
    table_name => 'REPAIR_TABLE',
    table_type => dbms_repair.repair_table,
    action => dbms_repair.create_action,
    tablespace => 'USERS');
    end;
    /
     
    select owner, object_name, object_type
    from dba_objects
    where object_name like '%REPAIR_TABLE';
     
    OWNER    OBJECT_NAME          OBJECT_TYPE
    -------- -------------------- --------------------
    SYS      DBA_REPAIR_TABLE     VIEW
    SYS      REPAIR_TABLE         TABLE
     
     
    --使用DBMS_REPAIR.ADMIN_TABLES过程创建一个表对象,用于记录在表块损坏后那些孤立索引,也就是指向坏块的那些索引
     
    -- Orphan Key Table
     
    drop table ORPHAN_KEY_TABLE purge;
     
    begin
    -- Create orphan key table
    dbms_repair.admin_tables (
    table_type => dbms_repair.orphan_table,
    action => dbms_repair.create_action,
    tablespace => 'USERS'); -- default TS of SYS if not specified
    end;
    /
     
    col OBJECT_NAME for a30
    col OBJECT_TYPE for a25
    select owner, object_name, object_type
    from dba_objects
    where object_name like '%ORPHAN_KEY_TABLE';
     
    OWNER      OBJECT_NAME          OBJECT_TYPE
    ---------- -------------------- --------------------
    SYS        ORPHAN_KEY_TABLE     TABLE
    SYS        DBA_ORPHAN_KEY_TABLE VIEW
     
     
    Step b 校验受损的对象
    --使用DBMS_REPAIR.CHECK_OBJECT来检测对象上受损的情形,并返回受损块数
     
    set serveroutput on
    declare
    rpr_count int;
    begin
    rpr_count := 0;
    dbms_repair.check_object (
    schema_name => 'SCOTT',
    object_name => 'TESTC',
    repair_table_name => 'REPAIR_TABLE',
    corrupt_count => rpr_count);
    dbms_output.put_line('repair count: ' || to_char(rpr_count));
    end;
    /
     
    repair count: 3
     
    --下面我们可以从repair_table查询到受损的块
    --从下面的查询中可以看出列marked_corrupt全部为true,表明我们在CHECK_OBJECT已经标注了坏块
     
    SQL> desc repair_table
    Name                                      Null?    Type
    ----------------------------------------- -------- ----------------------------
    OBJECT_ID                                 NOT NULL NUMBER
    TABLESPACE_ID                             NOT NULL NUMBER
    RELATIVE_FILE_ID                          NOT NULL NUMBER
    BLOCK_ID                                  NOT NULL NUMBER
    CORRUPT_TYPE                              NOT NULL NUMBER
    SCHEMA_NAME                               NOT NULL VARCHAR2(30)
    OBJECT_NAME                               NOT NULL VARCHAR2(30)
    BASEOBJECT_NAME                                    VARCHAR2(30)
    PARTITION_NAME                                     VARCHAR2(30)
    CORRUPT_DESCRIPTION                                VARCHAR2(2000)
    REPAIR_DESCRIPTION                                 VARCHAR2(200)
    MARKED_CORRUPT                            NOT NULL VARCHAR2(10)
    CHECK_TIMESTAMP                           NOT NULL DATE
    FIX_TIMESTAMP                                      DATE
    REFORMAT_TIMESTAMP                                 DATE
    set lines 120
    col OBJECT_NAME for a12
    col REPAIR_DESCRIPTION for a30
    col CORRUPT_DESCRIPTION for a25
    select object_name, block_id, corrupt_type, marked_corrupt,
    corrupt_description, repair_description
    from repair_table;
    OBJECT_NAME    BLOCK_ID CORRUPT_TYPE MARKED_COR CORRUPT_DESCRIPTION       REPAIR_DESCRIPTION
    ------------ ---------- ------------ ---------- ------------------------- ------------------------------
    TESTC               155         6148 TRUE                                 mark block software corrupt
    TESTC               157         6148 TRUE                                 mark block software corrupt
    TESTC               159         6148 TRUE                                 mark block software corrupt
     
     
    Step c 标记坏块
    --过程FIX_CORRUPT_BLOCKS用于标记坏块,在这个演示中,我们在CHECK_OBJECT已经被标注了,如没有执行下面的过程
    --由于上一步已经标注,所以下面的输出为0
     
     
    SET SERVEROUTPUT ON
    declare
    fix_count int;
    begin
    fix_count := 0;
    dbms_repair.fix_corrupt_blocks (
    schema_name => 'SCOTT',
    object_name => 'TESTC',
    object_type => dbms_repair.table_object,
    repair_table_name => 'REPAIR_TABLE',
    fix_count => fix_count);
    dbms_output.put_line('fix count: ' || to_char(fix_count));
    end;
    /
     
    num fix: 0
     
     
     
    select object_name, block_id, marked_corrupt from repair_table;
     
    OBJECT_NAME    BLOCK_ID MARKED_COR
    ------------ ---------- ----------
    TESTC               155 TRUE
    TESTC               157 TRUE
    TESTC               159 TRUE
     
     
    select * from scott.TESTC;
     
    select * from scott.TESTC
                        *
    ERROR at line 1:
    ORA-01578: ORACLE data block corrupted (file # 4, block # 147)
    ORA-01110: data file 4: '/oradata/orcl/users01.dbf'
     
     
     
    DBMS_REPAIR.DUMP_ORPHAN_KEYS
    ==============================
     
    DUMP_ORPHAN_KEYS reports on index entries that point to rows in corrupt data blocks.
     
    SQL> select index_name from dba_indexes where table_name in (select distinct object_name from repair_table);
     
    INDEX_NAME
    ------------------------------
    SYS_C0011945
     
     
     
     
     
    Step d DUMP孤立的索引键值
    --使用DUMP_ORPHAN_KEYS过程将那些指向坏块的索引键值填充到ORPHAN_KEY_TABLE
     
     
    set serveroutput on
    declare
    key_count int;
    begin
    key_count := 0;
    dbms_repair.dump_orphan_keys (
    schema_name => 'SCOTT',
    object_name => 'SYS_C0011945',
    object_type => dbms_repair.index_object,
    repair_table_name => 'REPAIR_TABLE',
    orphan_table_name => 'ORPHAN_KEY_TABLE',
    key_count => key_count);
    dbms_output.put_line('orphan key count: ' || to_char(key_count));
    end;
    /
     
    orphan key count: 3
     
     
     
     
    desc orphan_key_table
    Name                      Null?    Type
    ------------------------- -------- ----------------------------
    SCHEMA_NAME               NOT NULL VARCHAR2(30)
    INDEX_NAME                NOT NULL VARCHAR2(30)
    IPART_NAME                         VARCHAR2(30)
    INDEX_ID                  NOT NULL NUMBER
    TABLE_NAME                NOT NULL VARCHAR2(30)
    PART_NAME                          VARCHAR2(30)
    TABLE_ID                  NOT NULL NUMBER
    KEYROWID                  NOT NULL ROWID
    KEY                       NOT NULL ROWID
    DUMP_TIMESTAMP            NOT NULL DATE
     
     
    select index_name, count(*) from orphan_key_table group by index_name;
     
    INDEX_NAME                       COUNT(*)
    ------------------------------ ----------
    SYS_C0011945                            3
     
     
     
     
    Step e 跳过坏块
     
    --使用SKIP_CORRUPT_BLOCKS来告知Oracle哪些坏块需要被跳过
    begin
    dbms_repair.skip_corrupt_blocks (
    schema_name => 'SCOTT',
    object_name => 'TESTC',
    object_type => dbms_repair.table_object,
    flags => dbms_repair.skip_flag);
    end;
    /
     
    select table_name, skip_corrupt from dba_tables where table_name = 'TESTC';
     
    TABLE_NAME                     SKIP_COR
    ------------------------------ --------
    TESTC                            ENABLED
     
     
    SQL> select * from scott.TESTC;
     
    no rows selected  
     
     
    SQL> insert into scott.testc values (1,'aaaaaa',13111111111);
    insert into scott.testc values (1,'aaaaaa',13111111111)
    *
    ERROR at line 1:
    ORA-00001: unique constraint (SCOTT.SYS_C0011945) violated
     
     
     
    SQL> select * from scott.testc where col1=1;
     
    no rows selected
     
       
    REBUILD_FREELISTS rebuilds freelists for the specified object.      
     
    begin
    dbms_repair.rebuild_freelists (
    schema_name => 'SCOTT',
    object_name => 'TESTC',
    object_type => dbms_repair.table_object);
    end;
    /    
    ---此操作报错
     
    begin
    *
    ERROR at line 1:
    ORA-10614: Operation not allowed on this segment
    ORA-06512: at "SYS.DBMS_REPAIR", line 401
    ORA-06512: at line 2
     
     
    --由于索引键上存在孤立索引,因此我们重建索引:
     
    alter index scott.SYS_C0011945 rebuild online;
     
     
    再次插入数据,没有了主键冲突
     
    SQL> insert into scott.testc values (1,'aaaaaa',13111111111);
     
    1 row created.
     
    SQL> commit ;
     
    Commit complete.
     
     
    SQL> select * from scott.testc ;
     
          COL1 COL2                       COL3
    ---------- -------------------- ----------
             1 aaaaaa               1.3111E+10
  • 相关阅读:
    Java
    Linux
    Linux
    Linux
    Java
    Ansible
    Ansible
    Java
    ACM&OI 基础数论算法专题
    题解 P4781 【【模板】拉格朗日插值】
  • 原文地址:https://www.cnblogs.com/sky2088/p/13225110.html
Copyright © 2011-2022 走看看