오라클

ORA-1578 조치 방법

OEasy 2006. 10. 30. 20:04
BULLETIN CATEGORY 
BULLETIN TOPIC
: RDBMS       
: ORA-1578 조치 방법

 모든 오라클  데이타 블럭은 Sequence  번호(seq)와 Incarnation 번호(inc)를 갖고 있다. ORA-1578  에러는 seq=0 이고 inc<>0(새로운 블럭이 아님)일 때 발생한다. 
      ORA-1578 에러는 ORA-600[3339] 에러와 함께  발생하곤 한다. 

* ORA-1578 에러가 발생하면  Corruption이 발생한 화일번호와 블럭번호를 알려준다. 여기서는 이 때의  화일번호를 f, 블럭번호를 b 라고 부르기로 한다. 

<해결방법> 
1. 우선 해야 할 일은  어떠한 오브젝트가 Corrupt  되었는가를 알아내는 것이다. 
       다음의 스크립트를 이용하면 알 수 있다. 

        SQL> select segment_name, segment_type  
            from dba_extents  
            where file_id = f and  
            b between block_id and block_id + blocks - 1;  

2. 만약 해당 세그먼트가 인덱스이면 Drop 시키고 다시 생성하면 된다. 

3. 만약 해당 세그먼트가 테이블이면 Corrupt 된 블럭의 데이타는 손상된 것이다. 

4. 만약 해당 테이블이 들어있는  엑스포트 화일이 있다면 손상된 테이블을 Drop 시키고 임포트 받는 것이 제일 간단한 방법이다. 하지만 만약 엑스포트 받은 화일이 없거나 백업해 둔 화일도 없다면 해당 테이블에 인덱스가 생성되어 있는 경우에 한해서 다음의 방법을 사용해서  복구를 하도록 한다. 

* empno, ename, deptno 를 컬럼으로 가지는 EMP 테이블이 Corrupt되었다고 가정하자. 그리고 empno 컬럼에 인덱스가 생성되어 있다고 하자.   클러스터화되지 않은 모든  테이블은  유니크한   Rowid를 가진다.   Rowid를  Varchar2/hexadecimal 형식으로 표현하려면  Rowidtochar 함수를 이용한다. 

         SQL>select rowidtochar(rowid) from emp;  

* Rowid는 총 18자로 블럭어드레스(8자), 점(1자), 로우 어드레스(4자), 점(1자),  화일 어드레스(4자)로 구성되어 있다. 

        SQL> select empno, rowid  
            from emp  
            where empno > 0  

  위의 스크립트를 실행시키면 다음과 같은 결과를 얻게 된다. 

        EMPNO                   ROWID  
        ------------     --------------------------------  
        100             00000003.0000.0006  
        101             00000003.0001.0006  
        102             00000003.0002.0006  
        103             00000003.0003.0006  
        .  
        500             00000004.0000.000A  
        501             00000004.0001.000A  
        .  
        755             0000001A.0005.000A  
        756             0000001A.000C.000A  

* 만약 인덱스가 Character 컬럼에  대한 것이었다면, 위의 Query 문장을  다음과 같이 바꿀 수 있다. 
        SQL>select empno, rowid  
            from emp  
            where empno > '';  
   
* 예를 들어 다음과 같은 에러  메시지가 떨어졌다고 하자. 
             01578, 00000, "ORACLE data block corrupted (file # 10, block # 4)  

  그러면 다음의 스크립트를 사용하여  손상된 블럭에 있는 employee 에 대한 empno를 구할 수 있다. 

        SQL> select empno   
             from emp  
         where empno > 0  and rowidtochar(rowid) like '00000004.%.000A';  

        EMPNO             ROWID  
        ------------    --------------------------------  
        500             00000004.0000.000A  
        501             00000004.0001.000A  

* 이제 EMP 테이블과 같은 구조를 갖는 새로운 테이블을 만든다. 

        SQL> create table temp   
            as select * from emp  
               where 1 = 2;  

* 그리고는 손상된 부분을 피해서  새로운 테이블에 손상된 테이블의 데이타를 추가한다. 

        SQL>insert into temp select * from emp where empno < 500;  
        SQL>insert into temp select * from emp where empno > 501;  

  손상된 테이블을 Drop 시키고  Temp 테이블의 이름을 EMP 로 변경한다.  그리고 백업된 자료나 문서자료를  통하여 손상된 부분에 대한 정보를  추가한다. 
   
5. 손상된 블럭에 여러개의 로우가  존재하고 있다면 다음의 방법을 이용한다. 

        SQL> create table empnos as  
            select empno from emp  
            where empno>0  
            and rowidtochar(rowid) not like '00000004.%.000A';  

   이 스크립트를 이용하면 손상된  블럭에 포함되지 않은 empno 들을 알 수 있다. 

* 다음의 스크립트를 계속 실행시켜 복구를 한다. 

        SQL>create table temp  as select * from emp  where 1 = 2;   
        SQL> insert into temp   
            select emp.empno, emp.ename, emp.deptno  
            from emp, empnos  
            where emp.empno > 0   
            and emp.empno = empnos.empno;  

6. 만약 데이타 딕셔너리의 테이블이나 인덱스에서 손상된 블럭이 발생했다면 지원을 요청해야 한다.


Oracle Korea Customer Support Technical Bulletins
 

'오라클' 카테고리의 다른 글

ORA-165X 조치 방법    (0) 2006.10.30
ORA-162X 또는 ORA-163X 조치 방법    (0) 2006.10.30
ORA-1555 (snapshot too old)조치 사항  (0) 2006.10.30
ORA-1118 조치 방법 (MAXDATAFILES와 DB_FILES  (0) 2006.10.30
ORA-604 조치 방법  (0) 2006.10.30