안녕하세요. 데이터를 이관하다보면 Oracle -> PostgreSQL로 진행하게 되는데요. 이럴때, 사용할 수 있는 Ora2Pg에 설치 방법과 실행 방법에 대해서 정리해보려고 합니다. 해당 내용은 Rocky Linux 9.4 버전으로 진행되고 있는 점을 참고해주시면 좋을 것 같습니다🤗🤗
1. 설치하기
Ora2Pg 21.16.0 버전으로 진행합니다. 해당 링크에 들어가서 맞는 버전으로 `base, sdk` 파일 다운받으면 됩니다.
https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html
Instant Client for Linux x86-64 (64-bit)
Base - one of these packages is required Tools - optional packages Development and Runtime - optional packages
www.oracle.com
1-1. 압축풀기
sudo mkdir -p /opt/oracle/instantclient
sudo unzip instantclient-basic-linux.x64-21.16.0.0dbru.zip -d /opt/oracle/instantclient
sudo unzip instantclient-sdk-linux.x64-21.16.0.0dbru.zip -d /opt/oracle/instantclient
- 다운받은 파일들의 압축을 풀어서 실행을 준비합니다.
1-2. 환경변수 설정하기
echo "export ORACLE_HOME=/opt/oracle/instantclient/instantclient_21_16" >> ~/.bashrc
echo "export LD_LIBRARY_PATH=\$ORACLE_HOME" >> ~/.bashrc
echo "export PATH=\$ORACLE_HOME:\$PATH" >> ~/.bashrc
echo "export C_INCLUDE_PATH=\$ORACLE_HOME/sdk/include" >> ~/.bashrc
echo "export OCI_LIB_DIR=\$ORACLE_HOME" >> ~/.bashrc
echo "export OCI_INC_DIR=\$ORACLE_HOME/sdk/include" >> ~/.bashrc
source ~/.bashrc
1-3. perl-DBD-Oracle 설치하기
sudo dnf install -y perl-CPAN perl-devel gcc
perl -MCPAN -e shell
install DBD::Oracle
exit
- perl -MCPAN -e shell 명령어를 통하여 shell에 들어가서 설치를 진행합니다.
- perl-DBD-Oracle은 dnf로 설치가 안됨으로 따로 설치를 진행하는 것이 좋습니다.
perl -MDBD::Oracle -e 'print $DBD::Oracle::VERSION, "\n";'
- 명령어를 통해서 버전이 나온다면 잘 설치된 것입니다.
1-4. 필요 패키지 설치하기
1-4-1. Perl 패키지 설치하기
sudo dnf install -y perl make gcc perl-DBI perl-DBD-Pg perl-JSON perl-XML-LibXML unzip
- dnf 명령어를 이용하여서 perl에 관련된 패키지들을 설치합니다.
1-4-2. Ora2Pg 설치하기
wget https://github.com/darold/ora2pg/archive/refs/tags/v23.0.tar.gz -O ora2pg.tar.gz
tar -xzf ora2pg.tar.gz
cd ora2pg-23.0
# Perl 모듈 설치
perl Makefile.PL
# Ora2Pg 빌드 및 설치
make
sudo make install
# 설치 확인
ora2pg --version
- perl 모듈을 설치한 후에 Ora2Pg를 설치할 수 있습니다.
- 설치가 완료되었다면, 버전 체크를 통해서 설치가 완료되었는지 확인합니다.
1-4-3. PostgreSQL 설치하기
sudo dnf install postgresql
- PostgreSQL도 사용됨으로 dnf를 이용하여 같이 설치해줍니다.
2. Ora2Pg 프로젝트 구성
2-1. Ora2Pg 프로젝트 위치 설정
ora2pg --project_base [원하는 경로] --init_project [원하는 프로젝트 이름]
- ora2pg 명령어를 사용하여 프로젝트를 원하는 경로와 원하는 이름으로 시작합니다.
2-2. Ora2Pg 설정
2-2-1. Ora2Pg conf 파일 복사
cp /etc/ora2pg/ora2pg.conf.dist [위에서 지정한 경로]/[프로젝트 이름]/config/ora2pg.conf
- 설치시에 생성된 conf 파일이 아닌 사용자가 지정한 conf 를 사용하기 위해서 원본을 가지고 있고 cp 명령어를 통해서 복사해줍니다.
2-2-2. Ora2Pg conf 설정
# COPY를 이용해서 데이터를 복사
USE_COPY YES
# Oracle 설치 환경 변수 지정
ORACLE_HOME /opt/oracle/instantclient/instantclient_21_16
# Oracle host, port, service name 혹은 SID 지정
ORACLE_DSN dbi:[HOST];port=[PORT];service_name=[SERVICE_NAME];
# Oracle User, Password
ORACLE_USER [ORACLE_USER]
ORACLE_PWD [ORACLE_PWD]
# Oracle Schema, 지정안하면 다 가져옴
SCHEMA [SCHEMA]
# PG dbname, host, port 지정
PG_DSN dbi:Pg:dbname=[DBNAME];host=[HOST];port=[PORT]
# PG User, Password
PG_USER [PG_USER]
PG_PWD [PG_PWD]
# 전체 가져오기
FULL_EXPORT 1
# 전체 내용 가져오기(TABLE, QUERY 등)
TYPE FULL
# 테이블을 지정
ALLOW [TABLE_NAME]
# Debug를 같이 보고 싶으면 1로 변경
DEBUG 0
# Schema 사용
EXPORT_SCHEMA 1
- 첨부한 파일에는 전체적인 conf 파일의 내용들이 다 들어가있습니다.
- 현재 따로 코드로 나타낸 부분들이 기존의 내용에서 변경을 진행한 부분들입니다.
- 설정에 맞게 Oracle, PostgreSQL Host, Port, Schema, ID, PW, 테이블 지정들을 고려해서 작성해야합니다.
- TYPE 내용은 밑의 링크를 통해서 확인할 수 있습니다.
3. PostgreSQL 권한 설정
# 유저 생성하기 - 슈퍼 유저 혹은 SYS에 들어가서 실행
CREATE USER [USER] WITH PASSWORD 'your_password';
# 데이터베이스 생성 및 소유자 지정
CREATE DATABASE [DATABASE] OWNER [USER];
# 특정 데이터베이스에 대한 모든 권한 부여
GRANT ALL PRIVILEGES ON DATABASE [DATABASE] TO [USER];
# 특정 스키마 대한 권한 부여 - database에 들어가서 실행
\c [DATABASE]
CREATE SCHEMA datamart AUTHORIZATION [USER];
GRANT ALL ON SCHEMA datamart TO [USER];
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO [USER];
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO [USER];
SET search_path TO [USER],public;
- ora2pg.conf에서 설정한 Schema를 기준으로 PostgreSQL에 Schema 이름과 동일한 User와 Schema가있어야합니다.
- PostgreSQL에서 유저를 생성하고 해당 유저에게 Schema에 대한 권한을 부여합니다.
4. Oracle 권한 설정
CREATE USER [USER] IDENTIFIED BY [PWD];
GRANT CONNECT TO [USER];
GRANT RESOURCE TO [USER];
GRANT SELECT ANY TABLE TO [USER];
GRANT SELECT ANY DICTIONARY TO [USER];
GRANT SELECT ON ALL_TABLES TO [USER];
GRANT SELECT ON ALL_INDEXES TO [USER];
GRANT SELECT ON ALL_CONSTRAINTS TO [USER];
GRANT SELECT ON ALL_SEQUENCES TO [USER];
GRANT SELECT ON ALL_TAB_COLUMNS TO [USER];
- Oralce에서도 마찬가지로 유저를 생성하고 유저에게 ora2pg를 하기 위한 권한을 설정해줍니다.
- PostgreSQL과 Oracle에서 생성한 유저 모두 ora2pg.conf에 포함되어있어야합니다.
5. Ora2Pg 연결 확인하기
ora2pg -t SHOW_VERSION -c config/ora2pg.conf
- 오류가 안나고 버전이 나오면 잘 연결된 것입니다.
ora2pg -t SHOW_REPORT -c config/ora2pg.conf --estimate_cost --dump_as_html > migration_report.html
- migration_report.html 이 생기게 되는데, 크롬으로 열어보면 해당 Schema를 옮기는데 어느 정도의 난이도인지를 확인할 수 있습니다.
6. Export 하기(Oracle -> Ora2Pg)
#!/bin/sh
#-------------------------------------------------------------------------------
#
# Generated by Ora2Pg, the Oracle database Schema converter, version 23.0
#
#-------------------------------------------------------------------------------
EXPORT_TYPE="SEQUENCE TABLE PACKAGE VIEW GRANT TRIGGER FUNCTION PROCEDURE TABLESPACE PARTITION TYPE MVIEW DBLINK SYNONYM DIRECTORY"
SOURCE_TYPE="PACKAGE VIEW TRIGGER FUNCTION PROCEDURE PARTITION TYPE MVIEW"
namespace="."
unit_cost=5
script_start_time=$(date +%s)
echo "Script started at: $(date)"
ora2pg -t SHOW_TABLE -c $namespace/config/ora2pg.conf > $namespace/reports/tables.txt
ora2pg -t SHOW_COLUMN -c $namespace/config/ora2pg.conf > $namespace/reports/columns.txt
ora2pg -t SHOW_REPORT -c $namespace/config/ora2pg.conf --dump_as_html --cost_unit_value $unit_cost --estimate_cost > $namespace/reports/report.html
for etype in $(echo $EXPORT_TYPE | tr " " "\n")
do
ltype=`echo $etype | tr '[:upper:]' '[:lower:]'`
ltype=`echo $ltype | sed 's/y$/ie/'`
echo "Running: ora2pg -p -t $etype -o $ltype.sql -b $namespace/schema/${ltype}s -c $namespace/config/ora2pg.conf"
ora2pg -p -t $etype -o $ltype.sql -b $namespace/schema/${ltype}s -c $namespace/config/ora2pg.conf
ret=`grep "Nothing found" $namespace/schema/${ltype}s/$ltype.sql 2> /dev/null`
if [ ! -z "$ret" ]; then
rm $namespace/schema/${ltype}s/$ltype.sql
fi
done
for etype in $(echo $SOURCE_TYPE | tr " " "\n")
do
ltype=`echo $etype | tr '[:upper:]' '[:lower:]'`
ltype=`echo $ltype | sed 's/y$/ie/'`
echo "Running: ora2pg -t $etype -o $ltype.sql -b $namespace/sources/${ltype}s -c $namespace/config/ora2pg.conf"
ora2pg -t $etype -o $ltype.sql -b $namespace/sources/${ltype}s -c $namespace/config/ora2pg.conf
ret=`grep "Nothing found" $namespace/sources/${ltype}s/$ltype.sql 2> /dev/null`
if [ ! -z "$ret" ]; then
rm $namespace/sources/${ltype}s/$ltype.sql
fi
done
echo
echo
echo "To extract data use the following command:"
echo
echo "ora2pg -t COPY -o data.sql -b $namespace/data -c $namespace/config/ora2pg.conf"
echo
script_end_time=$(date +%s)
script_elapsed_time=$(($script_end_time - $script_start_time))
echo "Script ended at: $(date)"
echo "Total script execution time: $script_elapsed_time seconds"
exit 0
./export_schema.sh
- project안에 생성된 `export_schema.sh` 파일을 실행해서 테이블의 스키마를 받아올 수 있습니다.
- 현재 코드안에 실행 시간을 확인할 수 있도록 시간을 찍을 수 있게 추가해놓았습니다.
- Export가 완료되면, schema 폴더 -> tables 폴더 -> table.sql 이 생성된 것을 확인할 수 있습니다.
7. Import 하기(Ora2Pg -> PostgreSQL)
#!/bin/sh
#-------------------------------------------------------------------------------
#
# Script used to load exported sql files into PostgreSQL in practical manner
# allowing you to chain and automatically import schema and data.
#
# Generated by Ora2Pg, the Oracle database Schema converter, version 23.0
#
#-------------------------------------------------------------------------------
EXPORT_TYPE="TYPE SEQUENCE TABLE PACKAGE VIEW GRANT TRIGGER FUNCTION PROCEDURE TABLESPACE PARTITION MVIEW DBLINK SYNONYM DIRECTORY"
AUTORUN=0
NAMESPACE=.
NO_CONSTRAINTS=0
IMPORT_INDEXES_AFTER=0
DEBUG=0
IMPORT_SCHEMA=0
IMPORT_DATA=0
IMPORT_CONSTRAINTS=0
NO_DBCHECK=0
script_start_time=$(date +%s)
echo "Script started at: $(date)"
# Message functions
die() {
echo "ERROR: $1" 1>&2
exit 1
}
usage() {
echo "usage: `basename $0` [options]"
echo ""
echo "Script used to load exported sql files into PostgreSQL in practical manner"
echo "allowing you to chain and automatically import schema and data."
echo ""
echo "options:"
echo " -a import data only"
echo " -b filename SQL script to execute just after table creation to fix database schema"
echo " -d dbname database name for import"
echo " -D enable debug mode, will only show what will be done"
echo " -e encoding database encoding to use at creation (default: UTF8)"
echo " -f force no check of user and database existing and do not try to create them"
echo " -h hostname hostname of the PostgreSQL server (default: unix socket)"
echo " -i only load indexes, constraints and triggers"
echo " -I do not try to load indexes, constraints and triggers"
echo " -j cores number of connection to use to import data or indexes into PostgreSQL"
echo " -n schema comma separated list of schema to create"
echo " -o username owner of the database to create"
echo " -p port listening port of the PostgreSQL server (default: 5432)"
echo " -P cores number of tables to process at same time for data import"
echo " -s import schema only, do not try to import data"
echo " -t export comma separated list of export type to import (same as ora2pg)"
echo " -U username username to connect to PostgreSQL (default: peer username)"
echo " -x import indexes and constraints after data"
echo " -y reply Yes to all questions for automatic import"
echo
echo " -? print help"
echo
exit $1
}
# Function to emulate Perl prompt function
confirm () {
msg=$1
if [ "$AUTORUN" != "0" ]; then
true
else
if [ -z "$msg" ]; then
msg="Are you sure? [y/N/q]"
fi
# call with a prompt string or use a default
read -r -p "${msg} [y/N/q] " response
case $response in
[yY][eE][sS]|[yY])
true
;;
[qQ][uU][iI][tT]|[qQ])
exit
;;
*)
false
;;
esac
fi
}
# Function used to import constraints and indexes
import_constraints () {
if [ -r "$NAMESPACE/schema/tables/INDEXES_table.sql" ]; then
if confirm "Would you like to import indexes from $NAMESPACE/schema/tables/INDEXES_table.sql?" ; then
if [ -z "$IMPORT_JOBS" ]; then
echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/INDEXES_table.sql"
if [ $DEBUG -eq 0 ]; then
psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/INDEXES_table.sql
if [ $? -ne 0 ]; then
die "can not import indexes."
fi
fi
else
echo "Running: ora2pg -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/INDEXES_table.sql"
if [ $DEBUG -eq 0 ]; then
ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/INDEXES_table.sql
if [ $? -ne 0 ]; then
die "can not import indexes."
fi
fi
fi
fi
fi
if [ -r "$NAMESPACE/schema/tables/CONSTRAINTS_table.sql" ]; then
if confirm "Would you like to import constraints from $NAMESPACE/schema/tables/CONSTRAINTS_table.sql?" ; then
if [ -z "$IMPORT_JOBS" ]; then
echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/CONSTRAINTS_table.sql"
if [ $DEBUG -eq 0 ]; then
psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/CONSTRAINTS_table.sql
if [ $? -ne 0 ]; then
die "can not import constraints."
fi
fi
else
echo "Running: ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/CONSTRAINTS_table.sql"
if [ $DEBUG -eq 0 ]; then
ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/CONSTRAINTS_table.sql
if [ $? -ne 0 ]; then
die "can not import constraints."
fi
fi
fi
fi
fi
if [ -r "$NAMESPACE/schema/tables/FKEYS_table.sql" ]; then
if confirm "Would you like to import foreign keys from $NAMESPACE/schema/tables/FKEYS_table.sql?" ; then
if [ -z "$IMPORT_JOBS" ]; then
echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/FKEYS_table.sql"
if [ $DEBUG -eq 0 ]; then
psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/FKEYS_table.sql
if [ $? -ne 0 ]; then
die "can not import foreign keys."
fi
fi
else
echo "Running: ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/FKEYS_table.sql"
if [ $DEBUG -eq 0 ]; then
ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/FKEYS_table.sql
if [ $? -ne 0 ]; then
die "can not import foreign keys."
fi
fi
fi
fi
fi
if [ -r "$NAMESPACE/schema/triggers/trigger.sql" ]; then
if confirm "Would you like to import TRIGGER from $NAMESPACE/schema/triggers/trigger.sql?" ; then
echo "Running: psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/triggers/trigger.sql"
if [ $DEBUG -eq 0 ]; then
psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/triggers/trigger.sql
if [ $? -ne 0 ]; then
die "an error occurs when importing file $NAMESPACE/schema/triggers/trigger.sql."
fi
fi
fi
fi
}
# Command line options
while getopts "b:d:e:h:j:l:n:o:p:P:t:U:aDfiIsyx?" opt; do
case "$opt" in
a) IMPORT_DATA=1;;
b) SQL_POST_SCRIPT=$OPTARG;;
d) DB_NAME=$OPTARG;;
D) DEBUG=1;;
e) DB_ENCODING=" -E $OPTARG";;
f) NO_DBCHECK=1;;
h) DB_HOST=" -h $OPTARG";;
i) IMPORT_CONSTRAINTS=1;;
I) NO_CONSTRAINTS=1;;
j) IMPORT_JOBS=" -j $OPTARG";;
n) DB_SCHEMA=$OPTARG;;
o) DB_OWNER=$OPTARG;;
p) DB_PORT=" -p $OPTARG";;
P) PARALLEL_TABLES=" -P $OPTARG";;
s) IMPORT_SCHEMA=1;;
t) EXPORT_TYPE=$OPTARG;;
U) DB_USER=" -U $OPTARG";;
x) IMPORT_INDEXES_AFTER=1;;
y) AUTORUN=1;;
"?") usage 1;;
*) die "Unknown error while processing options";;
esac
done
# Check if post tables import SQL script is readable
if [ ! -z "$SQL_POST_SCRIPT" ]; then
if [ ! -r "$SQL_POST_SCRIPT" ]; then
die "the SQL script $SQL_POST_SCRIPT is not readable."
fi
fi
# A database name is mandatory
if [ -z "$DB_NAME" ]; then
die "you must give a PostgreSQL database name (see -d option)."
fi
# A database owner is mandatory
if [ -z "$DB_OWNER" ]; then
die "you must give a username to be used as owner of database (see -o option)."
fi
# Check if the project directory is readable
if [ ! -r "$NAMESPACE/schema/tables/table.sql" ]; then
die "project directory '$NAMESPACE' is not valid or is not readable."
fi
# If constraints and indexes files are present propose to import these objects
if [ $IMPORT_CONSTRAINTS -eq 1 ]; then
if confirm "Would you like to load indexes, constraints and triggers?" ; then
import_constraints
fi
exit 0
fi
# When a PostgreSQL schema list is provided, create them
if [ $IMPORT_DATA -eq 0 ]; then
is_superuser='f'
if [ $NO_DBCHECK -eq 0 ]; then
# Create owner user
user_exists=`psql -d $DB_NAME$DB_HOST$DB_PORT$DB_USER -Atc "select usename from pg_user where usename='$DB_OWNER';" 2>/dev/null`
is_superuser=`psql -d $DB_NAME$DB_HOST$DB_PORT$DB_USER -Atc "select usesuper from pg_user where usename='$DB_OWNER';" 2>/dev/null`;
if [ "a$user_exists" = "a" ]; then
if confirm "Would you like to create the owner of the database $DB_OWNER?" ; then
echo "Running: createuser$DB_HOST$DB_PORT$DB_USER --no-superuser --no-createrole --no-createdb $DB_OWNER"
if [ $DEBUG -eq 0 ]; then
createuser$DB_HOST$DB_PORT$DB_USER --no-superuser --no-createrole --no-createdb $DB_OWNER
if [ $? -ne 0 ]; then
die "can not create user $DB_OWNER."
fi
fi
fi
else
echo "Database owner $DB_OWNER already exists, skipping creation."
fi
# Create database if required
if [ "a$DB_ENCODING" = "a" ]; then
DB_ENCODING=" -E UTF8"
fi
db_exists=`psql -d $DB_NAME$DB_HOST$DB_PORT$DB_USER -Atc "select datname from pg_database where datname='$DB_NAME';"`
if [ "a$db_exists" = "a" ]; then
if confirm "Would you like to create the database $DB_NAME?" ; then
echo "Running: createdb$DB_HOST$DB_PORT$DB_USER$DB_ENCODING --owner $DB_OWNER $DB_NAME"
if [ $DEBUG -eq 0 ]; then
createdb$DB_HOST$DB_PORT$DB_USER$DB_ENCODING --owner $DB_OWNER $DB_NAME
if [ $? -ne 0 ]; then
die "can not create database $DB_NAME."
fi
fi
fi
else
if confirm "Would you like to drop the database $DB_NAME before recreate it?" ; then
echo "Running: dropdb$DB_HOST$DB_PORT$DB_USER $DB_NAME"
if [ $DEBUG -eq 0 ]; then
dropdb$DB_HOST$DB_PORT$DB_USER $DB_NAME
if [ $? -ne 0 ]; then
die "can not drop database $DB_NAME."
fi
fi
echo "Running: createdb$DB_HOST$DB_PORT$DB_USER$DB_ENCODING --owner $DB_OWNER $DB_NAME"
if [ $DEBUG -eq 0 ]; then
createdb$DB_HOST$DB_PORT$DB_USER$DB_ENCODING --owner $DB_OWNER $DB_NAME
if [ $? -ne 0 ]; then
die "can not create database $DB_NAME."
fi
fi
fi
fi
fi
# When schema list is provided, create them
if [ "a$DB_SCHEMA" != "a" ]; then
nspace_list=''
for enspace in $(echo $DB_SCHEMA | tr "," "\n")
do
lnspace=`echo $enspace | tr '[:upper:]' '[:lower:]'`
if confirm "Would you like to create schema $lnspace in database $DB_NAME?" ; then
echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -c \"CREATE SCHEMA $lnspace;\""
if [ $DEBUG -eq 0 ]; then
psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -c "CREATE SCHEMA $lnspace;"
if [ $? -ne 0 ]; then
die "can not create schema $DB_SCHEMA."
fi
fi
nspace_list="$nspace_list$lnspace,"
fi
done
# Change search path of the owner
if [ "a$nspace_list" != "a" ]; then
if confirm "Would you like to change search_path of the database owner?" ; then
echo "Running: psql$DB_HOST$DB_PORT$DB_USER -d $DB_NAME -c \"ALTER ROLE $DB_OWNER SET search_path TO ${nspace_list}public;\""
if [ $DEBUG -eq 0 ]; then
psql$DB_HOST$DB_PORT$DB_USER -d $DB_NAME -c "ALTER ROLE $DB_OWNER SET search_path TO ${nspace_list}public;"
if [ $? -ne 0 ]; then
die "can not change search_path."
fi
fi
fi
fi
fi
# Then import all files from project directory
for etype in $(echo $EXPORT_TYPE | tr "," "\n")
do
if [ $NO_CONSTRAINTS -eq 1 ] && [ $etype = "TRIGGER" ]; then
continue
fi
if [ $etype = "GRANT" ] || [ $etype = "TABLESPACE" ]; then
continue
fi
ltype=`echo $etype | tr '[:upper:]' '[:lower:]'`
ltype=`echo $ltype | sed 's/y$/ie/'`
if [ -r "$NAMESPACE/schema/${ltype}s/$ltype.sql" ]; then
if confirm "Would you like to import $etype from $NAMESPACE/schema/${ltype}s/$ltype.sql?" ; then
echo "Running: psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/${ltype}s/$ltype.sql"
if [ $DEBUG -eq 0 ]; then
psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/${ltype}s/$ltype.sql
if [ $? -ne 0 ]; then
die "an error occurs when importing file $NAMESPACE/schema/${ltype}s/$ltype.sql."
fi
fi
fi
fi
if [ ! -z "$SQL_POST_SCRIPT" ] && [ $etype = "TABLE" ]; then
if confirm "Would you like to execute SQL script $SQL_POST_SCRIPT?" ; then
echo "Running: psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $SQL_POST_SCRIPT"
if [ $DEBUG -eq 0 ]; then
psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $SQL_POST_SCRIPT
if [ $? -ne 0 ]; then
die "an error occurs when importing file $SQL_POST_SCRIPT."
fi
fi
fi
fi
done
# If constraints and indexes files are present propose to import these objects
if [ $NO_CONSTRAINTS -eq 0 ] && [ $IMPORT_INDEXES_AFTER -eq 0 ]; then
if confirm "Would you like to process indexes and constraints before loading data?" ; then
IMPORT_INDEXES_AFTER=0
import_constraints
else
IMPORT_INDEXES_AFTER=1
fi
fi
# When the database owner is not superuser use postgres instead
q_user='postgres'
if [ "$is_superuser" = "t" ]; then
q_user=$DB_OWNER
fi
# Import objects that need superuser privilege: GRANT and TABLESPACE
if [ -r "$NAMESPACE/schema/grants/grant.sql" ]; then
if confirm "Would you like to import GRANT from $NAMESPACE/schema/grants/grant.sql?" ; then
echo "Running: psql $DB_HOST$DB_PORT -U $q_user -d $DB_NAME -f $NAMESPACE/schema/grants/grant.sql"
if [ $DEBUG -eq 0 ]; then
psql $DB_HOST$DB_PORT -U $q_user -d $DB_NAME -f $NAMESPACE/schema/grants/grant.sql
if [ $? -ne 0 ]; then
die "an error occurs when importing file $NAMESPACE/schema/grants/grant.sql."
fi
fi
fi
fi
if [ -r "$NAMESPACE/schema/tablespaces/tablespace.sql" ]; then
if confirm "Would you like to import TABLESPACE from $NAMESPACE/schema/tablespaces/tablespace.sql?" ; then
echo "Running: psql $DB_HOST$DB_PORT -U $q_user -d $DB_NAME -f $NAMESPACE/schema/tablespaces/tablespace.sql"
if [ $DEBUG -eq 0 ]; then
psql $DB_HOST$DB_PORT -U $q_user -d $DB_NAME -f $NAMESPACE/schema/tablespaces/tablespace.sql
if [ $? -ne 0 ]; then
die "an error occurs when importing file $NAMESPACE/schema/tablespaces/tablespace.sql."
fi
fi
fi
fi
fi
# Check if we must just import schema or proceed to data import too
if [ $IMPORT_SCHEMA -eq 0 ]; then
# set the PostgreSQL datasource
pgdsn_defined=`grep "^PG_DSN" config/ora2pg.conf | sed 's/.*dbi:Pg/dbi:Pg/'`
if [ "a$pgdsn_defined" = "a" ]; then
if [ "a$DB_HOST" != "a" ]; then
pgdsn_defined="dbi:Pg:dbname=$DB_NAME;host=$DB_HOST"
else
#default to unix socket
pgdsn_defined="dbi:Pg:dbname=$DB_NAME;"
fi
if [ "a$DB_PORT" != "a" ]; then
pgdsn_defined="$pgdsn_defined;port=$DB_PORT"
else
pgdsn_defined="$pgdsn_defined;port=5432"
fi
fi
# remove command line option from the DSN string
pgdsn_defined=`echo "$pgdsn_defined" | sed 's/ -. //g'`
# If data file is present propose to import data
if [ -r "$NAMESPACE/data/data.sql" ]; then
if confirm "Would you like to import data from $NAMESPACE/data/data.sql?" ; then
echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/data/data.sql"
if [ $DEBUG -eq 0 ]; then
psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/data/data.sql
if [ $? -ne 0 ]; then
die "an error occurs when importing file $NAMESPACE/data/data.sql."
fi
fi
fi
else
# Import data directly from PostgreSQL
if confirm "Would you like to import data from Oracle database directly into PostgreSQL?" ; then
echo "Running: ora2pg$IMPORT_JOBS$PARALLEL_TABLES -c config/ora2pg.conf -t COPY --pg_dsn \"$pgdsn_defined\" --pg_user $DB_OWNER"
if [ $DEBUG -eq 0 ]; then
ora2pg$IMPORT_JOBS$PARALLEL_TABLES -c config/ora2pg.conf -t COPY --pg_dsn "$pgdsn_defined" --pg_user $DB_OWNER -j 16 -L 50000
if [ $? -ne 0 ]; then
die "an error occurs when importing data."
fi
fi
fi
fi
if [ $NO_CONSTRAINTS -eq 0 ] && [ $IMPORT_DATA -eq 0 ]; then
# Import indexes and constraint after data
if [ $IMPORT_INDEXES_AFTER -eq 1 ]; then
import_constraints
fi
fi
fi
script_end_time=$(date +%s)
script_elapsed_time=$(($script_end_time - $script_start_time))
echo "Script ended at: $(date)"
echo "Total script execution time: $script_elapsed_time seconds"
exit 0
PGPASSWORD='[PG 비밀번호]' ./import_all.sh -h [PG host] \
-p [PG port] \
-U [PG user] \
-o [PG owner] \
-d [PG database]
- project안에 생성된 `import_all.sh` 파일을 실행해서 테이블을 생성하고 데이터를 넣을 수 있습니다.
- 실행하기 위해서는 PostgreSQL의 해당하는 내용들을 적어주어야합니다.
- host, user, password, user, owner, database
- 현재 파일에는 안에 실행 시간을 확인할 수 있도록 시간을 찍을 수 있게 추가해놓았습니다
- -j / -p등 옵션을 추가해서 처리 속도를 높일 수 있습니다.
- `ora2pg$IMPORT_JOBS$PARALLEL_TABLES -c config/ora2pg.conf -t COPY --pg_dsn "$pgdsn_defined" --pg_user $DB_OWNER -j 16 -L 50000`
- 파일안에 들어가면 밑의 부분에 COPY 명령어를 통해서 데이터를 넣는 부분이 있습니다. 해당 부분에서는 옵션을 추가해서 사용할 수 있습니다.
- `-j` : 작업 단위 병렬 처리, 테이블 작업의 대한 병렬 처리, 일반적으로 CPU 코어 수의 50~75%로 설정합니다.
- `-p` : 테이블 단위 병렬 처리, 테이블당 병렬 처리를 진행할 수 있습니다.
- `-L` : 한 번에 추출할 데이터의 최대 행(row) 수를 제한, 과부화를 방지합니다.
- 해당 파일을 실행하면, y or n을 입력해서 진행하는데 directories 부분은 파일의 내용이 없으면 에러가 남으로 n을 눌러서 넘겨줍니다.
이렇게 진행해보면, Ora2Pg가 작동되는 것을 실시간으로 볼 수 있습니다. 처음에 설치하는 과정이 어렵지만, 한번 설정을 진행해놓으면 명령어를 통해서 쉽게 데이터를 이관할 수 있는 장점이 있습니다. 가끔 사용자 지정 인덱스들이 이관되지 않는 일도 있으니 주의하시기 바랍니다. 보다 쉽게 데이터를 이관하시기를 바라면, 해당 내용이 여러분의 궁금증에 도움이 되었기를 바랍니다. 다음에도 더 유익한 내용으로 찾아오겠습니다!🤓🤓
'챱챱' 카테고리의 다른 글
| [Kubernetes] RBAC 설정 알아보기 (0) | 2025.03.30 |
|---|---|
| [Airflow] Oralce, Kafka Connection 설치 및 설정하기 (0) | 2025.03.02 |
| [Airflow] Kubernetes에서 Airflow 설치하기 (1) | 2025.02.02 |
| [서평] 데이터 엔지니어를 위한 97가지 조언 (2) | 2025.01.05 |
| [챱챱] ML엔지니어 -> 데이터 엔지니어로 Change (0) | 2024.11.24 |