백업본이 없는 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;
/