[Oracle 11gR2] RMAN DUPLICATE 명령어를 사용하여 운영DB를 개발DB로 이관하기
개발 환경에서 신규 프로세스나 제품을 테스트할 때, 데이터 부족으로 인해 실무적인 검증이 어려운 경우가 많습니다. 특정 스키마(사용자)나 일부 테이블만 옮길 때는 Data Pump Utility를 사용하는 것이 효율적이지만, DB 전체를 마이그레이션해야 할 때는 RMAN DUPLICATE 명령어를 사용하는 것이 훨씬 안정적이고 편리합니다.
- 운영DB와 개발DB의 운영현황(파라미터 등)을 확인합니다.
– FROM ACTIVE DATABASE 방식은 운영DB가 반드시 ARCHIVELOG 모드여야 합니다.
파라미터(명령어) 운영DB 개발DB Hostname
( SELECT host_name FROM v$instance; )cmain cdev Log Mode
( SELECT log_mode FROM v$database; )ARCHIVELOG ARCHIVELOG SID
( show parameter instance_name; )CMAIN CDEV Datafile 경로
( show parameter db_create_file_dest; )/u02/app/oracle/oradata/CMAIN /u02/app/oracle/oradata/CDEV Redo 경로
( show parameter db_create_online_log_dest_; )/u04/app/oracle/redo/CMAIN/ /u02/app/oracle/redo/CDEV/ Control files
( show parameter control_files; )/u04/app/oracle/redo/CMAIN/CMAIN/controlfile/o1_mf_jhgxljgz_.ctl /u02/app/oracle/redo/CDEV/CDEV/controlfile/o1_mf_jhgxd8gn_.ctl - TNS 이름을 설정합니다. 관리의 편리성을 위해 운영DB와 개발DB를 동일하게 설정합니다. 설정이 완료된 이후
tnsping 명령어를 사용해서 접속되는지 확인합니다.CMAIN = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = camin)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = CMAIN) ) ) CDEV = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = cdev)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = CDEV) ) ) - 개발DB의 listener.ora 파일에 아래와 같이 등록합니다.
lsnrctl status 명령어로 확인합니다.
tnsnames.ora 파일에 등록된 SERVICE_NAME과 listener.ora 파일의 GLOBAL_DBNAME는 동일해야 합니다.LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = cdev)(PORT = 1521)) (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) ) # static listener: DB가 NOMOUNT 상태여도 RMAN이 찾아올 수 있게 합니다. SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME = CDEV) # 서비스 이름으로 접속 시 매칭 (ORACLE_HOME = /u01/app/oracle/product/11.2.0.4/dbhome_1) (SID_NAME = CDEV) # 인스턴스 식별자 ) ) ADR_BASE_LISTENER = /u01/app/oracle - 이 부분이 중요할 수도 있는데요, 개발DB용 설정 정보가 저장되어 있는 테이블을 백업합니다. 그렇지 않으면 운영DB용 설정 정보가 개발DB에 적용되어 데이터 마이그레이션 이후 데이터가 엉망이 될 수 있습니다.
- 개발DB를 NOMOUNT 상태로 재기동합니다. 복제 중에 발생하는 내부 DDL 에러를 무시하고 진행하고 싶다면
ALTER SYSTEM SET "_system_trig_enabled = FALSE" SCOPE=MEMORY;를 추가 실행합니다.SQL> shutdown immediate; SQL> startup nomount; SQL> select instance_name, status from v$instance; INSTANCE_NAME STATUS ---------------- ------------ CDEV MOUNTED
- 운영DB의 비밀번호 파일(orapwCMAIN)을 개발DB로 복사할 때 이름을 변경(orapwCDEV)합니다.
비밀번호 파일의 이름은 orapw<SID> 형식을 따라야 합니다.scp $ORACLE_HOME/dbs/orapwCMAIN oracle@cdev:$ORACLE_HOME/dbs/orapwCDEV
- 아래 RMAN DUPLICATE 스크립트를 작성후 실행합니다.
- AUXILIARY CHANNEL의 개수가 복제 속도를 결정하는 핵심이므로, 서버 자원이 허락한다면 2개(c1, c2)보다 조금 더 늘리는 것(예: 4개)이 시간을 단축하는 방법입니다.
- db_create_file_dest 파라미터 값이 동일하다면 DB_FILE_NAME_CONVERT를 사용할 필요가 없습니다.
- DUPLICATE 명령어 옵션 중 TO CDEV를 FOR STANDBY로 변경하면 Dataguard 백업 복제(6.2단계)를 하는 겁니다.
#!/bin/bash #nohup ./duplicate.sh & export ORACLE_SID=CDEV #Using @tnsname TAR_CONN="sys/password@CMAIN" AUX_CONN="sys/password@CDEV" BASE_DIR=$(cd "$(dirname "$0")" && pwd) SCRIPT_NAME=$(basename "$0" .sh) DATE=$(date +%Y%m%d%H%M%S) LOG_FILE=${BASE_DIR}/${SCRIPT_NAME}_${DATE}.log echo "***********************************************************" echo " WARNING: This script will OVERWRITE data using REPLACE." echo " Be careful: You should run this script under NONE PROD DB." echo "***********************************************************" echo -n "Are you sure? (Type 'YES' to continue): " read USER_INPUT if [ "$USER_INPUT" != "YES" ]; then echo "Action canceled by user. Exiting..." exit 1 fi #show parameter db_create_file_dest; rm -rf /u02/app/oracle/oradata/CDEV/CDEV/datafile/* #show parameter db_create_online_log_dest_1; rm -rf /u02/app/oracle/redo/CDEV/CDEV/onlinelog/* #show parameter control_files; rm -rf /u02/app/oracle/redo/CDEV/CDEV/controlfile/* # You can check duplication process by running 'tail -f ${LOG_FILE}' and/or 'watch -n 5 du -sh .' command rman target ${TAR_CONN} auxiliary ${AUX_CONN} log=${LOG_FILE} append <<EOF RUN { ALLOCATE CHANNEL t1 DEVICE TYPE DISK; ALLOCATE CHANNEL t2 DEVICE TYPE DISK; ALLOCATE AUXILIARY CHANNEL c1 DEVICE TYPE DISK; ALLOCATE AUXILIARY CHANNEL c2 DEVICE TYPE DISK; DUPLICATE TARGET DATABASE TO CDEV FROM ACTIVE DATABASE DB_FILE_NAME_CONVERT=('/u02/app/oracle/oradata/CMAIN/CMAIN/datafile/','/u02/app/oracle/oradata/CDEV/CDEV/datafile/') NOFILENAMECHECK; RELEASE CHANNEL t1; RELEASE CHANNEL t2; RELEASE CHANNEL c1; RELEASE CHANNEL c2; } EXIT; EOF - Invalid Object 컴파일: 복제 과정에서 무효화된 패키지나 뷰가 있을 수 있습니다.
SQL> @?/rdbms/admin/utlrp.sql -- 아직 컴파일이 필요한 남은 객체 수 (숫자가 줄어들어야 정상입니다) SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6); -- 현재까지 컴파일 완료된 객체 수 (숫자가 늘어나야 정상입니다) SELECT COUNT(*) FROM UTL_RECOMP_COMPILED;
- 개발DB용 설정 정보가 저장된 테이블을 복구하고, 개발DB의 운영환경에 맞도록 파라미터를 조정합니다.
-- DBMS_JOB 또는 DBMS_SCHEDULER에 등록된 모든 자동 작업을 중단시킨 뒤, 안전이 확인되면 필요한 Job만 골라서 다시 활성화 ---- 원치 않는 운영 배치 실행을 방지하기 위해 필요합니다. SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0 SCOPE=BOTH; -- SGA_TARGET와 PGA_AGGREGATE_TARGET는 물리적 메모리 크기에 맞게 설정합니다.(32G 기준) ---- 전용 데이터베이스 서버에 대한 일반적인 권장 사항은 물리적 RAM의 80%를 Oracle에 할당하는 것입니다. ---- SGA_TARGET : 80% of Oracle Memory ---- PGA_AGGREGATE_TARGET : 20% of Oracle Memory ALTER SYSTEM SET SGA_MAX_SIZE=20G SCOPE=SPFILE; ALTER SYSTEM SET SGA_TARGET=20G SCOPE=BOTH; ALTER SYSTEM SET PGA_AGGREGATE_TARGET=5.12G SCOPE=BOTH;
- 개발DB를 재기동할 필요는 없으며 SPFILE을 확인하고 재생성합니다.
SQL> SHOW PARAMETER SPFILE; -- $ORACLE_HOME/dbs/spfileCDEV.ora 경로가 떠 있고, 실제 파일이 존재한다면 OK입니다. ---- 재기동하기 전에 파일명을 spfileCDEV.ora로 변경한 다음에 재기동합니다. SQL> CREATE SPFILE='?/dbs/spfileCDEV_new.ora' FROM MEMORY; -- 텍스트 파일로 백업받아둡니다. ---- /u01/app/oracle/product/11.2.0.4/dbhome_1/dbs/initCDEV.ora 파일이 존재한다면 기존 파일을 백업합니다. SQL> CREATE PFILE='/u01/app/oracle/product/11.2.0.4/dbhome_1/dbs/initCDEV_new.ora' FROM MEMORY;
- 혹시 재기동할 때 “ORA-32004: obsolete or deprecated parameter(s) specified for RDBMS instance” 오류가 발생한다면, [diagnostic_dest]/diag/rdbms/[db_name]/[instance_name]/trace/alert_[SID].log 파일에서 오류 메시지를 찾아서
ALTER SYSTEM RESET명령어로 더 이상 사용하지 않는 파라미터들을 초기화합니다.SQL> ALTER SYSTEM RESET <parameter_name> SCOPE=SPFILE;
