Oracle Data Pump와 DMS를 사용해 Oracle DB를 RDS로 마이그레이션 하기(1)

Sojeong Baek
Cloud Villains
Published in
13 min readJan 28, 2023

지난 게시글인 MySQL DB 이관 가이드에 이어, 이번 가이드에서는 온프레미스 Oracle DB에서 AWS RDS for Oracle로의 DB 이관 방법에 대해 알아보겠습니다.

1. Oracle Data Pump로 스키마 이관하기

📕시나리오

EC2를 소스 DB가 설치된 온프레미스 서버라고 가정합니다. 해당 서버 내에는 sqlplus가 설치되어 있으며 샘플 데이터가 저장되어 있습니다. 또한 온프레미스 네트워크와 AWS VPC 간 통신이 가능하도록 양 VPC 간 Site-to-Site VPN가 생성되어 있습니다. 덤프 파일을 로컬에서 생성하고 AWS S3로 전송하며, S3에서 RDS로 데이터를 업로드 및 import하여 마이그레이션을 진행할 예정입니다.

  • 소스 DB: 온프레미스 서버 내 설치된 Oracle Database 12c Enterprise Edition Release 12.1.0.2.0–64bit Production
  • SID: TEST
  • 스키마: TESTUSR(약 1GB)
  • User: scott
  • P/W: tiger

1) Full load

소스 DB가 설치된 서버에 접속해 sqlplus 클라이언트 툴로 오라클 DB에 접속합니다.

sqlplus / as sysdba 

비밀번호 입력 창에서는 엔터를 입력합니다.

아래 커맨드로 현재 DB 이름과 스키마들을 확인합니다. 오라클에서는 유저가 스키마입니다.

SELECT NAME FROM v$database;
SELECT DISTINCT(OWNER) FROM ALL_ALL_TBLES;

현재 접속되어 있는 TEST DB 내 TESTUSR 스키마에 대한 덤프 파일을 생성 및 RDS로 이관해보도록 하겠습니다.

아래 커맨드로 유저 계정의 lock을 해제하여 덤프 파일 이관에 사용할 scott 유저를 생성합니다.

ALTER USER &A IDENTIFIED BY &B ACCOUNT UNLOCK;

아래 커맨드로 덤프 파일 생성에 필요한 권한을 부여하고 디렉토리를 생성합니다.

GRANT EXP_FULL_DATABASE TO scott; GRANT IMP_FULL_DATABSE TO scott; 
GRANT READ, WRITE ON DIRECTORY DUMP TO scott;
GRANT CREATE ANY DIRECTORY TO scott;
CREATE DIRECTORY DUMP AS ‘/oracle/dumpfile’;
ALTER SESSION SET CURRENT_SCHEMA = TESTUSR;
GRANT SELECT, INSERT, UPDATE, DELETE ON TESTUSR.ITEM TO scott;
GRANT SELECT, INSERT, UPDATE, DELETE ON TESTUSR.CUSTOMER TO scott;

그 후 아래 커맨드로 디렉토리가 잘 생성되었는지 확인합니다.

SELECT directory_name, directory_path FROM dba_directories WHERE directory_name=’DUMP’;

DB에서 빠져나와 아래 커맨드로 소스 DB가 설치된 서버 내에 oracle 디렉토리 및 dumpfile 디렉토리를 생성합니다.

마찬가지로 oracle 디렉토리 내 dumpfile이 생성된 것을 확인합니다.

cd /
pwd
sudo mkdir oracle
sudo mkdir oracle/dumpfile

이때 생성하는 디렉토리는 오라클 서버 내 만든 디렉토리 위치와 같게 만들어야 합니다. 디렉토리 위치를 유의해서 생성해주세요!

아래 커맨드로 ec2-user가 방금 생성한 oracle 및 dumpfile 디렉토리의 소유자가 되게 합니다.

sudo chown -R ec2-user:ec2-user oracle

덤프 파일을 만들기 위한 모든 준비는 끝났습니다! 아래 커맨드로 소스 DB의 덤프 파일을 생성합니다. 아래 커맨드는 스키마 내 테이블과 인덱스만 포함한 백업 파일을 export합니다.

expdp scott/tiger dumpfile=test.dmp directory=dump schemas=TESTUSR job_name=test logfile=test.log

*참고

1) 오라클 DB 내 모든 스키마를 export 하려면 아래 커맨드를 사용합니다. 해당 커맨드는 마스터 유저인 system으로 명령어를 실행해 DB 내 전체 스키마의 덤프 파일을 export하는 커맨드입니다.

expdp system/oracle dumpfile=full.dmp directory=dump full=y logfile=full.log job_name=fullexp

2) FLASHBACK_SCN 옵션을 사용하면 특정 SCN 지점을 선택하여 해당 지점 이후에 대한 데이터 덤프를 생성할 수 있습니다.

expdp scott/tiger dumpfile=cdc.dmp directory=dump schemas=TESTUSR job_name=cdc logfile=cdc.log FLASHBACK_SCN=${SCN 번호}

덤프 파일 export가 끝났다고 메세지가 나오면 dumpfile 디렉토리에서 파일을 확인합니다.

cat으로 파일을 열어보면 읽을 수 없는 형태로 변환된 것을 확인할 수 있습니다.

생성한 덤프파일을 S3에 업로드해볼텐데요, 이에 앞서 프라이빗 서브넷에 위치한 인스턴스와 S3가 통신할 수 있게 VPC 페이지 Endpoint 탭으로 이동해 VPC endpoint를 생성합니다.

S3 Gateway endpoint 선택 후, IDC 온프레미스 서버가 위치한 VPC 및 라우팅 테이블을 선택합니다.

Endpoint가 생성되면 선택한 라우팅 테이블에서 S3와 통신할 때 생성한 endpoint를 통하도록 route table이 자동으로 수정됩니다.

Endpoint가 연결되었으니 온프레미스 서버에서 S3로 프라이빗 통신이 가능해졌습니다. S3로 덤프 파일을 업로드 하기 위해 온프레미스 서버 내에서 aws cli로 접속합니다.

아래 커맨드로 덤프 파일 디렉토리 내 덤프 파일을 S3 버킷으로 복사합니다.

aws s3 cp /oracle/dumpfile/test.dmp s3://${S3 버킷명}
aws s3 cp /oracle/dumpfile/test.log s3://${S3 버킷명}

*s3 cp 시 endpoint에 연결이 되지 않을 때 참고:

  • 사용한 AWS 계정에 s3에 대한 권한이 있어야 합니다. 없으면 연결이 되지 않으므로 사용한 Role에 s3에 대한 Role을 추가합니다.
  • aws configure get region 커맨드로 현재 선택된 리전과 s3 버킷이 위치한 리전이 같은지 확인이 필요합니다. cli의 리전이 다르다면 vi ~/.aws/config 커맨드로 리전을 변경합니다.

S3 페이지로 이동해서 버킷을 선택해보면 조금 전 s3 cp 명령어로 덤프 파일이 복사 된 것을 확인할 수 있습니다.

S3에 있는 덤프 파일을 RDS로 업로드 위해서는 RDS에 IAM Role 추가 및 옵션 그룹 수정이 필요합니다.

IAM 페이지 Policy 탭으로 이동합니다. Policy 만들기를 선택하여 Visual editor에서 아래와 같이 선택합니다.

Service로 S3 선택합니다. Action은 각 목록을 확장시켜 List — ListBucket, Read — GetObject, Write — PutObject를 선택합니다. Resource는 Specific 및 Bucket을 선택합니다. Bucket에는 덤프 파일이 있는 S3 버킷의 ARN을 입력하고 object는 any를 선택합니다. Policy 생성하기를 눌러 Policy를 생성합니다.

IAM 페이지 Role 탭으로 이동해 Role을 생성합니다. Trusted entity로는 AWS service 및 RDS — Add Role to Database를 선택합니다.

Policy를 선택하는 페이지에서는 방금 생성한 policy를 검색 및 선택합니다. Create role를 눌러 role 생성을 완료합니다.

RDS 페이지로 이동해 생성한 RDS를 선택합니다. Connectivity & security 탭 내 제일 아래 Manage IAM roles 탭에서 방금 생성한 IAM Role를 선택 및 추가합니다. IAM Role이 적용되면 상태가 Active로 변경되는 것을 확인합니다.

RDS 페이지 Option groups 탭으로 이동해 타겟 RDS에 적용된 option group를 선택합니다. 페이지 아래로 이동해 Options에서 option 추가를 선택합니다.

Option name에서 S3_INTEGRATION을 선택합니다. 바로 적용될 수 있도록 Apply immediately를 Yes로 선택합니다.

S3에 업로드된 덤프 파일을 업로드할 준비가 완료되었습니다. 타겟 오라클 DB에 접속해 아래 쿼리로 S3에 있는 덤프 파일을 RDS로 업로드합니다.

SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3(
p_bucket_name => '${버킷 명}',
p_directory_name => 'DATA_PUMP_DIR')
AS TASK_ID FROM DUAL;

해당 쿼리가 실행되면 TASK_ID가 나오는데 해당 ID를 아래 쿼리에 입력해 덤프 파일 업로드 진행 상황을 조회합니다.

SELECT text FROM table(rdsadmin.rds_file_util.read_text_file(‘BDUMP’,’dbtask-${TASK_ID}.log’));

Task가 완료됐다고 메세지가 나오면 아래 쿼리로 RDS에 업로드 된 덤프 파일들을 확인합니다. datapump 디렉토리 내에 덤프 파일 및 로그 파일이 업로드 된 것을 확인할 수 있습니다.

덤프 파일이 RDS에 업로드 완료되면, 아래 프로시저로 덤프 파일 내 스키마와 테이블을 DB 내에 복원합니다.

DECLARE
hdnl NUMBER;
BEGIN
hdnl := DBMS_DATAPUMP.OPEN( operation => 'IMPORT', job_mode => 'SCHEMA', job_name=>null);
DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'test.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file);
DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'test.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file);
DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_EXPR','IN (''TESTUSR'')');
DBMS_DATAPUMP.START_JOB(hdnl);
END;
/

아래 커맨드로 DB import 로그를 확인할 수 있습니다.

SELECT text FROM table(rdsadmin.rds_file_util.read_text_file(‘DATA_PUMP_DIR’,’test.log’));

Oracle DB에서 테이블스페이스란, 논리적인 스토리지 단위입니다. DB 데이터는 테이블스페이스에 저장되게 됩니다.

아래 커맨드로 디폴트 테이블스페이스를 확인합니다.

SELECT PROPERTY_VALUE FROM DATABASE_PROPERTIES WHERE PROPERTY_NAME = ‘DEFAULT_PERMANENT_TABLESPACE’;

그 후 아래 커맨드로 해당 테이블스페이스의 스토리지 여유 공간을 확인합니다.

SYSTEM 테이블스페이스에는 오라클 서버 관련 중요한 정보들을 저장하고, SYSAUX는 서버의 성능 튜닝 관련 정보를 저장합니다. DB의 디폴트 테이블 스페이스는 USERS인 것을 앞서 확인했으니 아래 커맨드로 USERS 테이블스페이스의 사용량을 확인할 수 있습니다.

SELECT TABLESPACE_NAME “TABLESPACE”, EXTENT_MANAGEMENT,FORCE_LOGGING,BLOCK_SIZE,SEGMENT_SPACE_MANAGEMENT
FROM DBA_TABLESPACES;
작업이 완료되었다는 문구가 뜨면 테이블을 새로 고침하여 아래 커맨드로 스키마 및 테이블 내 행 수를 확인합니다.

Load가 완료됐다고 나오면 DB에 접속해 아래 커맨드로 CUSTOMER 테이블 내 레코드 갯 수를 count하여 모든 레코드가 잘 이관되었는지 확인합니다.

ALTER SESSION SET current_schema = TESTUSR;
SELECT COUNT(*) FROM CUSTOMER;

행 수가 정확한 것을 확인했고, 이로써 데이터 이관 확인을 완료했습니다. 👏

지금까지Oracle Data Pump로 스키마 이관하기에 대해 알아보았습니다.

다음 게시글에서는 Oracle DB를 AWS RDS로 이관 하는방법 중, 다른 하나인 ‘DMS로 스키마 이관하기’에 대해 설명 드리도록 하겠습니다.

--

--

Sojeong Baek
Cloud Villains

A junior solutions architect loves tech and business.