mysql(mariadb 5.5)에 있는 데이터를 oracle(oracle 12c)로 migration

mysql에 있는 데이터를 oracle로 migration하기 위해서는 이미 출시되어 있는 툴을 사용하는 것이 가장 빠르고 효율적이다.

그러나, 선천적으로 이러한 툴 또는 유틸리티에 거부감이 있거나 트라이얼 버전의 설치가 번거롭거나 두려움이 느껴지는 경우 직접 데이터를 옮기는 작업을 선택한다.

직접 데이터를 옮기는 방법은 1. phyton이나 php 등으로 프로그램을 직접 짜서 mysql에서 읽어서 oracle로 insert 하는 방법과 2. mysqldump로 데이터를 다운로드 받아 oracle에서 insert를 하는 방법이 있겠다.

1. phyton, php 등으로 직접 프로그램을 짜는 방법

자기가 잘 아는 방법으로 그냥 프로그램을 짜서 돌린다.

이 때 주의할 점이 있는데 DDL, 즉 oracle의 tablespace나 table, view, index, primary key 정의 등은 mysql과 차이가 있기 때문에 미리 별도의 스크립트로 다 만들어 두어야 한다. 그렇지 않으면 프로그램으로 tablespace, table, index 등등을 만들어주는 프로그램을 직접 다 작성해야 한다.

데이터의 insert 시에도 한글 변환문제, 자릿수 문제, NULL 문제 등을 생각하고 처리해야한다. mysql에서는 ”을 NULL로 인식하지 않지만 oracle에서는 NULL로 인식한다.

2. mysqldump를 사용하는 방법

mysqldump -p -u userid database tablename > table1.sql  등의 방법을 사용한다.

이 때 mysqldump로 dump된 내용은

INSERT INTO `tablename` VALUES (value1, value2, value3, .. ), (value1, value2, value3, ... ), (value1, value2, value3, ... ), ...

와 같이 되어 있다.

이를 변환하여

INSERT INTO `tablename` VALUES (value1, value2, value3, ... ) ;
INSERT INTO `tablename` VALUES (value1, value2, value3,... );
...

와 같은 형식으로 변환하는 것은 귀찮은 작업이므로 다음의 옵션을 준다.

mysqldump --skip-opt --quick -p -u userid database tablename > table1.sql .

skip-opt 옵션 ( –skip-opt )는 –add-drop-table, –add-locks, –create-options, –disable-keys, –extended-insert, –lock-tables, –quick, –set-charset 등의 옵션을 취소시키는 옵션으로 그 중 extended-insert 옵션을 특히 disable 시킴으로 써 INSERT 문장이 개별 문장(한줄씩)으로 생성되도록 하고 drop-table 문장과 create table 문장을 포함시키지 않도록 한다. (실제로는 계속 create table 문장이 포함된다)

그리고 –quick 옵션은 버퍼를 하지 않고 바로 disk에 쓰게 함으로써 대용량 테이블의 경우 메모리 오버플로우가 발생하는 것을 막아준다.

그렇게 생성된 table1.sql을 oracle sqlplus에서 @ 명령으로 실행시켜 주면 테이블 명에 `table_name`과 같은 ` 문자가 포함되어 있어서 에러가 발생한다.

그래서

sed -i 's/`//g' table1.sql

명령으로 `문자를 다 제거해 준 다음 sqlplus에서 @로 실행시켜 준다.

 

sqlplus로 oracle에 데이터를 입력할 때 & 문자는 oracle의 예약어로 변수를 선언하는 예약어이다.

만약 데이터 내에 & 문자가 포함되어 있다면 (예를 들어 ‘School & Campus 와 같이 ) insert를 하다가 갑자기 변수값을 입력을 받기 위한 프롬프트 상태가 되어 버린다.

이런 상태를 방지하기 위해서는 table1.sql 파일 첫 머리에

SET DEFINE OFF; 
SET AUTOCOMMIT 1000;

를 추가해 주어야 한다.

SET AUTOCOMMIT 1000;은 1000 line 마다 commit을 해 주도록 한다. 만약 AUTOCOMMIT이 안되면 모든 INSERT 문은 rollback 가능한 상태로 undo tablespace에 저장되고 속도가 점점 느려진다.

한글 문제

데이터 이전시 한글 문제는 여러모로 골치를 썩히는 일이다. 특히 mysql을 패키지로 설치하고 그냥 쓰는 경우 table의 문자셋을 latin1으로 그냥 둔 경우 default-char-set을 latin1으로 지정해야 한글이 정상적으로 추출되고 oracle 한글 입력도 다양한 파라미터( LANG, NLS_LANG, NLS_CHARACTER 등등)를 설정해야 하므로 테스트를 충분히 해 보고 migration해야 할 것이다.