TECH
QUESTION
자주하는 질문답변 입니다.
Oracle
작성자 | 유건데이타 | 등록일 | 2015-05-16 |
제목 | ORA-1578 : Data block corrupted in file # block # | ||
---|---|---|---|
개 요 : ORA-00600 [3339] [arg1] [arg2] [] [] [] []
ORA-1578 : Data block corrupted in file # block # ORA-600 에러는 ORACLE이 직접 버퍼로 데이타를 읽어들일 때 읽은 블럭의 DBA(Data Block Address)가 잘못되었음(INVALID)을 의미한다. arg1은 실제로 읽어들인 블럭의 DBA를 나타내며 arg2는 ORACLE이 읽고자 하였던 블럭의 DBA를 나타낸다. arg1과 arg2이 다르면 위에서와 같은 에러가 발생하며 주로 OS나 HW의 문제가 그 원인이 되는 경우가 많다.데이타의 손상 원인은 여러가지가 있으며 대개 데이타가 손상될 당시에는 그 사실이 드러나지 않다가 손상된 부분의 데이타가 사용될 때 비로소 손상된 사실이 알려지게 된다. ORACLE은 모든 정보를 블럭 형태로 관리한다. ORACLE 데이타 블럭은 하나 이상의 OS 블럭으로 이루어져 있다. 그 크기는 init.ora 화일의 DB_BLOCK_SIZE에 나타나 있다. ORACLE 데이타 블럭은 블럭의 정보를 담은 fixed header 를 갖고 있으며 이 정보를 이용하여 각각의 블럭과 데이타베이스 전체의 INTEGRITY를 유지한다. DBA는 fixed header의 한 부분으로 32bit 길이의 정수이며 데이타베이스의 화일 번호와 화일에서 블럭위치를 나타낸다. DBA에 문제가 있으면 ORACLE은 OERI(3339)와 함께 위에서 말한 2개의 인수, 즉 arg1과 arg2를 표시하게 된다. 이 두 값이 다르면 OERI(3339)가 발생하게 되는 것이다. ORACLE은 화일에 블럭을 읽고 쓸때 시스템 펑션 콜을 이용한다. 여기에는 lseek(), read(), readv(), write(), writev() 등이 포함된다. 블럭이 OS에 의해서 읽혀지면 SGA로 들어가며 곧이어서 DBA에 대한 검사가 이루어진다. 원인과 증상: 경우1) ORA-00600 [3339] [0] [large number] [] [] [] [] ORA-1578: Data block corrupted file # block # 이 경우에는 arg1은 0이고 arg2는 ORACLE이 찾고 있는 DBA이다. 이 에러의 원인은 ORACLE 블럭의 일부가 모두 0이기 때문인 경우가 많다. ORACLE 블럭내의 첫번째 OS 블럭은 디스크상의 문제로 해서 OS 또는 디스크 복구 프로그램이 해당 블럭을 복구하려는 과정에서 모두 0으로 되어버리곤 한다. 유닉스 플랫폼의 경우에는 여러개의 DBWR을 동시에 작동시키면 이와같은 문제가 발생하는 것으로 알려져 있으나 V6.0.33.2 이후 버전에서부터는 수정되었다. ORA-1578 메시지는 반드시 OERI(3339)를 유발시키지는 않는다. 원인: arg1이 0이되는 또다른 원인은 ORACLE의 버그 때문인데 롤백세그먼트가 드롭되기 전 그 롤백 세그먼트를 포함한 테이블스페이스가 먼저 드롭되면 발생한다. 이 문제는 V6.0.32 이후의 버전에서 수정되었다. 경우2) ORA-00600 [3339] [large number] [large number] [] [] [] [] ORA-1578: Data block corrupted file # block # 원인1) 이번에는 디스크상의 물리적 블럭의 DBA가 틀린 경우이다. 이것은 블럭이 메모리 상에서 손상되었으나 그대로 디스크에 기록된 경우에 발생한다. 이 문제는 매우 드물게 나타나며 이 때의 DBA는 보통 아무의미없는 값이다. 만약 메모리에 문제가 있다고 생각된다면 다음과 같은 event parameter를 init.ora에 추가함으로써 블럭 검사를 할 수 있다. event = "10210 trace name context forever, level 10" event = "10211 trace name context forever, level 10" DBWR가 디스크에 데이타를 쓰기 전에 캐쉬에서 손상된 블럭을 발견하면 OERI(3398) 메시지를 출력하고 인스턴스를 정지시킬 것이다. 따라서 문제의 블럭은 디스크에 저장되지 않는다. 이 때 DBA를 포함한 많은 인수들이 OERI(3398) 내부 에러 처리기에 전달된다. 이와 같은 경우에는 인스턴스를 다시 기동시키고 리턴된 인수와 tarce 화일을 가지고 Oracle World Wide Customer Support에 연락하여야 한다. 원인2) 블럭이 데이타화일상에 기록될 위치를 잘못 찾는 경우이다. 이것은 "write blocks out of sequence" 라고 불리운다. 이 때 OERI(3339)에서 표시되는 DBA는 모두 유효한 값이다. 이것은 ORACLE이 lseek()을 호출했을 때 OS가 블럭을 잘못된 곳에 기록해서 생기는 경우가 많다. 어떤 HW/OS 공급업체들은 4.2G 를 넘는 큰 화일을 다룰 수 있는 기능을 제공한다. 이것은 32bit unsigned number로 다룰 수 있는 범위를 벗어나기 때문에 OS는 offset 값을 ORACLE이 사용할 수 있도록 적절히 변환시켜야 한다. ORACLE은 OS의 지원 여부와 관계없이 2G 이상의 화일을 지원하지 않으며 위와같은 큰 화일을 다룰 수 있는 환경에서는 lseek() 시스템 콜이 정확한 위치로의 변환을 시켜주지 못함에따라 보다 작은 크기의 화일에서도 문제가 발생하는 경우도 있다. 원인3) 세번째 원인은 I/O기능이 전혀 작동하지 않는 경우이다. 이 경우에 표시되는 DBA 값은 모두 유효한 값들이지만 arg1은 이전에 SGA로 읽혀진 블럭의 DBA 값이 된다. ORACLE은 lseek(), read() 시스템 콜이 리턴하는 에러 코드를 검사하며 read()가 읽어들인 바이트 수가 BLOCK SIZE의 정수배인지를 검사한다. 이 검사를 통과하면 ORACLE은 성공적으로 READ가 수행되었다고 가정한다. 만약 DBA가 정확하지 않다고 체크되면 DATABASE에 대한 읽기 요구는 실패하기 때문에 실제의 블럭 읽기는 일어나지 않는다. 이 경우에 리턴된 DBA는 실제로는 다른 화일의 다른 블럭을 지시하게 될 수도 있다. 원인4) 또 다른 원인은 동일한 디바이스에서 다른 블럭을 읽어온 경우이다. 이것은 작업이 메우 바쁜 디스크에서 발생하곤 한다. 어떤 경우에는 수백개 이상 떨어진 곳의 블럭을 읽어오는 경우도 있다. 이때에도 DBA 값은 모두 유효한 값이다. 세번째와 네번째 경우에는 다시 한번 동작을 반복함으로써 문제는 해결될 수 있으며 이것은 일반적으로 ORACLE의 문제가 아니라 OS나 HW의 문제인 경우가 많다. OERI(3339)에서 표시되는 인수들의 값은 플랫폼에 따라 다르다. |
Comment | |||
---|---|---|---|
등록된 코멘트가 없습니다. |