[Ora2Pg] Oracle to PostgreSQL 데이터베이스 마이그레이션
Oracle에서 PostgreSQL로의 데이터베이스 간 마이그레이션을 하려고 한다.
오픈소스로 무료로 이용이 가능한 Ora2Pg 마이그레이션 도구를 사용해서 진행한다.
(Ora2Pg는 Oracle과 MySQL을 PostgreSQL로 마이그레이션 하는 도구다.)
Oracle과 PostgreSQL은 설치가 이미 되어있다고 가정하고 최대한 복잡하지 않게 진행하려고 한다.
서버 환경, 버전 등에 따라서도 다를 수 있는데, ora2pg 공식문서도 함께 보면 좋을 듯하다.
환경 정보
CentOS Linux release 7.6.1810
PostgreSQL 15.1
Oracle 12.1
1. 마이그레이션에 필요한 항목 설치
1-1. Oracle Instant Client 설치
Oracle Instant Client가 설치되어 있어야 진행이 가능하다.
rpm -ivh oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64.rpm
rpm -ivh oracle-instantclient12.2-devel-12.2.0.1.0-1.x86_64.rpm
rpm -ivh oracle-instantclient12.2-jdbc-12.2.0.1.0-1.x86_64.rpm
rpm -ivh oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm
오라클 공식 페이지에서도 다운로드 가능하니 사용하려는 버전에 맞게 설치하면 된다.
내 경우는 window환경 오라클 공식페이지에서 설치하고 해당 파일들을 SFTP로 옮겨서 설치를 진행했다.
설치받은 rpm을 localinstall 한다.
yum localinstall -y ~/oracle-instantclient12*.rpm
설치가 완료되면 .bash_profile 환경변수를 추가해야 한다.
vi ~/.bash_profile
.bash_profile 아래쪽에 다음과 같이 추가한다. (아래 경로가 생겼는지도 확인)
export ORACLE_HOME=/usr/lib/oracle/12.2/client64
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PAT
export PATH=$ORACLE_HOME/bin:$PATH
수정이 완료되면 source 명령어를 실행하여 적용한다.
source ~/.bash_profile
1-2. perl, postgresql-devel, postgresql-contrib 설치
perl, postgresql-contrib을 설치한다.
yum install -y perl
yum install perl-devel
yum install perl-DBI.x86_64
yum install postgresql15-contrib
1-3. Oracle DBD 설치
다음은 DBD::Oracle을 설치하고 빌드한다.
wget, tar가 없다면 설치하고 진행하면 된다.
DBD-Oracle은 사용하려는 버전에 맞게 받아오고 압축을 풀어 준다.
yum install wget
yum install tar
wget https://cpan.metacpan.org/authors/id/Z/ZA/ZARQUON/DBD-Oracle-1.76.tar.gz
tar -xvzf DBD-Oracle-1.76.tar.gz
압축이 풀린 폴더로 이동해서 빌드해 준다.
cd DBD-Oracle-1.76
perl Makefile.PL
make && make test
make install
2. ora2pg 설치 및 구성
위 내용들이 완료가 되었다면 ora2pg를 설치 및 빌드하면 된다.
2-1. ora2pg 설치 및 빌드
우선 ora2pg github에 올라와 있는 버전을 선택해서 다운받아 압축을 풀어준다. (최신버전 사용)
wget https://github.com/darold/ora2pg/archive/v23.2.tar.gz
tar -xvzf v20.0.tar.gz
해당 폴더로 이동해서 마찬가지로 빌드하면 된다.
cd ora2pg-23.2
perl Makefile.PL
make
make install
2-2. ora2pg Oracle, PostgreSQL설정
간단하게 연결 및 스키마 정보만 설정하고 다른 추가설정은 공식문서를 통해 추가하면 된다.
ora2pg-23.2 폴더로 이동해서 ora2pg.conf.dist 파일을 수정하다.
ORACLE 접속정보를 입력하고 마이그레이션 할 스키마를 입력한다.
ORACLE_DSN dbi:Oracle:host=123.123.123.123;port=1521;service_name=ORCL
ORACLE_USER test
ORACLE_PWD test1234
EXPORT_SCHEMA 1
SCHEMA TEST11
내보내기를 PostgreSQL로 직접 보내려면 PostgreSQL 접속 정보도 함께 입력해 주면 된다.
PG_DSN dbi:Pg:dbname=test_db;호스트=123.123.123.123;포트=5432
PG_USER test
PG_PWD test1234
이제 모든 준비는 완료가 되었는데
버전을 출력하는 테스트를 한번 해보면 정상적으로 버전을 보여준다.
ora2pg -t SHOW_VERSION -c ora2pg.conf.dist
---------------------------------------------
Oracle Database 12c Standard Edition Release 12.2.0.1.0
3. 추정 보고서
ora2pg에서는 Oracle에서 PostgreSQL로의 마이그레이션 비용을 추정할 수 있는 기능을 제공한다.
마이그레이션을 진행하기 전에 비용이 얼마나 예상되는지와
모든 기능, 오브젝트를 검사해서 자동으로 변환할 수 없는 항목이 있는지를 감지한다.
ora2pg -t SHOW_REPORT --estimate_cost -c ora2pg.conf.dist
실행하게 되면 마이그레이션 등급과 여러 개체들에 대한 보고서를 볼 수 있다.
-------------------------------------------------------------------------------
Ora2Pg v23.2 - Database Migration Report
-------------------------------------------------------------------------------
Version Oracle Database 12c Standard Edition Release 12.2.0.1.0
Schema TEST11
Size 8267.75 MB
...중략
-------------------------------------------------------------------------------
Migration level : A-2
-------------------------------------------------------------------------------
Migration levels:
A - Migration that might be run automatically
B - Migration with code rewrite and a human-days cost up to 5 days
C - Migration with code rewrite and a human-days cost above 5 days
Technical levels:
1 = trivial: no stored functions and no triggers
2 = easy: no stored functions but with triggers, no manual rewriting
3 = simple: stored functions and/or triggers, no manual rewriting
4 = manual: no stored functions but with triggers or views with code rewriting
5 = difficult: stored functions and/or triggers with code rewriting
-------------------------------------------------------------------------------
Details of cost assessment per function
Function test_func total estimated cost: 26.7
CONCAT => 46 (cost: 0.1)
SIZE => 14
TRUNC => 11 (cost: 0.1)
ISOPEN => 2 (cost: 1)
TEST => 2
GOTO => 1 (cost: 2)
ROWNUM => 1 (cost: 1)
NOTFOUND => 1
위 내용을 좀 더 보기 쉽게 dump_as_html 옵션을 사용해서 html 문서로 출력할 수도 있다.
ora2pg -t SHOW_REPORT --estimate_cost -c ora2pg.conf --dump_as_html > ~/ora2pg.html
ora2pg.html 파일을 열어보면 더 보기 쉽게 정리가 되어 있는 것을 확인할 수 있다.
등급은 A-1이 가장 쉽고 간단하며 등급이 C-5로 다가갈수록 수작업해야 할 양이 늘어난다.
4. Oracle to PostgreSQL 마이그레이션
4-1. ora2pg 프로젝트 구성
마이그레이션을 하기 위해 먼저 ora2pg 프로젝트를 구성해 준다.
ora2pg --project_base /data1/ora2pg --init_project test
/data1/ora2pg/test 디렉터리가 생성된 것을 확인할 수 있다.
export_schema.sh, import_all.sh 쉘 파일을 이용해서 마이그레이션을 진행해 보자.
4-2. Oracle DDL 스크립트 생성
Oracle의 DDL 스크립트를 생성하려면 export_schema.sh 파일을 실행하면 된다.
./export_schema.sh
여러 오브젝트들의 DDL 스크립트가 생성되는 것을 확인할 수 있다.
[========================>] 14/14 tables (100.0%) end of scanning.
[==> ] 1/11 objects types (9.1%) inspecting object DATABAS
[====> ] 2/11 objects types (18.2%) inspecting object GLOBAL
[======> ] 3/11 objects types (27.3%) inspecting object INDEX
[==========> ] 5/11 objects types (45.5%) inspecting object PROCED
[=============> ] 6/11 objects types (54.5%) inspecting object SEQUEN
[===============> ] 7/11 objects types (63.6%) inspecting object SYNONY
[=================> ] 8/11 objects types (72.7%) inspecting object TABLE
[===================> ] 9/11 objects types (81.8%) inspecting object TRIGGE
[=====================> ] 10/11 objects types (90.9%) inspecting object TYPE
[========================>] 11/11 objects types (100.0%) end of objects auditing.
Running: ora2pg -p -t TABLE -o table.sql -b ./schema/tables -c ./config/ora2pg.conf
[========================>] 14/14 tables (100.0%) end of scanning.
[========================>] 14/14 tables (100.0%) end of table export.
Running: ora2pg -p -t PACKAGE -o package.sql -b ./schema/packages -c ./config/ora2pg.conf
[========================>] 0/0 packages (100.0%) end of output.
Running: ora2pg -p -t VIEW -o view.sql -b ./schema/views -c ./config/ora2pg.conf
[========================>] 1/1 views (100.0%) end of output.
...생략
To extract data use the following command:
ora2pg -t COPY -o data.sql -b ./data -c ./config/ora2pg.conf
To extract data use the following command:
마지막 내용을 보면 데이터를 추출하려면 다음 명령을 사용하라고 한다.
데이터도 같이 마이그레이션 하기 위해서 다음 명령어를 실행한다.
ora2pg -t COPY -o data.sql -b ./data -c ./config/ora2pg.conf
프로젝트 폴더에서 schema, data 폴더 하위에 마이그레이션 관련된 스크립트들이 생성된 것을 확인할 수 있다.
4-3. PostgreSQL DDL 실행 및 데이터 로드
생성된 DDL 스크립트와 데이터들을 마이그레이션 하기 위해 import_all.sh 파일을 실행하면 된다.
./import_all.sh -U test -d TEST11 -p 5432 -o test
마이그레이션이 진행이 되지 않는 항목이 있을 수도 있는데
그럴 경우 해당 작업들은 수작업으로 진행이 필요하다.
Would you like to drop the database TEST11 before recreate it? [y/N/q] y
Running: dropdb -p 5432 -U test TEST11
Running: createdb -p 5432 -U test -E UTF8 --owner test TEST11
Would you like to import TYPE from ./schema/types/type.sql? [y/N/q] y
Running: psql --single-transaction -p 5432 -U test -d TEST11 -f ./schema/types/type.sql
SET
CREATE TYPE
CREATE TYPE
Would you like to import TABLE from ./schema/tables/table.sql? [y/N/q] y
Running: psql --single-transaction -p 5432 -U test -d TEST11 -f ./schema/tables/table.sql
SET
CREATE TABLE
COMMENT
COMMENT
COMMENT
COMMENT
CREATE TABLE
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
CREATE TABLE
CREATE TABLE
CREATE TABLE
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
CREATE TABLE
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
CREATE TABLE
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
CREATE TABLE
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
COMMENT
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE TABLE
Would you like to import VIEW from ./schema/views/view.sql? [y/N/q] y
Running: psql --single-transaction -p 5432 -U test -d TEST11 -f ./schema/views/view.sql
SET
SET
CREATE VIEW
Would you like to import SEQUENCE from ./schema/sequences/sequence.sql? [y/N/q] y
Running: psql --single-transaction -p 5432 -U test -d TEST11 -f ./schema/sequences/sequence.sql
SET
CREATE SEQUENCE
CREATE SEQUENCE
CREATE SEQUENCE
CREATE SEQUENCE
Would you like to import TRIGGER from ./schema/triggers/trigger.sql? [y/N/q] y
Running: psql --single-transaction -p 5432 -U test -d TEST11 -f ./schema/triggers/trigger.sql
SET
SET
psql.bin:./schema/triggers/UPDATE_JOB_HISTORY_trigger.sql:9: NOTICE: trigger "update_job_history" for relation "employees" does not exist, skipping
DROP TRIGGER
CREATE FUNCTION
CREATE TRIGGER
Would you like to import PROCEDURE from ./schema/procedures/procedure.sql? [y/N/q] y
Running: psql --single-transaction -p 5432 -U test -d TEST11 -f ./schema/procedures/procedure.sql
SET
SET
psql.bin:./schema/procedures/ADD_JOB_HISTORY_procedure.sql:20: NOTICE: type reference job_history.employee_id%TYPE converted to integer
psql.bin:./schema/procedures/ADD_JOB_HISTORY_procedure.sql:20: NOTICE: type reference job_history.start_date%TYPE converted to timestamp without time zone
psql.bin:./schema/procedures/ADD_JOB_HISTORY_procedure.sql:20: NOTICE: type reference job_history.end_date%TYPE converted to timestamp without time zone
psql.bin:./schema/procedures/ADD_JOB_HISTORY_procedure.sql:20: NOTICE: type reference job_history.job_id%TYPE converted to character varying
psql.bin:./schema/procedures/ADD_JOB_HISTORY_procedure.sql:20: NOTICE: type reference job_history.department_id%TYPE converted to smallint
CREATE FUNCTION
SET
CREATE FUNCTION
Would you like to process indexes and constraints before loading data? [y/N/q] y
Would you like to import indexes from ./schema/tables/INDEXES_table.sql? [y/N/q] n
Would you like to import constraints from ./schema/tables/CONSTRAINTS_table.sql? [y/N/q] y
Running: psql -p 5432 -U test -d TEST11 -f ./schema/tables/CONSTRAINTS_table.sql
SET
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
Would you like to import foreign keys from ./schema/tables/FKEYS_table.sql? [y/N/q] n
Would you like to import data from Oracle database directly into PostgreSQL? [y/N/q] y
Running: ora2pg -c config/ora2pg.conf -t COPY --pg_dsn "dbi:Pg:dbname=TEST11;host=localhost;port=5432" --pg_user test
[========================>] 14/14 tables (100.0%) end of scanning.
[========================>] 25/25 rows (100.0%) Table COUNTRIES (25 recs/sec)
[> ] 25/136953 total rows (0.0%) - (0 sec., avg: 25 recs/sec).
[> ] 25/136953 rows (0.0%) on total estimated data (1[========================>] 27/27 rows (100.0%) Table DEPARTMENTS (27 recs/sec)
[> ] 52/136953 total rows (0.0%) - (0 sec., avg: 52 recs/sec).
... 생략
진행하다가 혹시나 이런 오류가 발생한다면
ERROR: could not access file "$libdir/uuid-ossp": No such file or directory"
PostgreSQL extension에 관련된 오류라고 생각하면 되는데
사용하는 postgre의 버전에 맞게 postgresql-contrib을 설치하면 해결된다.
yum install postgresql15-contrib
PostgreSQL에 접속에서 확인해 보면 Oracle에서 마이그레이션 된 것을 확인할 수 있었다.
수작업이 필요한 경우 ora2pg 프로젝트 하위에 schema, data 등 스크립트는 생성되어 있으니 적용하면 될 듯하다.
'Database > PostgreSQL' 카테고리의 다른 글
[PostgreSQL] 리눅스에서 postgreSQL 오류 로그 확인하는 방법 (0) | 2023.01.20 |
---|