전문가칼럼

DBMS, DB 구축 절차, 빅데이터 기술 칼럼, 사례연구 및 세미나 자료를 소개합니다.

개발자들이 자주 접하는 오라클 에러 메세지

전문가칼럼
DBMS별 분류
Oracle
작성자
dataonair
작성일
2015-11-18 00:00
조회
11738




◎ 연재기사 ◎


물탱크 구조로 알아본 오라클의 블록 옵션 ‘PCTFREE와 PCTUSED’


이산가족 찾기 생방송을 통해 배우는 DB 원리


개발자에게 맞는 DB 공부방법 찾기: 물리적 분류와 논리적 분류 그리고 인덱스


데이터베이스 인덱스의 오해와 진실


쉬운 것이 올바른 것이다. ‘인덱스 끝장리뷰’ (상)


쉬운 것이 올바른 것이다. ‘인덱스 끝장리뷰’ (하)


누구도 알려주지 않았던 ‘오라클 인덱스 생성도’의 비밀


누구도 알려주지 않았던 ‘오라클 쿼리 작성의 비법’


퀴리 최적화 및 튜닝을 위한 오라클 공정쿼리 작성법


만능 쿼리와 한 방 쿼리


오라클 옵티마이저 ‘CBO와 RBO’ 이해하기


재미있는 DB 이야기 ‘60갑자와 쿼리’


그림으로 배우는 ‘오라클 조인의 방식’ 이야기


반드시 알아야 하는 오라클 힌트절 7가지


오라클 플랜을 보는 법


개발자들의 영원한 숙제 ‘NULL 이야기’


알면 유용한 오라클 기능 ‘GATHER_PLAN_STATISTICS’


알면 유용한 오라클 기능들


오라클 DICTIONARY를 활용한 DB툴 프로그램 ‘FreeSQL’


이제는 말할 수 있다: 주식 자동매매 프로그램(상)


이제는 말할 수 있다: 주식 자동매매 프로그램(하)


개발자들이 자주 접하는 오라클 에러 메세지


재미있는 DB 이야기 ‘사라진 날짜를 찾아라’


오라클 랜덤 함수와 사용자 정의 함수


그림으로 배우는 ‘공정쿼리와 인덱스 생성도’


이병국의 개발자를 위한 DB 이야기: 디폴트 세팅의 함정과 오라클 파라미터


재미있는 DB 이야기 ‘놀라운 마방진의 세계’


오라클 운반 최소 단위 BLOCK


이병국의 개발자를 위한 DB 이야기: 이세돌과 알파고의 세기의 대결


이병국의 개발자를 위한 DB 이야기(30회) : DB 엔지니어의 가볍게 읽는 세상 이야기


이병국의 개발자를 위한 DB 이야기: 튜닝(31회) : 개발자를 위한 DB 튜닝 실전(1편)


이병국의 개발자를 위한 DB 이야기: 튜닝(32회) : 개발자를 위한 튜닝 실전(2편)


이병국의 개발자를 위한 DB 이야기: 튜닝(33회) : 개발자를 위한 튜닝 실전(3편)


이병국의 개발자를 위한 DB 이야기: 튜닝(34회) : 개발자를 위한 DB 튜닝 실전(4편)


이병국의 개발자를 위한 DB 이야기: 튜닝(35회) : 개발자를 위한 튜닝 실전(5편)


이병국의 개발자를 위한 DB 이야기: 페이징 처리에 대한 이해 (36회)


보기 좋은 떡이 먹기도 좋다 - 좋은 쿼리 좋은 성능


테이블의 수직분할과 수평분할에 대한 이해


DB 성능 제고를 위한 채번의 이해와 방식별 장단점 비교


이병국의 개발자를 위한 DB 이야기: 마지막회 : ‘개발자를 위한 DB 이야기’ 연재를 마치며



이병국의 개발자를 위한 DB 이야기: 에러 메세지 (22회)

개발자들이 자주 접하는 오라클 에러 메세지



성공과 실패의 경험을 나누자, 용기와 희망을 나누자

개발업무를 시작으로 IT계에 입문했던 필자가 10년 가까이 DB 엔지니어로서 활동하면서 얻은 경험과 지식을 나누고자 한다. DB를 자주 접하는 SW 개발자뿐 아니라, DB 전문가를 꿈꾸는 대학생에서 DB 분야에 입문한 지 1~2년 된 기 입문자가 쉽게 이해할 수 있도록 비유를 통해 쉽게 접근해볼 계획이다. 물론 전문가들이라도 다시 한번 개념을 정립하는 의미에서 필요한 내용이 될 수 있다.

전체적으로 DB의 기본 원리와 개념을 이해하고 테이블, 인덱스, 쿼리, 튜닝, 플랜 등 개발자들이 알아야 하는 DB 전분야에 대해 쉽게 이해하도록 설명하겠다. DB 기술서적이나 번역서보다는 조금 더 부드럽게 접근할 계획이다. 그렇다고 흔히 서점에서 만날 수 있는 개발자 위주의 SQL 소개서도 아니다. 이 연재는 시리즈로 나갈 것이다. 연재를 끝까지 읽는 독자라면, 준전문가 수준의 DB 원리를 아는 것을 목표로 한다.



김기사와 빅데이터

빅데이터는 실시간으로 수집되는 다양한 종류의 수 많은 자료들로 정의할 수 있는데, 빅데이터 자체만으로는 의미 있는 자료가 될 수 없다. 분석툴을 이용하여 빅데이터에서 가치 있는 정보를 추출할 때 비로소 의미 있는 자료가 된다.

현재 빅데이터는 모바일 기기의 확대, SNS 활성화, 저장장치의 가격 하락, 다양한 빅데이터 분석 기술의 발전에 힘입어 점점 더 그 활용성이 올라가고 있다.

빅데이터가 한동안 핫이슈가 되었다가 지금은 잠시 소강 상태이지만 그렇다고 빅데이터의 중요성이 낮아졌다고는 볼 수 없다. 지금은 물밑에서 열심히 움직이는 오리발처럼 그 폭발력을 숨기고 있을 뿐이다. 어느 순간 비상하는 날을 위해 잠시 날개를 접고 다리를 저으면서 준비하고 있다. 글로벌 IT 기업들이 치밀하게 빅데이터 시대를 준비하고 있는 상황을 보면 이런 예측이 억지가 아님을 알 수 있다.

얼마 전에 다음카카오가 국민 네비게이션인 김기사를 626억원에 100% 인수했다는 뉴스를 보았다. 카카오택시와 연계하여 시너지 효과를 기대한다는 내용이었다. 일부 사람들은 너무 비싼 가격에 회사를 인수했다는 말도 하지만, 필자는 절대 그렇게 생각하지 않는다. 김기사는 단순한 국민 네비게이션 회사로만 인식되어서는 안 된다.

수백만 명이 이동하는 경로에 대한 정보를 매일 수백 만건씩 축적하는 정보 수집 회사다. 엄밀히 말한다면 김기사가 수집하는 것이 아니다. 앱에 가입한 수백만 명이 능동적으로 자기 정보를 김기사에게 전송하는 것이다. 그 정보들은 단지 도로에 대한 최적의 경로를 추출 하는 데 국한되어 활용되는 것은 아니다. 많은 다양한 분야에서 활용 가능한 의미 있는 정보들을 추출해 낼 수 있다.

방문 지역정보, 차량 상태정보, 차량 운행정보 등 다양한 수집 자료에 근거해 개개인의 활동 영역, 소득, 취미, 성향, 성별, 나이 등 수 많은 개인 정보를 추출할 수 있다. 정보활용 동의의 수고도 거치지 않는 알짜 개인 정보들이다. 이러한 정보를 활용한다면 여행, 쇼핑, 보험, 투자, 광고 등 수많은 분야와 연계해서 수익을 창출할 수 있다.

한발 더 나아가 차량의 센서 데이터까지도 수집할 수 있다면, 일례로 수집된 에어컨 센서 정보를 통해 추위를 타는 사람인지, 더위를 타는 사람인지, 냉면집을 소개할 건지, 따뜻한 국밥집을 소개 할건지 판단할 수도 있다. 이는 수많은 광고와 연결할 수 있다는 의미다. 또한 이러한 빅데이터 활용은 운행 중으로 한정한 범위에서만 활용되는 것은 분명히 아닐 것이다. 아마 다양한 분야에서 폭넓게 활용될 것이다. 결론은, 다음카카오는 김기사를 비싼 값에 인수한 것이 아니라 헐값에 인수했으며 조만간 그것을 증명해 보일 것이라 믿는다.



‘조선시대에도 빅데이터가 있었다’

빅데이터는 새로운 것이 아니다. 인류 역사와 궤를 같이 한다. 인류의 역사와 함께 수 만년 동안 축적된 전 인류의 총체적인 지식도 빅데이터라고 할 수 있다. 조선시대 허준의 동의보감도 빅데이터를 활용하여 만든 결과물이라 할 수 있다. 의술에 뛰어난 천재 한 명의 머리에서 나온 책이 아니다. 우리나라에서 자라는 온갖 약초와 독초에 대한 오랜 기간 축적된 지식과 수많은 처방 결과에 따른 효과들을 일목요연하게 정리한 백과사전식 의학 서적이다. 중국(서의)에 비교되는 우리나라(동의)의 보물(보감)이다.

조선시대 김정호 선조는 대동여지도를 만들었다. 그 당시 지도는 적국에 넘어가면 안 되는 국가 기밀이었다. 지도를 만드는 것 조차도 허락되지 않았다고 한다. 최고의 지배층만 지도 정보를 공유하였다. 기밀을 지나치게 강조하다 보니 지도 정보가 촉발할 수 있는 엄청난 사회적 변혁과 경제적 발전의 기회를 놓쳤다. 우리는 과거의 잘못된 역사의 반성을 통해서 미래를 대비해야 한다.

우리나라는 현재 초고속 인터넷과 스마트폰 보급률이 세계 1위다. 또한 신용카드 결제 비율도 세계 선두 그룹에 속한다. 잘 구축된 공공 인프라를 통한 전자정부 부분도 선두권이다. 개인건강기록이나 개인의료정보도 잘 구축돼 있다. 이렇게 수많은 빅데이터를 확보하고도 활용하지 못하고 있다. 물론 개인적-국가적으로 민감한 정보에 대한 통제는 필요하다. 하지만 빅데이터에 대한 보안성을 지나치게 강조하면, 조선시대 지도를 통제함에 따라 놓쳐버린 기회처럼 정보의 활용성은 떨어질 것이다.

엄청난 빅데이터가 존재함에도 그것을 활용하지 못하고 있으며, 빠른 시간 안에 사회적 타협과 제도적 정비를 이루어내지 못한다면 많은 기회를 놓칠 것이다. 공공의 빅데이터에 대한 사회적 타협과 제도적 정비가 잘 이뤄진다면 엄청난 경제적 효과를 선점 할 수 있다. 빅데이터에 대한 기업의 독점적 사용은 적절하게 통제 되어야 하며, 공익적 활용에 대한 정보는 폭넓게 개방 되어야 한다. 우리나라가 빅데이터의 선두권 국가에 다가서는 것을 기대해 본다.



오라클 에러 메시지 톱10

개발자들이 가장 빈번하게 접하는 오라클 에러 메시지에 관한 내용을 네이버 블로그에서 검색해 보았다. 다소 무모한 방법으로 시간을 써가면서 아래와 같이 오라클 에러 메시지 톱10을 추출하였다. 이것도 빅데이터의 활용이라고 주장하기엔 다소 무리가 있어 보이지만, 오늘의 연재는 오라클 에러 메시지에 대한 내용이다. 그 중에서도 아래 톱10에 대해서 자세히 설명하고자 한다.



column_img_2208.jpg

[그림 1] Oracle Error Message Top 10

“ORA-00001 : 유일성 제약조건에 위배됩니다.“

오라클 에러 메시지 중에서 개발자가 가장 자주 접하는 에러 메시지다. 테이블에 PK가 있거나 UNIQUE INDEX가 있을 때, 중복되게 INSERT 하면 발생한다. 이 에러는 가장 흔하게 접하는 에러이기 때문에 대부분의 개발자들이 쉽게 조치를 하지만, 의외로 조치가 빨리 이루어지지 않는 경우도 있다.

예를 들면 UNIQUE INDEX 존재 여부를 모르고 PK 컬럼들만 살펴볼 경우가 그러하다. 또한 UPDATE 중에 발생하는 경우도 의외로 발견하기 쉽지 않다. 그래서 PK 컬럼이나 UNIQUE INDEX 구성 컬럼은 가능한 UPDATE하지 않는 것을 원칙으로 정하고 쿼리 구분에서 아예 배제하는 것도 한 방편이다. 프로젝트 일정 말미에 데이터 컨버전 적재 작업 시에도 빈번하게 발생한다.



“ORA-00942 : 테이블 또는 뷰가 존재하지 않습니다.”

개발자의 오타에 의한 경우가 가장 흔하지만, 실제로 테이블이 생성됐는지 확인도 필요하다. 개발계와 운영계를 따로 관리하는 환경이라면, 실제 해당 테이블에 대한 생성 유무를 착각할 수도 있기 때문이다. 또한 권한이 없어서 발생하는 경우도 있다. 이와 같은 경우에는 DBA에게 권한을 요청하거나 아래와 같이 직접 권한을 부여하면 된다.



GRANT SELECT, INSERT, UPDATE, DELETE ON [테이블명] TO [유저명]



대소문자 사용에 따른 문제일 수도 있다. 오라클은 테이블 생성시 대소문자 구분은 없으며 자동으로 대문자로 생성된다. 하지만 따옴표로 감싸서 소문자로 생성시 테이블명은 소문자로 생성된다.



CREATE TABLE AAA → 대문자 테이블 생성 AAA
CREATE TABLE aaa → 대문자 테이블 생성 AAA
CREATE TABLE ‘AAA’ → 대문자 테이블 생성 AAA
CREATE TABEL ‘aaa’ → 소문자 테이블 생성 aaa



“ORA-00904 : 열명이 부적합합니다.“

존재하지 않는 컬럼명을 쿼리 구문에 사용할 경우에 발생하는 에러 메시지다. 대부분은 오타가 원인이다. 간혹 컬럼은 실제로 존재하나 SELECT 절에 없는 컬럼을 ORDER BY 절에 사용해서 발생하는 경우도 있으므로 쿼리 작성시 유의해야 한다. 아래 쿼리와 같은 경우가 그러하다.



SELECT 고객아이디, 고객명
FROM
(
SELECT CUST_ID AS 고객아이디, CUST_NM AS 고객명
FROM 고객
)
ORDER BY CUST_NM



“ORA-01017 : 유효하지 않는 사용자/패스워드에 의한 접근을 제한합니다.“

오라클 접속 시 사용자 ID나 패스워드가 일치하지 않아서 발생한다. 하지만 이런 경우가 아닌 대소문자 사용에 따라서 발생하기도 한다. 왜냐하면 오라클 11g부터는 대소문자를 구분하기 때문이다. 오라클 대소문자 구분 설정을 해제할 수도 있지만 보안상의 이유 때문에 통상적으로는 해제하지 않고 대소문자를 구분해 사용한다.

간혹 TNS 정보가 틀린 경우에도 발생하는데 이런 경우 에러 원인을 찾기 힘들다. 설마 TNS 정보가 잘못 됐으리라고는 상상도 하지 않기 때문이다.



“ORA-01722 : 수치가 부적합합니다.“

INSERT 혹은 UPDATE 시에 컬럼의 타입에 맞지 않는 값을 입력할 때 발생한다. 숫자 컬럼에 문자값을 입력하거나 문자 컬럼에 숫자값을 입력하는 경우가 그러하다. 조건절에서 아래와 같은 구문 사용시에도 발생한다. 결국 컬럼의 타입 전환시에 문제가 발생한다고 볼 수 있다.



SELECT * FROM 상품
WHERE SUBSTR(상품코드, 1, 1) = 1



단, 상품코드의 실제 값이 영문이나 한글이 아닌 숫자로 구성되어 있을 때는 에러가 발생하지 않는다.



“ORA-01555 : 스냅샷이 너무 오래 되었습니다. (롤벡 세그먼트가 너무 작습니다)”

사용자가 필요로 하는 롤백 세그먼트의 정보가 다른 트랜잭션에 의해 오버라이트돼서 존재하지 않을 때 발생한다.

결국, 롤백 세그먼트가 너무 작다는 의미인데 가장 쉽게 해결하는 방법은 롤백 세그먼트를 크게 하여 해결하는 것이다. 정말로 롤백 세그먼트가 작다면 늘리는 것이 올바른 방법이겠지만, 대부분의 경우에는 다른 방법으로 조치가 가능하다. 크기 확장이 항상 최선의 해결책은 아니다.

대용량 데이터 처리시에 빈번한 COMMIT 사용을 자제하거나, 처리를 한가한 시간대로 돌리는 것으로도 충분한 효과를 낼 수도 있다. 또한 실제로 필자의 경험에 따르면 이러한 에러 메시지는 대부분 잘못된 Heavy 쿼리에 기인하는 경우가 더 많았다. 주로 무거운 배치 쿼리의 실행에서 자주 발생하였다. 이러한 경우에는 크기 조정보다는 튜닝을 하는 것이 더 우선책이 될 수 있다. 만약 튜닝이 곤란하다면 트랜잭션이 몰리지 않는 한가한 시간에 배치를 구동하는 방법도 고려해 볼 만 하다.



“ORA-00911 : 문자가 부적합합니다.“

쿼리 구문을 잘못 작성해서 발생하는 에러라고 생각이 들겠지만, 대부분은 쿼리 구문의 끝에 세미콜론(;)을 사용해서 발생하는 경우이다. 이러한 경우에는 세미콜론을 없애면 된다.

토드에서 쿼리 구문 끝에 세미콜론을 붙이고, 이를 그대로 카피하여 무의식적으로 사용하기 때문에 자주 발생하는 경우이다. XML 파일에 SQL을 작성하는 경우에는 홑따옴표와 세미콜론의 사용에 주의를 기울여야 한다.



“ORA-12541 : 리스너가 존재하지 않습니다.“

오라클의 리스너는 네트워크를 통해 클라이언트에서 오라클 서버로 접근하는 것을 관리하는 기능을 수행한다. 원격 데이터베이스 서버에 접근하기 위해서는 원격 서버에 리스너가 구동되어 있어야 한다. 주로 리스너가 구동되어 있지 않았을 때에 발생하는 에러 메시지다. 아래의 명령으로 리스너를 구동한다.



명령 프롬프트 > Lsnrctl
LSNRCTL > status
LSNRCTL > stop
LSNRCTL > start



리스너 로그 파일이 너무 커져서 문제가 발생하는 경우도 있다. 이러한 경우 리스너 로그 파일을 옮기고 새로 생성하거나 아예 만들지 않게 설정하면 된다.



“ORA-03113 : 통신 채널에 EOF가 있습니다.“

서버의 고장이나 네트워크가 불안정할 때 주로 발생하는데, 다량의 데이터를 INSERT 하거나 UPDATE할 때 발생하기도 한다. 이 에러의 원인은 명확하지 않고 너무 포괄적으로 발생하기에 적절하게 대처하기가 무척 곤란하다.

이러한 에러를 만나면 네트웍 상태를 점검하기도 하고 방화벽을 의심해 보기도 한다. 아예 DB를 재가동하여 해결 하기도 한다. 만약 오렌지나 토드와 같은 툴에서는 잘 되는데 프로그램에서 안 된다면 쿼리의 길이를 줄여서 테스트 해 볼 필요도 있다. 그냥 시간이 지나면 자연스레 해결되는 경우도 있다. 참 난감한 에러 메시지다.



“ORA-01476 : 제수가 0 입니다.“

쿼리 구문의 나눗셈에서 분모가 0일 때 발생한다. SELECT 0 / 1 FROM DUAL → 에러가 발생하지 않는다. SELECT 1 / 0 FROM DUAL → 에러가 발생한다. 해결 방법은 다음과 같은 다양한 방식으로 조치하면 된다. SELECT CASE WHEN 분모가 = 0 THEN 0 ELSE 분자 / 분모 END FROM … SELECT DECODE(분모, 0, 0, 분자/분모) FROM … SELECT NVL(분자 / DECODE(분모, 0, NULL, 분모), 0) FROM …



오라클 에러 메시지를 마무리 하며

개발자들은 수많은 개발 과정에서 다양한 오라클 에러 메시지를 접한다. 대부분은 단순한 실수이거나 어처구니 없는을 소비한 후에 결국은 해결되겠지만, 조치 이후에 자괴감과 허무함을 느낄 것이다. 필자 또한 숱한 자괴와 허무를 느꼈다.

여러분들은 오라클 에러가 발생하더라도 결코 겁 먹을 필요는 없다. ‘이번엔 또 어떤 단순한 실수를 했는가’ 생각하면서 찬찬히 살펴 본다면 대부분은 쉽게 해결된다. 잘 모르거나 경험해 보지 못한 에러 메시지라면, 검색사이트에서 조회하면 대부분 해결 노하우를 쉽게 찾을 수 있다.

만약, 오라클 에러 메시지에 대해서 자세히 알고 싶다면 http://www.oracle.com/pls/db92/db92.error_search 사이트를 방문하면 된다. 그러면 보다 더 정확한 내용을 살펴 볼 수 있다.

이번 연재에서는 개발자들이 가장 빈번하게 접하는 ‘오라클 에러 메시지 톱10’에 대해 살펴보았다. 다음 연재에서는 재미있는 달력 이야기와 쿼리에 관한 것이다. 동서양 달력의 차이점과 달력의 역사에 대해서 살펴보겠다. 그리고 달력과 관련된 쿼리와 함수들 및 각종 날짜 관련 오류 메시지에 대해서 자세히 살펴볼 것이다. (다음 회에 계속)



[지난 문제의 정답과 풀이] 원리를 이해하고 논리로 풀어가는, 쉬어가는 DB 문제

지난 연재에 출제한 ‘원리를 이해하고 논리로 풀어가는, 쉬어가는 DB 문제’에 대한 정답과 해설은 아래와 같다. 문제를 풀면서 DB 원리를 하나씩 배우고 이해할 수 있다.



column_img_2209.jpg

[이번 호 문제] 원리를 이해하고 논리로 풀어가는, 쉬어가는 DB 문제

각 연재의 말미에 간단하면서도 재미있고 생각해 보는 문제를 출제하려 한다. 모든 문제는 DB의 원리를 이해할 수 있는 문제로 출제할 예정이다. 문제를 풀면서 DB 원리를 하나씩 배우고 이해할 수 있다. 정답과 그에 대한 설명은 다음 연재에서 한다.



column_img_2210.jpg