2. DBMS_REPAIR 패키지를 이용한 Block Recovery★★

- oracle 8i 버전부터 등장한 block corruption을 detecting하고, repair하는 패키지. corruption block을 repair하는 게 아니라, 장애난 블록을 찾아내서 해당 block을 장애로 mark하고, 더이상 사용안하게 막아주고 해당 블록 장애 때문에 진행 안 되던 작업을 계속할 수 있도록 도와주는 역할을 한다. (즉 장애를 건너뛰는 것!)

- Table block과 Index block을 조사하여 문제가 있는 block을 수정해주는 data corruption repair 패키지를 가지고있으며 sys계정으로 작업해야 한다.

- 장애난 블록에 데이터가 있었다면 그 블록 안에 있던 내용은 전부 소실된다.

 

1)DBMS_REPAIR 패키지

- 각각 수행될 수 있으며, 결과들이 저장되는 테이블에 "DBA_"라는 접두어가 붙어서 생성된다.

 

ADMIN_TABLE 프로시저 

Block Repair을 하기 위해 필요한 관리 작업(create, drop, purge)를 제공해준다.

테이블들은 항상 SYS schema 소유로 생성된다.

이 테이블에 손상이 발생한 블록들의 리스트를 저장한다.

CHECK_OBJECT 프로시저

Table이나 Index의 block corruption을 체크하고 문제가 있는 블록은 1번에서 만든 Repair table에 기록해준다.

DUMP_ORPHAN_KEYS 프로시저

corrupted된 블록들이 테이블과 관련된 것이라면 admin_table에서 생성한 곳에 기록되지만 index와 관련있는 블록들이라면 이 테이블에 기록한다.

FIX_CORRUPT_BLOCKS 프로시저

check_object로 발견된 corrupt된 block을 mark해준다.

REBUILD_FREELISTS 프로시저

object의 freelist를 재 생성

SEGMENT_FIX_STATUS 프로시저

ASSM 기능을 사용하고 있는 bitmap index가 corrupt 되었다면 이 프로시저가 fix 해준다.

SKIP_CORRUPT_BLOCKS 프로시저

table이나 index scan할 때 기존에 mark된 corrupt block들은 확인하지 않고 건너 뛴다.

 

 

2) DBMS_REPAIR의 제약사항 및 한계점.

 

 

1. LOB나 Cluster Index는 지원하지 않는다.

2. DUMP_ORPHAN_KEYS 프로시저는 BITMAP Index, Function-Based Index는 지원하지 않는다.

3. 3,950 bytes이상은 지원하지 못한다.

 

 

 

3) DBMS_REPAIR 시작하기.

 (1) Block corruption 찾아내기. 

 [관련 패키지] 

 CHECK_OBJECT

 FIX_CORRUPT_BLOCK

 - 위 두 가지 패키지 사용하려면 먼저 ADMIN_TABLE이 실행되어야 한다. 

 

 

 (2) admin_tables 프로시저를 실행시켜 REPAIR_TABLE 생성하기.

 : 검사 전에 검사내용을 적은 table이다. (대소문자 구분*)

 

SQL>conn / as sysdba;  --sys 계정으로 접속.

Connected.


SYS>begin                               -- admin_tables 프로시저를 실행시켜 repair_table생성

  2     dbms_repair.admin_tables(

  3     table_name => 'REPAIR_TABLE',

  4     table_type => dbms_repair.repair_table,

  5     action => dbms_repair.create_action,

  6     tablespace => 'USERS');

  7  end;

  8  /


PL/SQL procedure successfully completed.

 


SYS>desc repair_table;  -- repair 테이블 조회 (또는 dba_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
 

 

 

 (3) admin_tables 프로시저 실행해서 Orphan-key-table 생성하기.

 : 장애가 발생한 테이블과 관련이 있는 다른 object를 저장하는 테이블.

  (관련 인덱스나 FK 등의 정보를 저장하는 곳.)

-- 테이블 검사를 하다가 관련이 있는 인덱스 등이 문제가 있을 수 있기 때문에 미리 생성해둠.

 

 

SYS>begin

  2  dbms_repair.admin_tables(

  3     table_name => 'ORPHAN_KEY_TABLE',

  4     table_type => dbms_repair.orphan_table,

  5     action => dbms_repair.create_action,

  6     tablespace => 'USERS');

  7  end;

  8  /


PL/SQL procedure successfully completed.

 


SYS>desc orphan_key_table;  --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

 

 

 

 (4) DB_Block_checking=true

 : 블록이 문제가 있는지 없는지를 확인하기 위해 true값으로 변경해주면, 오라클이 모든 블록을 체크한다. (overhead는 감수해야함.)

 - flase로 하면 system tablespace만 체크하고 나머지는 체크하지 않는다.

 

SYS>show parameter db_block_checking;


NAME                                 TYPE        VALUE

---------------------- ---------- ----------------------------

db_block_checking                 string      FALSE

 

 


SYS>alter system set db_block_checking=true;


System altered.

 


SYS>show parameter db_block_checking;


NAME                                 TYPE        VALUE

--------------------------- ----------- --------------------------

db_block_checking                    string      TRUE

 

 

 

 (5) DBMS_REPAIR 실습.

 step1. 파라미터를 설정한 후 재시작. (또는 alter system set으로 적용) 

 

## block checking parameter 값을 true로 설정

SYS>show parameter db_block_checking;

NAME                                 TYPE        VALUE

------------------------- ----------- ------------------------------

db_block_checking                    string      FALSE

 


SYS>alter system set db_block_checking=true;

System altered.

 


SYS>show parameter db_block_checking;

NAME                                 TYPE        VALUE

--------------------------- ----------- ------------------------------

db_block_checking                    string      TRUE

 

 

 step2. Block corrupt 발생시킴. (먼저 tablespace 및 table을 생성하고 데이터를 입력해 준다.)


SYS>create tablespace test10 datafile '/app/oracle/oradata/testdb/test01.dbf' size 256k;

Tablespace created.


SYS>@dd

TABLESPACE         MB FILE_NAME

---------- ---------- ---------------------------------------------

USERS              10 /app/oracle/oradata/testdb/users01.dbf

UNDOTBS1           10 /app/oracle/oradata/testdb/undotbs01.dbf

SYSAUX            600 /app/oracle/oradata/testdb/sysaux01.dbf

SYSTEM            710 /app/oracle/oradata/testdb/system01.dbf

EXAMPLE       345.625 /app/oracle/oradata/testdb/example01.dbf

TEST10            .25 /app/oracle/oradata/testdb/test01.dbf

 

6 rows selected.


SYS>create table scott.tt900 (no number, name varchar2(10)) tablespace test10;

Table created.


SYS>insert into scott.tt900 values (1, 'AA');

1 row created.


SYS>insert into scott.tt900 values (2, 'BB');

1 row created.


SYS>select * from scott.tt900;


        NO NAME

------- ----------

         1 AA
         2 BB

 


SYS>alter tablespace test10 offline;
Tablespace altered.

 


## 해당 data file을 winSCP를 이용해서, 윈도우로 이동시킨 후 윈도우에서 에디터를 통해서 블록을 잘 수정하셔서 Block corruption 만든후 다시 리눅스로 이동 후 작업한다.

 

 

 

SYS>recover tablespace test10;

ORA-00283: recovery session canceled due to errors
ORA-00264: no recovery required    -- recover가 필요 없다고 뜬다.

 

SYS>alter tablespace test10 online;

Tablespace altered.                 -- tablespace는 정상적으로 recover됨.


SYS>select * from scott.tt900;

select * from scott.tt900

                    *

ERROR at line 1:

ORA-01578: ORACLE data block corrupted (file # 6, block # 11)
ORA-01110: data file 6: '/app/oracle/oradata/testdb/test01.dbf' --장애발생

 

 

 Step3. DBMS_REAIR을 사용하여 에러 찾는다.

 

SYS>set serveroutput on;


SYS>declare n_corrupt int;

  2  begin

  3  n_corrupt:=0;

  4  dbms_repair.check_object(

  5     schema_name => 'SCOTT',

  6     object_name => 'TT900',

  7     repair_table_name => 'REPAIR_TABLE',

  8     corrupt_count => n_corrupt);

  9  dbms_output.put_line('장애블록수:' || to_char(n_corrupt));

 10  end;

 11  /


PL/SQL procedure successfully completed.


SYS>set line 200;

SYS>col object_name for a10

SYS>col corrupt_description for a20

SYS>col repair_description for a20
SYS>select object_name, block_id, corrupt_type, marked_corrupt,

  2        corrupt_description, repair_description

  3  from repair_table;


OBJECT_NAM   BLOCK_ID CORRUPT_TYPE MARKED_COR CORRUPT_DESCRIPTION  REPAIR_DESCRIPTION

-------------- ---------- ---------------- ------------- ------------------------ --------------------

TT900                    11         6148                    TRUE                                                mark block software

                                                                                                  corrupt

--> 11번 블록이 문제가 있다는것이 확인되며 corrupt 되었다고 mark됨

    

 

 step4. corrupt된 블록을 Fix. (check_object 부분에서 자동으로 해서 안해도 상관 없음)

 - fix의 의미 : 해당 블록에 corruption이 발생해서 사용하지 못하므로 더 이상 읽지도 쓰지도 말라는 표시를 한다는 뜻. 즉 블록안에 있는데 데이터를 복구한다는 뜻이 아니라 해당 블록을 못 쓴다고 표시만 해둔다는 뜻이다. 

 
SYS>set serveroutput on;
SYS>declare n_fix int;
  2  begin
  3  n_fix:=0;
  4  dbms_repair.fix_corrupt_blocks(
  5     schema_name => 'SCOTT',
  6     object_name => 'TT900',
  7     object_type => dbms_repair.table_object,
  8     repair_table_name => 'REPAIR_TABLE',
  9     fix_count => n_fix);
 10  dbms_output.put_line('fix_count:' ||to_char(n_fix));
 11  end;
 12  /
fix_count:0    -- fix된 블록의 개수 (check_object 부분에서 자동으로 fix되었기 때문에 0으로 나온다.)

PL/SQL procedure successfully completed.

 


SYS>select * from scott.tt900;   -- fix를 하고난 후 select 해보면, 테이블 여전히 조회안됨

select * from scott.tt900

                    *

ERROR at line 1:

ORA-01578: ORACLE data block corrupted (file # 6, block # 11)
ORA-01110: data file 6: '/app/oracle/oradata/testdb/test01.dbf'

 

-- 위 데이터 파일에 수 많은 블록에 데이터가 들어있다고 가정할 경우 1개의 block에 corrupt가 발생할 경우 전체 데이터를 읽어 오지 못하는 상황이 된다.

 

 

 step5. corrupt된 block을 skip하도록 설정. (남아있는 데이터만이라도 살려내고 싶을 때)

 

SYS>begin
  2  dbms_repair.skip_corrupt_blocks
(
  3     schema_name => 'SCOTT',
  4     object_name => 'TT900',
  5     object_type => dbms_repair.table_object,
  6     flags => dbms_repair.skip_flag);
  7  end;
  8  /


PL/SQL procedure successfully completed.


SYS>select * from scott.tt900;    -- corrupt된 블록만 제외하고 나머지 블록을 읽음.
        NO    NAME
---------- ----------
         1       AA
         2       BB


SYS>select owner, table_name, skip_corrupt   -- corrupt된 블록을 skip하도록 설정되어있는지 조회
  2  from dba_tables
  3  where owner='SCOTT'
  4  and table_name='TT900';


OWNER                      TABLE_NAME                 SKIP_COR
------------------- -------------------------- --------
SCOTT                          TT900                          ENABLED

 

4) DBMS_REPAIR 패키지 활용 실습.

 835p~

Print Friendly and PDF Posted by JJ*
: