728x90

현장중계! 대한민국 개발자의 도전과 희망
1부, 기술 분야별 고민 해결 리포트

“당신도 데이터베이스 관리자인가요?”

고승훈 | 프로피아 오라클 기술팀장

데이터베이스를 처음 접하는 관리자가 갖는 막연한 두려움을 없애고 사소한 것이라도 원리에 충실한 지식만 있으면 어떠한 상황에서도 해결책이 있다는 것을 알려주기 위해서 이 글을 쓴다.

필자가 오라클을 접했을 때가 지난 1996년이었던 것으로 기억된다. 그때 버전은 7.0이었고 현재 버전이 10g로 변화하면서 Partitioning, Materialized View, Stream, Cache Fusion, Grid 등 새로운 기능 및 개념들이 많이 추가되었다. 
오라클을 처음 관리했을 때는 필자 역시 초보였고 뭐하나 작업을 하기 위해서는 명령문을 제대로 쓰고 있는가 하고 몇 번이고 망설이면서 사용했던 경험들이 많다. 필자의 초기 실수담을 하나 들자면 보통 오라클의 데이터베이스 파일의 확장자가 .dbf이다. 이전 파일 데이터베이스로는, dBASE IV들을 사용했던 경험자들은 알겠지만, 이것 역시 확장자가 dbf이다. 오라클을 몰랐던 필자는 오라클에서 사용했던 dbf 파일이 dBASE IV용 데이터 파일인 줄 알고 ftp로 전송을 시도했던 적이 있다. 물론 그날 전산실은 뒤집어졌음은 두말할 필요도 없다. 
필자의 생각에는 경험 없는 지식은 없다고 본다. 즉 머릿속으로만 기억하는 것은 지식으로써 의미가 반감된다는 것이다. 데이터 모델링, 재난 복구, 데이터베이스 운영 설계 등 생각만으로는 힘든 부분들이 많다. 특히 데이터 모델링 부분은 경험을 바탕으로 한 지식이 뒷받침되어야 한다. 이 글에서는 누구나 쉽게 이해할 수 있는 분야 중에서 재난 복구에 관한 필자의 경험을 통해 문제해결의 실마리를 푸는 각자의 열쇠를 찾기 바란다.

두 가지 순발력 테스트

글을 시작하기 전에 독자들에게 순발력과 관련된 상황문제를 제시해 보겠다. 5분이내로 정확하게 해답을 생각해내는 사람이라면 순발력이 좋다고 봐도 괜찮을 것이다.

“B지점의 입고량 좀 알고 싶소”

첫 번째 상황이다. 이것은 SQL문 작성에 관한 것인데 물류 쪽에서 가끔 나올 수 있는 질의다. 제품, 판매, 입고 등 3개의 테이블이 기본으로 주어지고 질의는 다음과 같다.

한 영업소 부장이 2004년 B지점에서 판매된 제품의 현재까지의 입고량을 보고 싶다고 갑자기 요청을 했다. 단순히 데이터만 보여주면 되었기 때문에 단순 조인으로 3개 테이블을 SELECT 작업을 했다. 그런데 이런! 결과가 10분이 지나도 나오지 않는 것이 아닌가? 당장 나온다고 큰소리 치고 시작했는데 10분이 지나고 20분이 지나도 나오지 않는 것이 아닌가? 등에선 땀이 나고 결국 30여분이 지나서야 결과가 나왔다. 그런데 이런 지점 코드가 B가 아니라 A라고 하면서 다시 결과를 보고 싶다고 한다. 이때 여러분은 어떻게 할 것인가? 또 다시 그대로 진행을 하여 30분 동안 기다릴 것인가?

답은 간단하다. 단순 조인 SQL문을 수정한 다음 질의를 하는 것이 낫지 않겠는가? 이제 질의문을 한 번 더 보자. 우리가 보고 싶은 것은 입고 현황이다. 즉 판매 쪽은 단지 판매가 된 제품코드를 얻기 위한 것이다. 그러므로 조금 더 생각을 하면 먼저 ‘2004년 A지점에서 팔린 제품 코드를 얻은 다음 이 코드를 가지고 입고량을 볼 수 있다’고 생각할 수도 있고, ‘2004년에 입고된 제품 중 2004년 A지점의 판매 내용에 있는지 여부를 체크한 다음에 있으면 입고량을 본다’라고도 해석할 수 있다. 이 두 가지의 경우에 따라 사용되는 SQL문이 달라진다. 처음에 제시한 내용에 대한 SQL문은 다음과 같이 나타낼 수 있다. 
<리스트 1>과 <리스트 2>는 서로 다르다. 그리고 맨 처음 생각했던 3개 테이블의 단순 조인과는 또 다르다. 결과는 단순 조인문과 <리스트 1>, <리스트 2>의 결과 값은 같다. 그러나 수행결과 시간에서 차이가 날 것이다. 왜 차이가 날까? 질의문 작성의 원칙은 ‘되도록이면 데이터를 줄여라’, 그리고 ‘필요 없는 조건수행을 하지 마라’이다. <리스트 1>은 데이터를 줄이는 부분에 충실한 것이고 <리스트 2>는 필요 없는 조건 수행을 없앤 것이다.

데이터베이스의 공간 할당

두 번째 상황은 데이터베이스 공간 할당이다. 여러분이 해결할 사항은 다음과 같다.

판매 입력을 배치 작업으로 진행하는 중에 갑자가 더 이상 EXTENTS를 증가할 수 없다는 메시지가 계속 나온다. 추가적으로 100MB짜리 데이터 파일을 추가했지만 같은 메시지가 계속 나온다. 오늘은 월말이고 내일 아침 판매회의 때 이달 말 판매 현황에 대한 보고서를 뽑기 위해서 영업부 직원들이 언제 작업을 할 수 있는지 물어보고 초보 데이터베이스 관리자였던 필자는 여러 방면으로 해결책을 찾아보고 있었다. 여러분들은 어떻게 할 것인가?

이 같은 문제는 데이터베이스 관리자가 겪는 에러 사항 중 가장 일반적인 문제라고 생각한다. 그런데 가끔 증가를 시켰는데도 문제가 계속적으로 발생하는 경우가 종종 있다. 요즘 버전에서도 가끔 일어나는데 우리가 아무 의미 없이 사용한 옵션 하나가 이러한 문제의 원인이다. 오라클에서는 ‘EXTENT는 연속된 공간의 세그먼트의 집합’이라고 한다. 이것을 기억하기 바란다. 예전에 필자가 겪었던 문제의 하나인데 디스크가 비쌌던 시절 ‘EXTENT 증가실패’ 메시지가 나와서 필자는 흔히 하는 방식대로 ‘ALTER TABLESPACE ADD .. ;’ 명령을 사용하여 증가를 시켰다. 사이즈는 100MB를 주었다. 그런데 동일 메시지가 발생을 했다. 이상하게도 전체적인 테이블스페이스 사용률도 70% 정도 밖에 안 되고 데이터 파일도 추가시켜 주었는데 발생을 했다. 여러분들은 어떤 측면으로 볼 것인가? 필자가 앞에서 했던 말 중 연속된 공간이라는 것을 떠올리면 답이 나올 수 있을 것이다. 그리고 EXTENT 증가시 그 크기를 어떻게 정하는지도 생각을 해라. 문제의 테이블 SALE이란 테이블의 PCTINCREASE 값이 기본 값인 50%로 되어 있었던 것이다. 그래서 EXTENT가 증가할 때마다 그전 크기의 50%만큼 계속 증가되어 최종적으로 약 80MB 정도가 마지막 EXTENT 크기가 된 것이다. 다음 EXTENTS의 크기는 ‘80+ 80*0.5= 120MB’가 되어서 새롭게 추가시킨 100MB로는 어림도 없었던 것이다. 그리고 전체 공간에서 30% 정도의 FREE 영역이 있다 해도 그것이 연속된 FREE 공간이라는 확신은 없다. 그래서 그 이후부터는 어떤 일이 있어도 PCTINCREASE 값은 0으로 설정한다. 
앞의 두 가지 상황에서 여러분들은 다른 선택을 했을지도 모른다. 그러나 문제를 어떤 방향으로 해석하느냐가 얼마나 중요한가를 느꼈을 것이며, 우리가 미처 인식하지 못했던 부분에서 나올 수도 있다는 사실이다. 항상 표면상의 문제뿐만 아니라 그 속에 숨어 있는 뜻을 알고자 하는 노력이 필요하다는 것을 필자는 두 가지 상황을 예로 들어 얘기하고 싶었던 것이고, 이제부터 필자가 쓰고자 하는 내용은 이러한 조그마한 지식이 어떻게 최악의 상황에서 필자를 구원했는지 이야기하려는 것이다.

최악의 상황은 예고 없이 찾아온다

지난 1999년쯤에 발생한 일이다. 필자는 전산실 데이터베이스 관리자로 근무하고 있었고, 그날은 일요일이어서 직접 회사 당직근무를 하고 있는데, 갑자기 영업부에서 회의 자료를 출력하는데 오류가 나온다는 것이다. 난 프로그램의 순간적인 오류로 생각하고 다시 시도해 보라고 한 다음에 전화를 끊었다. 그런데 이번엔 다른 영업부에서 전화가 왔다. 판매 자료가 조회 중에 갑자기 나오지 않는다는 것이다. 필자는 설마 데이터베이스가 어떻게 될 것이라고는 생각하지도 못한 상황에서 서버실로 들어가 보았다. 그 당시 필자의 회사는 다른 곳으로 이전하기 위해서 잠시 서버를 다른 곳에 옮겨둔 상태였기 때문에 서버 상태를 보기 위해서는 직접 그곳에 가야 했다. 서버실에 들어서니 상황이 생각했던 것보다 심각하다는 느낌을 받았다. 서버의 디스크에서는 소리가 ‘킥킥’하고 들렸던 것이다. 설마 디스크가? 그러나 이러한 필자의 생각은 적중했다. 디스크가 완전히 깨진 것이었다. 아침에 서버를 점검할 때에는 이상이 없었는데 한 시간도 안 지나서 디스크가 깨진 소리가 들린 것이었다.

백업은 당신의 수호천사

그 당시 필자의 회사는 백업 시스템이 제대로 갖추어지지 않았다. 데이터베이스 관리자로서 백업은 익스포트만 받았던 필자는 실제 물리적인 디스크에서 오류가 나자 복구할 수 있는 방법이 생각나지 않았다(그때 당시 왕 초보 관리자였음을 기억하기 바람). 만일 필자가 아카이브로 운영하고 있었고 백업 데이터 파일이 있었다면 아주 쉽게 복구한 다음 아무 일이 없었다는 듯이 무사히 당직근무를 마쳤을 것이다. 그러나 백업받은 데이터 파일은 한 달 전 파일이었고 더 큰 문제는 익스포트 백업은 테이프 이상으로 인해 복구가 불가능한 상태가 된 것이다. 백업도 없는 상황에서, 그리고 데이터베이스는 오픈되지 않는 상태에서 어떻게 한 달간의 자료를 살릴 것인가? 
그래서 필자는 항상 데이터베이스 관리자에게 당부하는 것이 백업이다. 흔히 하는 말로 “복구에 실패한 관리자는 용서할 수 있어도 백업에 실패한 관리자는 용서할 수 없다”는 말이 있다. 백업은 최대로 보수적으로 봐야 한다. 그 이유는 하드웨어라는 것들은 바로 몇 분 후에 무슨 일이 생길지 모르는 매체이기 때문이다. 테이프도 깨질 수 있고 백업 스토리지도 언제든지 망가질 수도 있다는 것을 초보 데이터베이스 관리자는 명심하기 바란다. 물론 최근의 장비들이 신뢰도가 높다고 하지만 가능성이 0%가 아니기 때문이다. 
사실 오라클에서는 데이터 파일에서 직접 데이터를 끄집어낼 수 있는 DUL(Data UnLoader)을 사용하여 깨지는 않는 데이터 파일에서 데이터를 복구할 수는 있겠지만 사실 당시에는 DUL이란 것이 있는지도 몰랐고 서비스 비용도 만만치 않은 이유도 있긴 하다.

침착한 대처는 좀 더 나은 상황을 만든다

우선 필자는 디스크 복구 여부를 확인하기 위해서 하드웨어 업체를 불렀고(물론 공유일이었으므로 서비스료를 지불했다. 당시 시간당 17만원으로 기억한다. 서비스료 산정은 다 알다시피 해당 엔지니어가 출발하는 시간부터 산출된다) 결과는 복구불능으로 파악되었다. 좀 더 복구와 관계된 조치를 하기 위해서는 미국으로 보내야 했고 기간은 한 달이 소요된다고 했다. 그러나 이 방법은 현재 상황에서는 불가능한 선택이었다. 그 이유는 바로 내일 아침에 바로 서비스가 되어야 했는데 한 달 동안 기다릴 수도 없었고 결과 또한 비관적이었기 때문이다. 그리고 깨진 디스크에 있는 데이터도 판매 데이터가 있는 디스크였기 때문에 한 달 전 자료가 있으므로, 필자는 마음을 비우고 한 달 동안의 판매 데이터를 수작업으로 입력하는 최악의 경우를 생각하고 조치방법을 생각했다. 
우선 데이터베이스를 정상적으로 오픈시켜야 했다. 오라클 관리자들은 알겠지만 No Archive Log 상태에서 데이터 파일이 깨졌을 경우에는 복구 자체가 되지 않는다. 필자는 우선 문제가 되는 데이터 파일을 offlline drop 옵션을 사용하여 오픈시켰다(<화면 1>). 또한 No Archive Log 상태로 운영 중인 데이터베이스는 offline만의 옵션으로 수행되지 않는다. 그리고 offline drop 옵션을 사용하면 해당 데이터 파일은 해당 데이터베이스에서는 영원히 사용하지 못한다.

<화면 1> OFFLINE DROP 옵션 사용 후 데이터베이스 오픈 


이때 필자의 머리에 한 가지 생각이 스치고 지나갔다(여기서부터는 약간의 데이터베이스 지식이 필요하다). 오라클 데이터베이스의 경우 하나의 테이블 스페이스에 여러 개의 데이터 파일이 존재할 수 있다. 처음에 설정한 데이터 파일이 모두 사용되면 또 다른 데이터 파일을 추가함으로써 결과적으로 하나의 테이블 스페이스에 여러 개의 데이터 파일이 존재하게 된다. 
문제의 판매용 테이블 스페이스는 4개의 데이터 파일로 구성된 것이었는데 그 중 하나가 깨진 디스크에 존재했고 이 데이터 파일을 offline drop 옵션을 사용해서 데이터베이스를 오픈시킨 것이다(<그림 1>). 필자는 그러면 안 깨진 데이터 파일에서 최근의 판매 데이터를 가지고 올 수 있는 방법이 있지 않을까 생각한 것이다.

<그림 1> OFFLINE된 데이터 파일 


그러면 해당 데이터가 어떤 데이터 파일에 있는지 알아야 하는데 이때 사용하는 것이 ROWID이다. 오라클에서는 하나의 row를 유일하게 구분하는 키 값이 ROWID이며 이 값의 포맷은 버전별로 약간 다르지만 오라클8 ROWID 포맷에 대해서는 다음의 <그림 2>에 나와 있다.

<그림 2> ROWID 포맷 


ROWID 값으로 해당 데이터가 어느 파일의 어느 블럭에 있는지 알 수 있는 것이다. 문제는 보통 테이블을 SELECT 작업을 해야 하는데 <화면 2>와 같은 에러가 나올 것이다. 이것을 보면 모든 데이터의 ROWID 값을 알기 위해서는 TABLE FULL SCAN을 해야 하는데 FULL SCAN을 하는 순간 ORA-00376 에러가 나온다는 것이다.

<화면 2> FULL SCAN시 에러 발생(ORA-00376) 


참고로 데이터가 어느 데이터 파일에 있는지 확인할 수 있는 명령문을 보면 다음과 같다. 우선 데이터 파일의 상대적인 파일 번호를 우선 알아야 되며, 해당 데이터의 ROWID에서 상대적 파일 번호를 찾아내어 비교하면 된다.

<화면 3> 상대적인 FILE 번호 


<화면 4> 상대적인 FILE 번호 


<화면 3>과 <화면 4>에서와 같이 해당 테이블 스페이스 TEST는 4개의 파일에 분포되어 있고 실제 데이터도 4개의 파일에 분포되어 있다는 것이 확인됐다(앞의 결과는 데이터 파일이 깨지기 전이므로 <화면 4>의 결과가 제대로 나온 것이다). <화면 4>에서 조건절에서 적절한 조건 값을 주면 조건 값에 맞는 데이터가 어느 데이터 파일에 있는지 나올 것이다. 
그러면 모든 데이터에 대한 ROWID도 알 수 없는 상황에서 어떻게 복구할 수 있을까? 해결책은 깨진 디스크에 있는 데이터 파일이 해당 테이블 스페이스에서 가장 먼저 만들어진 파일이라는 것에 힌트를 얻을 수 있다. 그리고 해당 테이블을 SELECT할 때는 이미 만들어져 있는 INDEX를 통해 SELECT를 해야 한다는 점, 이 두 가지를 기억해야 한다. 가장 먼저 만들어진 파일이라면 오래된 자료가 있을 가능성이 가장 높고 INDEX SCAN을 통해 최근의 데이터 중심으로 SELECT를 하면 정상적인 데이터를 얻을 수 있다. 필자의 경우에는 우선적으로 최근의 판매 데이터만을 얻으면 최상의 결론이었기 때문에 혹시 하는 생각으로 인덱스로 잡혀 있는 판매일자를 최근 한 달 것으로 SELECT를 해보았다. 결과는 대성공으로, 데이터를 가지고 올 수 있었다. 그때의 기분은 하늘을 날아갈 듯이 기뻤다. 왜냐하면 필자의 생각대로 진행이 되었기 때문이다. 이때가 개인적으로 하나의 도약을 할 수 있었던 상황으로 생각된다. 최악의 경우 수작업 입력을 생각했는데, 무작정 안 될 것이라고 포기하지 않고 데이터베이스의 기본적인 구조를 이해한 상태에서 적절한 조치를 통해 데이터를 복구할 수 있었던 것이다.

<화면 5>와 <화면 6>은 FULL SCAN과 INDEX SCAN의 차이를 극명하게 보여준다. 
<화면 5>와 <화면 6>에서와 같이 인덱스를 통한 데이터 SELECT 작업은 오류 없이 TRACE 결과를 보여주지만 해당 테이블을 FULL SCAN하는 경우에는 데이터 파일에 문제가 있기 때문에 ORA-376 에러가 난다.

<화면 5> INDEX SCAN 


<화면 6> FULL SCAN 


<그림 3> INDEX SCAN 원리 


사실 INDEX SCAN 원리(<그림 3>)는 초보 데이터베이스 관리자라도 모두 알 것이다. 그러나 중요한 요소는 그것을 적용시키는 순발력과 평상심일 것이다. 보통 당황하면 아는 것도 까먹는 경우가 많다. 특히 대안이 마땅하지 않는 경우에는 더욱 그럴 것이다. 그러나 모든 일이 대안이 없는 경우는 없다. 최악의 대안도 해법이 될 수 있기 때문이다. 그러므로 초보 데이터베이스 관리자에게 필자가 얘기하는 것은 우리가 의미 없이 지나가는 지식도 이런 상황에서는 아주 최선의 해결책이 될 수 있다는 것이다. “개똥도 약에 쓰려면 없다”는 말이 있는데 아주 흔해빠진 것이라도 정작 쓰려고 하려면 없다는 뜻이다. INDEX SCAN과 FULL SCAN은 데이터베이스에서의 아주 기본적인 개념이다. 이것을 정확히 이해하고 쓴다면 관리적인 차원에서도 많은 도움이 될 것이다. 필자도 처음부터 모든 것을 다 아는 것은 아니었고 기초적인 내용에 충실한 결과 현재가 있다고 생각한다.

기본에 충실하기 위한 생각

필자가 얘기하고 싶은 것은 항상 기본에 충실하고 아는 것도 다시 한번 보라는 것을 얘기하고 싶다. 사실 우리가 대부분의 업무에서 사용하고 있는 것은 아주 특별하고 어려운 기술을 사용하는 것이 아니고 일반적이고 쉬운 부분을 중심으로 이용한다. 이러한 일반적인 것을 해당 데이터베이스 시스템에 최선의 방안으로 선택하고 이용하는 것은 관리자의 몫이란 생각이 든다. 그리고 필자의 미숙한 글을 읽어준 사람들에게 감사를 드린다.


출처 : 마이크로소프트웨어 [2004년 11월호]

728x90

'용어' 카테고리의 다른 글

DBMS의 종류  (0) 2010.01.04
OLE DB에 대한 이야기  (0) 2009.12.17
아카이빙(Archiving) 과 백업(Backup) 의 차이점  (0) 2009.11.12
DBA란?  (0) 2009.07.08
아직도 UTF-8을 안 쓰십니까?  (0) 2009.07.08

+ Recent posts