Print
카테고리: [ Oracle Database ]
조회수: 9947
 
백업본이 없는 DB에 block corruption 이 발생하여 조치한 케이스 공유 드립니다.
해당 block 복구가 아닌 corrupted block을 skip 함으로써 조치했습니다.
 

-- ORA 01578 에러 발생

 
Insert Table TB_TEST  Error:ORA-01578: ORACLE 데이터 블록이 파손되었습니다 (파일 번호 2248, 블록 번호 474523)
ORA-01110: 2248 데이터 파일: '+DATA/TESTDB/datafile/TS_TEST.4663.984155003'

 

-- 이슈 세그먼트 확인

select owner,segment_name, segment_type
from dba_extents
where file_id = 2248  --파일번호
and 474523 between block_id and block_id + blocks-1 ; --블락번호
 
=> TESTUSER  TEST  TABLE
 

 

-- 뷰로 block corruption 조회하기

select * from v$database_block_corruption;
 
     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
      2248     474512         16         5.5986E+13 CORRUPT
 
=> 2248번 데이터파일의 474512~474527 의 block이 CORRUPT 됨 확인
 

-- DBMS_REPAIR 사용하는 방법

 
-1. parameter 설정
 
alter system set db_block_checking=true;
=> block 에 문제 있는 지 checking 하는 파라미터로 false 로 설정 되어 있을 시 system tablespace만 체크함
 
 
-2. CORRUPTED BLOCK 정보를 저장할 REPAIR TABLE 생성
 
REPAIR TABLE - 대상 테이블의 에러 정보 저장
 
begin
dbms_repair.admin_tables(
table_name =>'REPAIR_TABLE',
table_type => dbms_repair.repair_table,
action => dbms_repair.create_action,
tablespace => 'USERS');
end;
 
ORPHAN_KEY_TABLE - 연계된 OBJECT 에러 저장
 
begin
dbms_repair.admin_tables(
table_name=>'ORPHAN_KEY_TABLE',
table_type=>dbms_repair.orphan_table,
action=>dbms_repair.create_action,
tablespace=>'USERS');
end;
 
-3. 해당 테이블의 CORRUPTED BLOCK 체크
 
set serveroutput on;
declare n_corrupt int;
begin
n_corrupt :=0;
dbms_repair.check_object(
schema_name=>'TEST',
object_name=>'TB_TEST',
repair_table_name=>'REPAIR_TABLE',
corrupt_count=>n_corrupt);
dbms_output.put_line('장애블록수: '||to_char(n_corrupt));
end;
/
 
-4. REPAIR_TABLE 조회
 
set line 200;
col object_name for a20;
col corrupt_description for a20;
col repair_description for a20;
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
-------------------- ---------- ------------ ---------- -------------------- --------------------
TB_TEST                  474512         6148 TRUE                            mark block software corrupt
.
.
.                                                                             
TB_TEST                  474517         6148 TRUE                            mark block software corrupt
                                                                             
=> dbms_repair.check_object 후 repair_table에서 corrupted block 정보 조회
 
 
-4. CORRUPTED BLOCK들을 마킹
 
SET SERVEROUTPUT ON
DECLARE num_fix INT;
BEGIN 
num_fix := 0;
DBMS_REPAIR.FIX_CORRUPT_BLOCKS (
     SCHEMA_NAME => 'TEST',
     OBJECT_NAME=> 'TB_TEST',
     OBJECT_TYPE => dbms_repair.table_object,
     REPAIR_TABLE_NAME => 'REPAIR_TABLE',
     FIX_COUNT=> num_fix);
DBMS_OUTPUT.PUT_LINE('num fix: ' || TO_CHAR(num_fix));
END;
 
=> 위의 check_object 과정에서 자동으로 marking 하기 때문에 생략 가능
*여기서 fix 란, 해당 block에 corruption이 발생해서 사용할 수 없으므로 더이상 읽거나 쓰지 말라고 marking 한다는 의미
 
 
-5. corrupt marking 된 블락들 스킵해버리기
 
begin
dbms_repair.skip_corrupt_blocks (
schema_name=>'TEST',
object_name=>'TB_TEST',
object_type=>dbms_repair.table_object,
flags=>dbms_repair.skip_flag);
end;