본문 바로가기
일상, 기타/일상

오라클 마이그레이션 12c -> 19c 후기 및 회고

by 애기 개발자 2023. 1. 2.
반응형

회사에서 약 한 달의 기간을 주고

 

오랜 고객사 하나의 DB서버가 너무 용량이 적고 과부하가 생겨서

 

서버를 증성하며 오라클 버전의 업데이트한다고 하였고,

 

이 일의 담당으로 내가 배정되었다.

 

맨 처음 들었던 정보는

 

오라클 12c버전에서 정보를 그대로 가져다가

 

새로운 DB서버에 오라클 19c를 설치하여 데이터를 그대로 옮겨놔야 했다.

 

우선 구 DB서버의 스펙은

 

오라클 12c
자바 버전 1.7
character set euc-kr

 

신규 DB서버는

오라클 19c
자바 버전 1.8
character set utf-8

한글정보가 사용되기 때문에 캐릭터 셋을 잘 맞춰야 했다.

 

그렇게 euc-kr의 데이터를 읽어서 utf-8로 저장하는 insert into 로만 이루어진 .sql 파일을 생성하는 배치 프로그램을 작성하였다.

 

배치를 돌려보니 데이터는 잘 나왔다.

 

sql파일의 용량은 1.8GB 정도 되었고 이를 신규 DB서버의 developer 툴로 실행시킬 수가 없어서

 

cmd의 sql plus를 이용하여 실행시켰다.

 

결과는 한글이 전부 깨진 것이다. 알고 보니 고객사 측에서 al32 utf8로 준비를 했던 것이다.

 

그래서 이후 몇 번의 테스트과정을 거쳐서 utf8으로 인코딩 된 파일을 MS949로 생성하도록 배치파일의 코드를 수정하였고. 한글이 온전하게 잘 들어갔다.

 

200개가 넘는 테이블 중에 로그나 이력을 저장하는 테이블을 제외한 몇몇 중요한 테이블만 비교를 하였으며 큰 차이 없이 잘 입력된 것을 확인하고 테스트를 종료하였다.

 

이때까지만 해도 난 모든 게 잘 풀릴 줄 알았다.

 


이제 고객사 실제 적용하는 날이 되었다.

 

먼저 고객사 구 DB서버가 연결된 곳의 아파치와 톰캣의 서비스를 모두 종료하였다.

 

마이그레이션 작업동안 새로운 정보가 쌓이지 않도록 하기 위해 막아둔 것이다.

 

이후 배치파일을 실행시켜 구 DB서버의 데이터 덤프를 가져왔고

 

신규 DB서버에 sql plus를 이용하여 구서버에서 가져온 sql파일을 실행시켰다.

 

참고로 이 전에 & 같은 특수문자가 들어가면 입력기호로 받아들이는 현상 때문에

 

set define off
@@[sql파일 경로]\[파일이름].sql

 

위처럼 set define off를 먼저 적용시켜준 후 파일을 실행하였다.

 

1. 테이블의 개수가 안 맞았음

insert into 덤프파일을 실행하기 전에 당연히 create table 명령어를 먼저 입력시켜줘야 했다.

 

create table을 모아둔 sql파일을 구서버에 옛날에 저장해두었기 때문에 이를 가지고 신규서버에 적용하였는데

 

table의 개수가 다른 것이다. 신규서버는 243개, 구서버는 244개

 

하나하나 비교하여 확인할 수밖에 없었다.

 

확인 결과 아주 옛날에 사용했던 테이블 하나를 주석처리하여 저장한 것이다.

 

그래서 구서버는 244개, 신규서버는 주석처리되어 243개였던 것이다.

 

이는 현재 사용하지 않는 테이블로 무시할 수 있었다.

 

2. 테이블에 입력된 데이터의 개수가 안 맞음

이후 

 

SELECT TABLE_NAME,
               NUM_ROWS,
               TO_NUMBER(DBMS_XMLGEN.GETXMLTYPE('SELECT COUNT(*) C FROM '||TABLE_NAME).Extract('//text()')) as NUM_ROWS2
FROM USER_TABLES;

위의 명령어를 통해 구서버와 신규서버의 전체 row개수를 비교하였는데

 

10개가 넘는 테이블의 개수가 아예 달랐고

 

심지어 2개의 테이블은 insert가 한 개도 되지 않고 0개인 것이다.

 

개수가 다른 테이블을 확인해 보니

 

공통적으로 빠진 부분의 값에 ' (홑따옴표)가 들어간 것이다.

 

쿼리문이

 

insert into tablename ('col1', 'col2' ...) values ('value1', 'value2', 'value3' ...)

 

이런 식인데 이중에 value의 값이

 

'va'lue' 따옴표의 수가 맞지 않아 오류로 insert가 되지 않은 것이다.

 

그래서

tmp = tmp.replaceAll("'", "''");

위처럼 ' -> ''로 수정하여 입력하면 오류를 해결할 수 있었다.

 

3. 그럼에도 맞지 않은 데이터의 개수

일치하지 않은 테이블의 개수는 줄었으나 여전히 개수가 일치하지 않은 테이블이 존재했으며

 

여전히 2개의 테이블은 값이 하나도 들어가지 않았다.

 

먼저 일치하지 않은 테이블을 좀 더 조정하기 위해 찾아보았다.

 

그 이유는 character set의 변화로 인해 bytes의 차이가 생겼고

 

이로 인해 too long 오류가 발생하는 것을 확인하였다.

 

그래서 차이가 생긴 테이블 몇 개의 column의 사이즈를 넉넉하게 2배씩 늘려주었다.

 

* euc-kr은 한글에 2byte

* al32utf8은 한글에 3byte

 

4. 데이터가 전혀 들어가지 않은 테이블

이제 마지막으로 데이터가 한 개도 들어가지 않은 테이블 2개의 공통점을 찾아보았다.

 

두 테이블의 공통점은 clob 타입의 column을 사용한다는 것이다.

 

대부분 오라클의 데이터 타입은 varchar2를 사용하기 마련이다.

 

하지만 길이가 너무 긴 데이터는 clob 타입을 이용하는데 내가 작성한 배치 프로그램은 clob타입에 대한 별도의 처리가 없었던 것이다.

 

그래서 오류가 발생하였고 아무런 데이터도 들어가지 못했던 것이다.

 

이후 배치 코드의 데이터타입을 읽는 부분을 수정하면서 정상적으로 해결되었다.

 


이제 2년 차에 23년으로 해가 바뀌어 연차로 3년 차가 되었다.

 

군생활로 치면 전역하고 머리도 기를 시간이며 고1이었던 학생이 고3이 되는 긴 시간이다.

 

그동안 일하면서 알게 모르게 자만심도 생겼고 좋게 표현하면 자신감, 나쁘게 표현하면 허세? 일수도 있었다.

 

이날의 마이그레이션 업데이트로 인해 나를 포함하여 직원팀 한분, 내 사수님 한분, 고객사의 담당자분이 다 같이 밤샘을 하게 되었다.

 

이날의 밤샘 여파로 인해 그 다음 스키장을 갈 때 버스를 놓칠 정도로 늦잠을 자게 되었고 몸도 피곤하여 여러 실수가 있었다.

 

많은 분들에게 너무나도 죄송하고 내 실수를 전부 처리해주신 사수님께 감사했다. 심지어 당일 연차였는데 저녁 늦게 단톡방을 보시더니 일을 같이 해주셨다.

 


 

이번 마이그레이션 업무로 인해 잘 몰랐던 오라클에 대해서 알게 되었고

 

캐릭터 셋과 인코딩 타입, 데이터 타입의 길이, 종류 등 많은 생각을 하게 해 주었다.

 

또한 난 그래도 잘하고 있지 않나?라는 자만심을 완벽히 눌러주었으며

 

나쁘게 표현하면 자신감이 줄어든 계기가 되었다.

 

오만하지 않고 자만하지 않으며 방심하지 않고 늘 생각하는 개발자가 되도록 더욱 노력해야겠다.

 

모든 일은 내 생각대로 절대 흘러가주지 않는다라는 것을 다시 상기하게 되었다.

반응형

'일상, 기타 > 일상' 카테고리의 다른 글

코로나 걸린 후기? 중기?  (0) 2022.03.06

댓글