

# RDS Custom for Oracle 지원 종료
<a name="RDS-Custom-for-Oracle-end-of-support"></a>

**참고**  
지원 종료 공지: 2027년 3월 31일에 AWS는 Amazon RDS Custom for Oracle에 대한 지원을 종료합니다. 2027년 3월 31일 이후에는 RDS Custom for Oracle 콘솔 또는 RDS Custom for Oracle 리소스에 더 이상 액세스할 수 없습니다. 자세한 내용은 [RDS Custom for Oracle 지원 종료](#RDS-Custom-for-Oracle-end-of-support) 섹션을 참조하세요.

## 개요
<a name="RDS-Custom-for-Oracle-end-of-support-overview"></a>

신중하게 고려한 후 AWS는 Amazon RDS Custom for Oracle 서비스를 중단하기로 결정했습니다. 이 서비스는 **2027년 3월 31일**부터 더 이상 사용되지 않습니다. 이 규범적 지침은 RDS Custom for Oracle에서 Amazon Elastic Compute Cloud(Amazon EC2)의 자체 관리형 Oracle 데이터베이스로 마이그레이션하는 데 도움이 되는 자세한 마이그레이션 전략을 제공합니다.

### 키 제한 시간
<a name="RDS-Custom-for-Oracle-end-of-support-key_timelines"></a>
+ **2026년 3월 31일부터 2027년 3월 31일까지**: RDS Custom for Oracle에서 EC2 기반 Oracle 실행으로 마이그레이션하는 것이 좋습니다. 이 기간 동안 기존 기능 및 지원과 함께 RDS Custom for Oracle을 계속 사용할 수 있습니다.
+ **2027년 3월 31일 이후**: 더 이상 RDS Custom for Oracle 서비스를 사용할 수 없습니다.

### 대상 고객
<a name="RDS-Custom-for-Oracle-end-of-support-target_audience"></a>

이 지침은 다음을 위한 것입니다.
+ Oracle 데이터베이스 마이그레이션을 담당하는 데이터베이스 관리자
+ 마이그레이션 전략을 계획하는 클라우드 아키텍트
+ 데이터베이스 인프라를 관리하는 DevOps 엔지니어
+ 마이그레이션 프로세스를 감독하는 IT 관리자

### 사전 조건
<a name="RDS-Custom-for-Oracle-end-of-support-prerequisites"></a>

시작하기 전에 다음을 갖추었는지 확인하세요.
+ Oracle 19c Enterprise Edition을 실행하는 활성 Amazon RDS Custom for Oracle 인스턴스
+ EC2 인스턴스를 생성하고 관리하기 위한 적절한 AWS Identity and Access Management(IAM) 권한
+ 데이터베이스 아키텍처 이해(비 CDB 또는 PDB)
+ 소스 인스턴스와 대상 인스턴스 간의 네트워크 연결 계획
+ 마이그레이션을 위한 백업 및 복구 전략

## 마이그레이션 옵션  
<a name="RDS-Custom-for-Oracle-end-of-support-migration_options"></a>

마이그레이션 프로세스의 일부로 비즈니스 요구 사항 및 사용 사례에 따라 두 가지 마이그레이션 옵션 중 하나를 선택할 수 있습니다.

### 옵션 1: RMAN Active Duplication(온라인/오프라인 마이그레이션)
<a name="RDS-Custom-for-Oracle-end-of-support-migration_options-RMAN"></a>

**다음과 같은 경우에 가장 적합**
+ 최종 컷오버 중에 계획된 가동 중지 시간을 감당할 수 있는 워크로드
+ 더 적은 구성 요소로 더 간단한 마이그레이션 요구 사항
+ 간단한 일회성 마이그레이션을 원하는 데이터베이스
+ 컷오버 전에 지속적인 동기화가 필요하지 않은 시나리오

**주요 특징**
+ **가동 중지 시간**: 최종 컷오버 중 가동 중지 시간 최소화(중복 중 데이터베이스 온라인 유지, 최종 컷오버을 위한 짧은 가동 중지 시간)
+ **복잡성**: 직접 데이터베이스 복제로 복잡성 감소
+ **기간**: 마이그레이션 시간은 데이터베이스 크기 및 네트워크 대역폭에 따라 달라짐
+ **폴백**: 검증이 완료될 때까지 소스 데이터베이스를 유지 관리해야 함
+ **온라인 기능**: 소스 데이터베이스는 중복 프로세스 중에 온라인 상태를 유지하고 액세스할 수 있습니다.

**마이그레이션 접근 방식:** RMAN 활성 복제는 실행 중인 라이브 소스 데이터베이스에서 네트워크를 통해 데이터베이스 파일을 복사하여 대상에 소스 데이터베이스의 정확한 사본을 생성합니다. 온라인 기능: 소스 데이터베이스는 중복 프로세스 중에 온라인 상태를 유지하고 액세스할 수 있습니다. 멀티테넌트 데이터베이스의 경우 RMAN은 `CDB$ROOT`, `PDB$SEED` 및 모든 플러그형 데이터베이스를 포함한 전체 CDB를 단일 작업으로 자동으로 복제합니다. 애플리케이션을 새 EC2 인스턴스로 리디렉션하려면 짧은 컷오버 기간만 있으면 됩니다.

### 옵션 2: Oracle Data Guard(온라인 마이그레이션)
<a name="RDS-Custom-for-Oracle-end-of-support-migration_options-Oracle-Data-Guard"></a>

**다음과 같은 경우에 가장 적합**
+ 가동 중지 시간을 최소화해야 하는 프로덕션 워크로드
+ 가용성을 유지해야 하는 미션 크리티컬 데이터베이스
+ 컷오버 전에 지속적인 동기화가 필요한 시나리오
+ 내장 폴백 기능이 필요한 마이그레이션

**주요 특징**
+ **가동 중지 시간**: 가동 중지 시간이 거의 없음(전환의 경우 몇 초에서 몇 분)
+ **복잡성**: Data Guard 구성으로 복잡성 증가
+ **기간**: 초기 설정 시간 \+ 전환까지의 연속 동기화
+ **폴백**: 소스를 대기 상태로 유지하여 기본 제공 폴백 기능

**마이그레이션 접근 방식:** Oracle Data Guard는 기본 데이터베이스에서 다시 실행 로그를 지속적으로 전송하고 적용하여 동기화된 대기 데이터베이스를 유지합니다. 마이그레이션을 완료할 준비가 되면 가동 중지 시간을 최소화하면서 EC2 대기를 기본으로 승격하는 전환을 수행합니다. 멀티테넌트 데이터베이스의 경우 Data Guard는 모든 PDB를 포함한 전체 CDB를 자동으로 보호합니다.

 **의사결정 매트릭스** 

다음 매트릭스를 사용하면 적절한 마이그레이션 옵션을 선택하는 데 도움이 됩니다.


|  **속성**  |  **RMAN 활성 복제**  |  **Oracle Data Guard**  | 
| --- | --- | --- | 
| **소스 데이터베이스 가용성** | 복제 중 온라인 | 전체 프로세스 중 온라인 | 
| **허용 가능한 가동 중지 시간** | 몇 분에서 몇 시간(최종 컷오버) | 몇 초에서 몇 분(전환) | 
| **마이그레이션 복잡성** | 낮음 | 높음 | 
| **연속 동기화** | 아니요 | 예 | 
| **폴백 기능** | 수동(원본 유지) | 내장(자동) | 
| **컷오버 전 테스트** | 제한 사항 | 전체 테스트 가능 | 
| **네트워크 대역폭 요구 사항** | 중복 중 높음 | 보통(연속) | 
| **최적의 용도** | 대부분의 마이그레이션, 개발 및 테스트, 계획된 컷오버 | 프로덕션, 미션 크리티컬, 가동 중지 시간이 거의 없음 | 

### 아키텍처 고려 사항
<a name="RDS-Custom-for-Oracle-end-of-support-migration_options-architecture-considerations"></a>

두 마이그레이션 옵션 모두 두 가지 Oracle 데이터베이스 아키텍처를 지원합니다.

 **비 CDB** 

멀티테넌트 아키텍처가 없는 기존 단일 인스턴스 Oracle 데이터베이스. 이러한 데이터베이스는 다음과 같습니다.
+ 단일 데이터베이스 인스턴스 보유
+ 플러그형 데이터베이스(PDB)를 사용하지 않음
+ 관리 및 마이그레이션이 더 간단함
+ RDS Custom for Oracle에서 일반적으로 명명된 ORCL

 **멀티테넌트(PDB가 있는 CDB)** 

컨테이너 데이터베이스(CDB)는 여러 개의 플러그형 데이터베이스(PDB)를 호스팅하는 기술로, Oracle 12c에서 도입되었습니다. 이러한 데이터베이스는 다음과 같습니다.
+ `CDB$ROOT` 및 `PDB$SEED`를 사용하여 컨테이너 데이터베이스(CDB) 보유
+ 하나 이상의 플러그형 데이터베이스(PDB) 호스팅
+ 데이터베이스 통합 및 리소스 격리 제공
+ 일반적으로 RDS Custom for Oracle에서 RDSCDB로 명명됨
+ PDB 데이터 파일에 대한 GUID 기반 하위 디렉터리와 함께 Oracle Managed Files(OMF) 사용

**멀티테넌트 마이그레이션에 대한 중요 참고 사항**: 마이그레이션 프로세스 중에 대상 데이터베이스의 이름이 ORCL로 변경됩니다(소스: RDSCDB → 대상: ORCL). 이렇게 하면 대상 구성이 간소화되고 표준 이름 지정 규칙에 맞게 조정됩니다.

 **마이그레이션 접근 방식의 주요 차이점** 


|  **속성**  |  **비 CDB**  |  **멀티테넌트(PDB가 있는 CDB)**  | 
| --- | --- | --- | 
| **마이그레이션 범위** | 단일 데이터베이스 | 모든 PDB가 있는 전체 CDB | 
| **마이그레이션 후 단계**  | 데이터베이스 열기 READ WRITE | CDB 열기 READ WRITE, MOUNTED 상태의 PDB | 
| **PDB 관리** | 해당 사항 없음 | PDB 열고 자동 열기를 구성해야 함 | 
| **정리** | 단일 데이터베이스 | CDB$ROOT(PDB로 캐스케이드됨), C\#\# 일반 사용자 처리 | 
| **애플리케이션 연결** | 데이터베이스 서비스 | PDB 서비스(CDB 아님) | 
| **파라미터 파일** | 표준 파라미터 | enable\_pluggable\_database=TRUE 필요 | 
| **복잡성** | 작음 | 여러 컨테이너로 인해 높음 | 

## 두 마이그레이션 옵션의 공통 사전 조건
<a name="RDS-Custom-for-Oracle-end-of-support-common-prerequisites"></a>

마이그레이션 옵션을 시작하기 전에 다음 사전 조건 단계를 완료합니다.

1. EC2 인스턴스 시작 및 구성

   다음 사항을 고려하여 EC2 인스턴스를 시작하세요.
   + **인스턴스 유형**: 워크로드의 리소스 요구 사항을 충족하는 EC2 인스턴스 유형을 선택합니다. RDS Custom 인스턴스와 동일한 인스턴스 클래스를 사용하는 것이 좋습니다. 메모리, CPU 및 네트워크 대역폭 요구 사항을 고려합니다.
   + **운영 체제**: Oracle Linux 또는 Red Hat Enterprise Linux(RDS Custom OS 버전과 일치하거나 호환)
   + **Oracle 소프트웨어**: Oracle Database 소프트웨어(주요 버전, 마이너 버전, 릴리스 업데이트, 이상적으로는 RDS Custom과 동일한 일회성 패치)를 설치합니다. Oracle 소프트웨어가 /u01/app/oracle/ 또는 원하는 위치에 설치되어 있는지 확인합니다.
   + **스토리지**: 워크로드 요구 사항에 맞게 적절한 크기와 IOPS로 Amazon EBS 볼륨을 구성합니다. 비용 효율적인 성능을 위해 gp3 볼륨을 사용하거나 고성능 워크로드를 위해 io2 Block Express를 사용하는 것이 좋습니다.

1. 스토리지 아키텍처 구성

   1. 파일 시스템 스토리지(대부분의 시나리오에서 권장됨)
      + Oracle 데이터 파일에 표준 파일 시스템 디렉터리 사용
      + 관리가 더 간단하고 대부분의 워크로드에 적합
      + 이 지침에서는 파일 시스템 스토리지 예제를 사용합니다.

   1. Oracle Automatic Storage Management(ASM)
      + 워크로드에 ASM이 필요한 경우 EC2 인스턴스에 독립 실행형 ASM을 설치하고 구성합니다.
      + ASM 디스크 그룹(예: \+DATA, \+FRA)을 사용하도록 init 파일의 모든 경로 파라미터를 적절히 조정합니다.
      + 마이그레이션 프로세스는 경로 조정과 함께 ASM과 유사합니다.

1. 파일 전송 메커니즘 설정

   RDS Custom 인스턴스와 EC2 인스턴스 간에 파일을 전송하는 메커니즘을 생성합니다. 여러 가지 옵션이 있습니다.

   1. 옵션 A: Amazon S3(대부분의 시나리오에서 권장됨)
      + Amazon S3 버킷을 만들거나 기존 버킷 사용
      + 두 인스턴스 모두에 AWS CLI 설치 및 구성
      + 지침은 [AWS CLI 시작하기](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html)를 참고하세요.

   1. 옵션 B: 직접 SCP/SFTP
      + 인스턴스 간에 SSH 포트가 열려 있는 경우 파일을 직접 전송할 수 있습니다.
      + 파라미터 파일 및 암호 파일과 같은 작은 파일에 적합

   1. 옵션 C: Amazon EFS
      + 두 인스턴스에 Amazon EFS가 이미 탑재되어 있는 경우 공유 파일 시스템으로 사용할 수 있습니다.
      + 기존 EFS 인프라가 있는 환경에 적합

      이 지침에서는 Amazon S3를 예제로 사용하지만 선택한 메서드에 맞게 명령을 조정할 수 있습니다.

1. 네트워크 연결 구성

   RDS Custom 인스턴스와 EC2 인스턴스 간의 네트워크 연결을 확인합니다.
   + **동일한 VPC**: 보안 그룹은 Oracle 리스너 포트(기본값 1521 또는 사용자 지정 포트)에서 양방향 트래픽을 허용해야 합니다.
   + **다른 VPC(동일 계정)**: VPC 피어링 설정 및 라우팅 테이블 및 보안 그룹 구성
   + **다른 계정**: 계정 간에 VPC 피어링을 설정하거나 AWS Transit Gateway 사용
   + **연결 확인**: ping 및 telnet을 사용하여 데이터베이스 포트에서 연결 테스트

1. EC2에서 디렉터리 구조 생성

   디렉터리 구조는 데이터베이스 아키텍처에 따라 달라집니다.  
**Example 비 CDB의 경우:**  

   ```
   # Non-CDB directories
   mkdir -p /u01/app/oracle/oradata/ORCL/controlfile/
   mkdir -p /u01/app/oracle/oradata/ORCL/datafile
   mkdir -p /u01/app/oracle/oradata/ORCL/onlinelog
   mkdir -p /u01/app/oracle/oradata/ORCL/arch
   mkdir -p /u01/app/oracle/admin/ORCL/adump
   mkdir -p /u01/app/oracle/backup
   # Set ownership
   chown -R oracle:oinstall /u01/app/oracle/oradata/ORCL
   chown -R oracle:oinstall /u01/app/oracle/admin/ORCL
   chown -R oracle:oinstall /u01/app/oracle/backup
   ```  
**Example 멀티테넌트(PDB가 있는 CDB)의 경우**  

   ```
   # CDB directories
   mkdir -p /u01/app/oracle/oradata/ORCL/controlfile/
   mkdir -p /u01/app/oracle/oradata/ORCL/cdb/datafile
   mkdir -p /u01/app/oracle/oradata/ORCL/pdbseed/datafile
   mkdir -p /u01/app/oracle/oradata/ORCL/onlinelog
   mkdir -p /u01/app/oracle/oradata/ORCL/arch
   mkdir -p /u01/app/oracle/admin/ORCL/adump
   mkdir -p /u01/app/oracle/backup
   # PDB directories (RDS Custom uses OMF with GUID-based paths)
   # Create a generic pdb directory - migration will create subdirectories as needed
   mkdir -p /u01/app/oracle/oradata/ORCL/pdb/datafile
   # Set ownership
   chown -R oracle:oinstall /u01/app/oracle/oradata/ORCL
   chown -R oracle:oinstall /u01/app/oracle/admin/ORCL
   chown -R oracle:oinstall /u01/app/oracle/backup
   ```
**참고**  
RDS Custom for Oracle은 GUID 기반 하위 디렉터리(예: `/rdsdbdata/db/pdb/RDSCDB_A/{{{GUID}}}/datafile/`)가 있는 PDB 데이터 파일에 Oracle Managed Files(OMF)를 사용합니다. 마이그레이션 프로세스는 대상에 필요한 하위 디렉터리 구조를 자동으로 생성합니다. 상위 디렉터리만 생성하면 됩니다.

   **스토리지 전략**: /u01/app/oracle/backup에 별도의 EBS 볼륨을 사용하여 마이그레이션이 완료된 후 쉽게 분리하고 제거하여 스토리지 비용을 절감하는 것이 좋습니다.

1. 소스 데이터베이스 구성 확인

마이그레이션을 시작하기 전에 소스 데이터베이스 구성을 확인합니다.

1. RDS Custom 데이터베이스 호스트에 rdsdb 사용자로 로그인하고 환경을 설정합니다.  
**Example**  

   ```
   # For non-CDB
   export ORACLE_HOME=/rdsdbbin/oracle.19.custom.r1.EE.1
   export ORACLE_SID=ORCL
   export PATH=$ORACLE_HOME/bin:$PATH
   
   # For multitenant CDB
   export ORACLE_HOME=/rdsdbbin/oracle.19.custom.r1.EE-CDB.1
   export ORACLE_SID=RDSCDB
   export PATH=$ORACLE_HOME/bin:$PATH
   ```

1. 데이터베이스에 연결하고 아키텍처를 확인합니다.  
**Example**  

   ```
   sqlplus / as sysdba
   SQL> SELECT name, cdb, open_mode, log_mode FROM v$database;
   ```  
**Example 비CDB의 경우 예상 출력**  

   ```
   NAME CDB OPEN_MODE                 LOG_MODE
   --------- --- -------------------- ------------
   ORCL NO  READ  WRITE               ARCHIVELOG
   ```  
**Example 멀티테넌트(CDB)의 경우 예상 출력:**  

   ```
   NAME    CDB  OPEN_MODE             LOG_MODE
   --------- --- -------------------- ------------
   RDSCDB    YES READ WRITE           ARCHIVELOG
   ```

1. **멀티테넌트 CDB가 있는 경우** 모든 PDB 및 해당 상태:  
**Example**  

   ```
   SQL> SELECT con_id, name, open_mode, restricted FROM v$pdbs;
   ```

   예상 출력(ORCLDB라는 PDB가 1개인 예):  
**Example**  

   ```
   CON_ID     NAME                           OPEN_MODE  RES
   ---------- ------------------------------ ---------- ---
   2          PDB$SEED                       READ ONLY  NO
   3          ORCLDB                         READ WRITE NO
   ```

1. 총 데이터베이스 크기 확인:  
**Example 비 CDB의 경우:**  

   ```
   SQL> SELECT SUM(bytes)/1024/1024/1024 AS total_size_gb FROM dba_data_files;
   ```  
**Example 멀티테넌트의 경우:**  

   ```
   -- Total CDB size (all containers)
   SQL> SELECT SUM(bytes)/1024/1024/1024 AS total_size_gb FROM cdb_data_files;
   -- Size per PDB
   SQL> SELECT p.name AS pdb_name,
         ROUND(SUM(d.bytes)/1024/1024/1024, 2) AS size_gb
   FROM v$pdbs p
   JOIN cdb_data_files d ON p.con_id = d.con_id
   GROUP BY p.name, p.con_id
   ORDER BY p.con_id;
   ```

## 옵션 1: RMAN 활성 복제를 사용한 물리적 마이그레이션
<a name="RDS-Custom-for-Oracle-end-of-support-option-1"></a>

**Topics**
+ [RMAN 활성 중복을 사용해야 하는 경우](#RDS-Custom-for-Oracle-end-of-support-option-1-when-to-use)
+ [RMAN 활성 중복 개요](#RDS-Custom-for-Oracle-end-of-support-option-1-overview)
+ [RMAN 활성 복제를 위한 마이그레이션 워크플로](#RDS-Custom-for-Oracle-end-of-support-option-1-migration-workflow)
+ [1단계: Amazon RDS Custom 자동화 일시 중지](#RDS-Custom-for-Oracle-end-of-support-option-1-step-1)
+ [2단계: 암호 및 파라미터 파일 생성](#RDS-Custom-for-Oracle-end-of-support-option-1-step-2)
+ [3단계: EC2로 파일 전송](#RDS-Custom-for-Oracle-end-of-support-option-1-step-3)
+ [4단계: EC2에서 파라미터 파일 편집](#RDS-Custom-for-Oracle-end-of-support-option-1-step-4)
+ [5단계: TNS 및 리스너 구성](#RDS-Custom-for-Oracle-end-of-support-option-1-step-5)
+ [6단계: EC2에서 `NOMOUNT`의 데이터베이스 시작](#RDS-Custom-for-Oracle-end-of-support-option-1-step-6)
+ [7단계: RMAN 활성 중복 수행](#RDS-Custom-for-Oracle-end-of-support-option-1-step-7)
+ [8단계: PDB 열기(멀티테넌트만 해당)](#RDS-Custom-for-Oracle-end-of-support-option-1-step-8)
+ [9단계: RDS Custom 객체 제거](#RDS-Custom-for-Oracle-end-of-support-option-1-step-9)
+ [10단계: 자동 시작 구성](#RDS-Custom-for-Oracle-end-of-support-option-1-step-10)
+ [11단계: 최종 검증](#RDS-Custom-for-Oracle-end-of-support-option-1-step-11)

이 섹션에서는 RMAN 활성 복제를 사용하여 Oracle 데이터베이스를 RDS Custom for Oracle에서 EC2로 마이그레이션하는 자세한 단계를 제공합니다. 이 방법은 실행 중인 라이브 데이터베이스에서 복제되어 마이그레이션 프로세스 중에 소스를 온라인 상태로 유지하고 액세스할 수 있습니다.

### RMAN 활성 중복을 사용해야 하는 경우
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-when-to-use"></a>

다음과 같은 경우 RMAN 활성 중복을 선택합니다.
+ 마이그레이션 중에 소스 데이터베이스를 온라인 상태로 유지하고 액세스할 수 있도록 하려는 경우
+ 최종 애플리케이션 리디렉션을 위해 짧은 컷오버 기간을 제공할 수 있습니다.
+ 움직이는 부분이 적은 간단한 마이그레이션 프로세스를 원할 경우
+ 데이터베이스 크기와 네트워크 대역폭으로 인해 적절한 중복 시간이 허용됩니다.
+ 컷오버 전에 연속 동기화가 필요하지 않습니다.
+ 프로덕션, 개발 또는 테스트 데이터베이스를 마이그레이션하는 경우

### RMAN 활성 중복 개요
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-overview"></a>

RMAN 활성 중복은 소스 데이터베이스를 백업하거나 소스 데이터베이스를 오프라인으로 전환할 필요가 없습니다. 소스가 온라인 상태로 유지되고 애플리케이션에서 액세스할 수 있는 동안 네트워크를 통해 데이터베이스 파일을 복사하여 실행 중인 라이브 소스 데이터베이스를 대상으로 복제합니다.

**주요 이점:**
+ **소스는 온라인 상태로 유지**: 애플리케이션은 복제 중에 소스 데이터베이스에 계속 액세스할 수 있습니다.
+ **백업 불필요**: 중간 백업 스토리지 필요 없음
+ **직접 네트워크 전송**: 데이터베이스 파일이 소스에서 대상으로 직접 복사됩니다.
+ **자동 일관성**: RMAN은 중복 데이터베이스의 일관성을 보장합니다.
+ **단일 작업**: 멀티테넌트의 경우, 모든 PDB를 포함한 전체 CDB를 한 번의 작업으로 복제합니다.

복제 프로세스는 모든 데이터 파일, 제어 파일 및 다시 실행 로그를 포함하여 대상에 소스 데이터베이스의 정확한 사본을 생성합니다. 소스 데이터베이스는 복제 프로세스 전반에 걸쳐 애플리케이션 요청을 계속 처리합니다. 소스에서 대상으로 애플리케이션을 리디렉션하려면 끝에 짧은 컷오버 기간만 있으면 됩니다.

**일반적인 타임라인**

1. **복제 단계**(소스는 온라인 상태로 유지): 데이터베이스 크기에 따라 30분\~몇 시간

1. **검증 단계**(소스는 온라인 상태로 유지): 필요에 따라 몇 시간에서 며칠까지

1. **컷오버 단계**(짧은 가동 중지 시간): 애플리케이션을 EC2로 리디렉션하는 데 몇 분

### RMAN 활성 복제를 위한 마이그레이션 워크플로
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-migration-workflow"></a>

**RDS Custom DB 인스턴스(소스) 단계:**

1. Amazon RDS Custom 자동화 일시 중지

1. 데이터베이스 아키텍처 확인(비 CDB 또는 PDB가 있는 CDB)

1. 소스 데이터베이스에서 암호 파일 및 파라미터 파일 생성

1. 암호 파일과 파라미터 파일을 대상 EC2 인스턴스에 복사합니다.

1. 소스 데이터베이스가 아카이브 로그 모드에서 실행 중인지 확인

1. RDS Custom DB 서버에서 tnsnames.ora 구성

**EC2 DB 인스턴스(대상) 단계:**

1. EC2용 파라미터 파일 편집(아키텍처별)

1. EC2에서 tnsnames.ora 구성

1. EC2 인스턴스에 대한 환경 구성

1. EC2에서 Oracle Listener 구성

1. NOMOUNT 상태에서 EC2에서 데이터베이스 시작

**RMAN 복제 단계:**

1. RMAN 활성 중복 수행

1. 데이터베이스(및 멀티테넌트용 PDB) 열기

1. PDB 자동 열기 구성(멀티테넌트만 해당)

1. RDS Custom 특정 사용자 및 객체 제거

1. SPFILE 생성 및 자동 시작 구성

1. 소스에서 Amazon RDS Custom 자동화 재개(활성 상태로 유지되는 경우)

### 1단계: Amazon RDS Custom 자동화 일시 중지
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-1"></a>

자동화가 RMAN 활동을 방해하지 않도록 마이그레이션 단계를 진행하기 전에 RDS Custom 인스턴스에서 자동화 모드를 일시 중지합니다. --resume-full-automation-mode-minute 파라미터(이 예제에서는 240분 = 4시간)는 데이터베이스 크기와 예상 중복 시간에 따라 조정해야 합니다.

**중요**: 자동화를 일시 중지해도 데이터베이스 가용성에는 영향을 주지 않습니다. 데이터베이스는 온라인 상태로 유지되며 복제 프로세스 중에 애플리케이션에 액세스할 수 있습니다.

**Example**  

```
aws rds modify-db-instance \
--db-instance-identifier my-custom-instance \
--automation-mode all-paused \
--resume-full-automation-mode-minute 240 \
--region us-east-1 
--query 'DBInstances[0].AutomationMode'
```

자동화 상태 검증:

**Example**  

```
aws ds describe-db-instances \
--db-instance-identifier my-custom-instance \
--region us-east-1 \
--query 'DBInstances[0].AutomationMode'
```

예상 결과: ‘`all-paused`’

### 2단계: 암호 및 파라미터 파일 생성
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-2"></a>

`orapwd`를 사용하여 암호 파일을 생성합니다. AWS Secrets Manager에서 SYS 암호를 검색합니다(RDS Custom 인스턴스 생성 중에 저장됨).

**Example**  

```
# Non-CDB
$ORACLE_HOME/bin/orapwd file=/rdsdbdata/config/orapwORCL password={{<SYS_PASSWORD>}} entries=10
# Multitenant
$ORACLE_HOME/bin/orapwd file=/rdsdbdata/config/orapwRDSCDB password={{<SYS_PASSWORD>}} entries=10
```

소스 데이터베이스에서 파라미터 파일을 생성합니다.

**Example**  

```
sqlplus / as sysdba
SQL> CREATE PFILE='/tmp/initORCL.ora' FROM SPFILE; -- Non-CDB
SQL> CREATE PFILE='/tmp/initRDSCDB.ora' FROM SPFILE; -- Multitenant
```

생성된 파라미터 파일에는 RDS Custom별 경로 및 파라미터가 포함됩니다. 멀티테넌트의 경우 주요 파라미터는 다음과 같습니다.
+ `enable_pluggable_database`=`TRUE`(멀티테넌트의 경우 필수)
+ `noncdb_compatible`=`TRUE`(이전 버전과의 호환성을 위해)
+ `CDB$ROOT`, `PDB$SEED` 및 모든 PDB의 데이터 파일 경로
+ OMF의 경우 `db_create_file_dest` 및 `db_create_online_log_dest_1`

### 3단계: EC2로 파일 전송
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-3"></a>

원하는 파일 전송 방법을 선택합니다. 이 지침에서는 Amazon S3를 예제로 사용합니다.

 **Amazon S3 사용** 

#### Amazon S3 사용:
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-3-ec2"></a>

**Example 비 CDB의 경우:**  

```
# Copy files to Amazon S3 from the RDS Custom instance
aws s3 cp /tmp/initORCL.ora s3://{{<YOUR_BUCKET>}}/
aws s3 cp /rdsdbdata/config/orapwORCL s3://{{<YOUR_BUCKET>}}/
# On EC2, download files
aws s3 cp s3://{{<YOUR_BUCKET>}}/initORCL.ora $ORACLE_HOME/dbs/
aws s3 cp s3://{{<YOUR_BUCKET>}}/orapwORCL $ORACLE_HOME/dbs/
```

**Example 멀티테넌트의 경우:**  

```
# Copy files to Amazon S3 from the RDS Custom instance
aws s3 cp /tmp/initRDSCDB.ora s3://{{<YOUR_BUCKET>}}/
aws s3 cp /rdsdbdata/config/orapwRDSCDB s3://{{<YOUR_BUCKET>}}/
# On EC2, download and rename files to use ORCL naming
aws s3 cp s3://{{<YOUR_BUCKET>}}/initRDSCDB.ora $ORACLE_HOME/dbs/initORCL.ora
aws s3 cp s3://{{<YOUR_BUCKET>}}/orapwRDSCDB $ORACLE_HOME/dbs/orapwORCL
```

EC2에서 파일을 검증합니다.

**Example**  

```
ls -l $ORACLE_HOME/dbs/initORCL.ora
ls -l $ORACLE_HOME/dbs/orapwORCL
```

### 4단계: EC2에서 파라미터 파일 편집
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-4"></a>

파라미터 파일을 성공적으로 마이그레이션하려면 신중한 편집이 필요합니다. 이는 마이그레이션 프로세스에서 가장 중요한 단계 중 하나입니다.

EC2 인스턴스에서 `$ORACLE_HOME/dbs/initORCL.ora`를 편집하고 다음과 같이 중요한 변경을 수행합니다.

1. **데이터베이스 이름 업데이트**: 멀티테넌트의 경우 RDSCDB의 모든 발생을 ORCL로 변경합니다.

1. **RDS Custom 경로를 EC2 경로로 변환**: /rdsdbdata/를 /u01/app/oracle/로 바꾸기

1. 

**RDS Custom 관련 파라미터 제거**
   + `dg_broker_config_file1` 및 `dg_broker_config_file2`(있는 경우 - 복제본이 있음을 나타냄)
   + `standby_file_management`(있는 경우)
   + `spfile`(나중에 새 SPFILE 생성)
   + 대기 대상을 가리키는 모든 `log_archive_dest` 파라미터(로컬 아카이브에만 `log_archive_dest_1` 유지)

1. **파일 이름 변환 파라미터 추가**(아래 참조)

1. EC2 인스턴스 크기에 따라 **메모리 파라미터 조정**(선택 사항이지만 권장됨)

**파일 이름 변환 파라미터 이해:** 

`DB_FILE_NAME_CONVERT` 및 `LOG_FILE_NAME_CONVERT` 파라미터는 RMAN 복제에 매우 중요합니다. 중복 프로세스 중에 소스 파일 경로를 대상 파일 경로에 매핑하는 방법을 RMAN에 알려줍니다. 이러한 파라미터가 없으면 RMAN은 소스와 동일한 경로에 파일을 생성하려고 시도하며, 이는 EC2에서 실패합니다.

**주요 고려 사항:**
+ 각 파라미터는 소스 경로와 대상 경로 등 문자열 쌍을 허용합니다.
+ 단일 파라미터에서 여러 페어를 지정할 수 있습니다.
+ 멀티테넌트의 경우 `CDB$ROOT`, `PDB$SEED` 및 모든 PDB에 대한 경로를 매핑해야 합니다.
+ 페어 순서가 중요합니다. RMAN은 지정된 순서대로 페어를 처리합니다.
+ 경로는 대/소문자를 구분하며 정확히 일치해야 합니다.

**경로 매핑:**


**비CDB:**  

|  **RDS Custom 경로**  |  **EC2 경로**  |  **설명** –   | 
| --- | --- | --- | 
| /rdsdbbin | /u01/app/oracle | Oracle 기반 | 
| /rdsdbdata/db/ORCL\_A/datafile/ | /u01/app/oracle/oradata/ORCL/datafile/ | 데이터 파일 | 
| /rdsdbdata/db/ORCL\_A/controlfile/ | /u01/app/oracle/oradata/ORCL/controlfile/ | 제어 파일 | 
| /rdsdbdata/db/ORCL\_A/onlinelog/ | /u01/app/oracle/oradata/ORCL/onlinelog/ | 온라인 다시 실행 로그 | 
| /rdsdbdata/db/ORCL\_A/arch/ | /u01/app/oracle/oradata/ORCL/arch/ | 아카이브 로그 | 
| /rdsdbdata/admin/ORCL/adump | /u01/app/oracle/admin/ORCL/adump | 감사 덤프 | 
| /rdsdbdata/log | /u01/app/oracle | 진단 대상 | 


**멀티테넌트**  

|  **RDS Custom 경로**  |  **EC2 경로**  |  **설명** –   | 
| --- | --- | --- | 
| /rdsdbbin | /u01/app/oracle | Oracle 기반 | 
| /rdsdbdata/db/cdb/RDSCDB/datafile/ | /u01/app/oracle/oradata/ORCL/cdb/datafile/ | CDB 루트 데이터 파일 | 
| /rdsdbdata/db/cdb/pdbseed/ | /u01/app/oracle/oradata/ORCL/pdbseed/datafile/ | PDB$SEED 데이터 파일 | 
| /rdsdbdata/db/pdb/RDSCDB\_A/ | /u01/app/oracle/oradata/ORCL/pdb/datafile/ | PDB 데이터 파일(GUID 포함 OMF) | 
| /rdsdbdata/db/cdb/RDSCDB\_A/controlfile/ | /u01/app/oracle/oradata/ORCL/controlfile/ | 제어 파일 | 
| /rdsdbdata/db/cdb/RDSCDB\_A/onlinelog/ | /u01/app/oracle/oradata/ORCL/onlinelog/ | 온라인 다시 실행 로그 | 
| /rdsdbdata/db/cdb/RDSCDB\_A/arch/redolog | /u01/app/oracle/oradata/ORCL/arch/ | 아카이브 로그 | 
| /rdsdbdata/admin/RDSCDB/adump | /u01/app/oracle/admin/ORCL/adump | 감사 덤프 | 
| /rdsdbdata/log | /u01/app/oracle | 진단 대상 | 

**변환 파라미터 추가:**

**Example 비CDB:**  

```
*.DB_FILE_NAME_CONVERT='/rdsdbdata/db/ORCL_A/datafile/','/u01/app/oracle/oradata/ORCL/datafile/'
*.LOG_FILE_NAME_CONVERT='/rdsdbdata/db/ORCL_A/onlinelog/','/u01/app/oracle/oradata/ORCL/onlinelog/'
```

**Example **멀티테넌트**(CDB 루트, `PDB$SEED` 및 모든 PDB 경로에 대한 매핑을 포함해야 함):**  

```
*.DB_FILE_NAME_CONVERT='/rdsdbdata/db/cdb/RDSCDB/datafile/','/u01/app/oracle/oradata/ORCL/cdb/datafile/','/rdsdbdata/db/cdb/pdbseed/','/u01/app/oracle/oradata/ORCL/pdbseed/datafile/','/rdsdbdata/db/pdb/RDSCDB_A/','/u01/app/oracle/oradata/ORCL/pdb/datafile/'
 *.LOG_FILE_NAME_CONVERT='/rdsdbdata/db/cdb/RDSCDB_A/onlinelog/','/u01/app/oracle/oradata/ORCL/onlinelog/'
```

**중요**: 멀티테넌트의 경우 파라미터 파일에 `enable_pluggable_database`=`TRUE`가 있는지 확인합니다. RDS Custom은 GUID 기반 하위 디렉터리가 있는 PDB 데이터 파일에 OMF를 사용합니다. 경로 매핑은 이를 자동으로 처리합니다.

 **전체 예제 파라미터 파일:** 

**Example 비 CDB 파라미터 파일(`initORCL.ora`)의 예:**  

```
ORCL.__data_transfer_cache_size=0
ORCL.__db_cache_size=6039797760
ORCL.__inmemory_ext_roarea=0
ORCL.__inmemory_ext_rwarea=0
ORCL.__java_pool_size=0
ORCL.__large_pool_size=33554432
ORCL.__oracle_base='/u01/app/oracle'
ORCL.__pga_aggregate_target=4966055936
ORCL.__sga_target=7449083904
ORCL.__shared_io_pool_size=134217728
ORCL.__shared_pool_size=1207959552
ORCL.__streams_pool_size=0
ORCL.__unified_pga_pool_size=0
*.archive_lag_target=300
*.audit_file_dest='/u01/app/oracle/admin/ORCL/adump'
*.compatible='19.0.0'
*.control_files='/u01/app/oracle/oradata/ORCL/controlfile/control-01.ctl'
*.db_block_checking='MEDIUM'
*.db_create_file_dest='/u01/app/oracle/oradata/ORCL'
*.db_name='ORCL'
*.db_recovery_file_dest_size=1073741824
*.db_unique_name='ORCL'
*.dbfips_140=FALSE
*.diagnostic_dest='/u01/app/oracle'
*.filesystemio_options='setall'
*.heat_map='OFF'
*.job_queue_processes=50
*.local_listener='(address=(protocol=tcp)(host=)(port=1521))'
*.log_archive_dest_1='location="/u01/app/oracle/oradata/ORCL/arch", valid_for=(ALL_LOGFILES,ALL_ROLES)'
*.log_archive_format='-%s-%t-%r.arc'
*.max_string_size='STANDARD'
*.memory_max_target=12385852416
*.memory_target=12385852416
*.open_cursors=300
*.pga_aggregate_target=0
*.processes=1673
*.recyclebin='OFF'
*.sga_target=0
*.undo_tablespace='UNDO_T1'
*.use_large_pages='FALSE'
*.DB_FILE_NAME_CONVERT='/rdsdbdata/db/ORCL_A/datafile/','/u01/app/oracle/oradata/ORCL/datafile/'
*.LOG_FILE_NAME_CONVERT='/rdsdbdata/db/ORCL_A/onlinelog/','/u01/app/oracle/oradata/ORCL/onlinelog/'
```

**Example 멀티테넌트 파라미터 파일(`initORCL.ora`)의 예:**  

```
ORCL.__data_transfer_cache_size=0
ORCL.__db_cache_size=6006243328
ORCL.__inmemory_ext_roarea=0
ORCL.__inmemory_ext_rwarea=0
ORCL.__java_pool_size=0
ORCL.__large_pool_size=33554432
ORCL.__oracle_base='/u01/app/oracle'
ORCL.__pga_aggregate_target=4966055936
ORCL.__sga_target=7415529472
ORCL.__shared_io_pool_size=134217728
ORCL.__shared_pool_size=1207959552
ORCL.__streams_pool_size=0
ORCL.__unified_pga_pool_size=0
*.archive_lag_target=300
*.audit_file_dest='/u01/app/oracle/admin/ORCL/adump'
*.compatible='19.0.0'
*.control_files='/u01/app/oracle/oradata/ORCL/controlfile/control-01.ctl'
*.db_block_checking='MEDIUM'
*.db_create_file_dest='/u01/app/oracle/oradata/ORCL/pdb/datafile'
*.db_create_online_log_dest_1='/u01/app/oracle/oradata/ORCL'
*.db_name='ORCL'
*.db_recovery_file_dest_size=1073741824
*.db_unique_name='ORCL'
*.dbfips_140=FALSE
*.diagnostic_dest='/u01/app/oracle'
*.enable_pluggable_database=TRUE
*.filesystemio_options='setall'
*.heat_map='OFF'
*.job_queue_processes=50
*.local_listener='(address=(protocol=tcp)(host=)(port=1521))'
*.log_archive_dest_1='location="/u01/app/oracle/oradata/ORCL/arch", valid_for=(ALL_LOGFILES,ALL_ROLES)'
*.log_archive_format='-%s-%t-%r.arc'
*.max_string_size='STANDARD'
*.memory_max_target=12361688064
*.memory_target=12361688064
*.noncdb_compatible=TRUE
*.open_cursors=300
*.pga_aggregate_target=0
*.processes=1670
*.recyclebin='OFF'
*.sga_target=0
*.undo_tablespace='UNDO_T1'
*.use_large_pages='FALSE'
*.DB_FILE_NAME_CONVERT='/rdsdbdata/db/cdb/RDSCDB/datafile/','/u01/app/oracle/oradata/ORCL/cdb/datafile/','/rdsdbdata/db/cdb/pdbseed/','/u01/app/oracle/oradata/ORCL/pdbseed/datafile/','/rdsdbdata/db/pdb/RDSCDB_A/','/u01/app/oracle/oradata/ORCL/pdb/datafile/'
*.LOG_FILE_NAME_CONVERT='/rdsdbdata/db/cdb/RDSCDB_A/onlinelog/','/u01/app/oracle/oradata/ORCL/onlinelog/'
```

**주요 파라미터 설명:**
+ `enable_pluggable_database=TRUE`: 멀티테넌트 CDB에 필요합니다. 이 파라미터는 플러그형 데이터베이스 기능을 활성화합니다.
+ `noncdb_compatible=TRUE`: 이전 버전과의 호환성을 위해 RDS Custom에서 설정합니다. 요구 사항에 따라 유지하거나 제거할 수 있습니다.
+ `db_create_file_dest`: Oracle Managed Files(OMF)의 기본 위치를 지정합니다. 멀티테넌트의 경우 PDB 데이터 파일 디렉터리를 가리킵니다.
+ `db_create_online_log_dest_1`: OMF를 사용할 때 온라인 다시 실행 로그의 위치를 지정합니다.
+ `DB_FILE_NAME_CONVERT`: RMAN 복제에 중요합니다. 소스 데이터 파일 경로를 대상 경로에 매핑합니다.
+ `LOG_FILE_NAME_CONVERT`: 소스 다시 실행 로그 경로를 대상 경로에 매핑합니다.
+ `memory_target` 및 `memory_max_target`: EC2 인스턴스 메모리에 따라 이를 조정합니다. 표시된 값은 예제입니다.
+ `processes`: Oracle에 연결할 수 있는 운영 체제 프로세스의 최대 수입니다. 워크로드에 따라 조정합니다.

**메모리 크기 조정 지침:**

EC2 인스턴스의 메모리 파라미터를 조정할 때:


|  **EC2 인스턴스 메모리**  |  **권장 memory\_target**  |  **권장 memory\_max\_target**  | 
| --- | --- | --- | 
| 16 GB | 12GB(12,884,901,888바이트) | 14GB(15,032,385,536바이트) | 
| 32GB | 24GB(25,769,803,776바이트) | 28GB(30,064,771,072바이트) | 
| 64GB | 48GB(51,539,607,552바이트) | 56GB(60,129,542,144바이트) | 
| 128GB | 96GB(103,079,215,104바이트) | 112GB(120,259,084,288바이트) | 

운영 체제 및 기타 프로세스에 대해 시스템 메모리의 약 20\~25%를 그대로 둡니다.

### 5단계: TNS 및 리스너 구성
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-5"></a>

두 인스턴스 모두에서 TNS 항목을 `tnsnames.ora`에 추가합니다.

**Example 비CDB:**  

```
DB_SOURCE = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {{<RDS_CUSTOM_IP>}})(PORT = 1521)) (CONNECT_DATA = (SID = ORCL)))
DB_TARGET = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {{<EC2_IP>}})(PORT = 1521)) (CONNECT_DATA = (SID = ORCL)))
```

**Example 멀티테넌트:**  

```
DB_SOURCE = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {{<RDS_CUSTOM_IP>}})(PORT = 1521)) (CONNECT_DATA = (SID = RDSCDB)))
DB_TARGET = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {{<EC2_IP>}})(PORT = 1521)) (CONNECT_DATA = (SID = ORCL)))
```

**Example EC2에서 리스너 구성(`$ORACLE_HOME/network/admin/listener.ora`):**  

```
LISTENER = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {{<EC2_IP>}})(PORT = 1521)))
SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME = ORCL) (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1) (SID_NAME = ORCL)))
```

**Example 리스너 시작:**  

```
lsnrctl start
```

**참고**  
RMAN 활성 중복의 경우 TNS 항목은 SID(SERVICE\_NAME 아님)를 사용하여 데이터베이스 인스턴스에 연결됩니다. 멀티테넌트 환경의 경우, 이는 CDB에 연결되고 RMAN은 모든 PDB를 자동으로 복제합니다.

### 6단계: EC2에서 `NOMOUNT`의 데이터베이스 시작
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-6"></a>

**Example**  

```
export ORACLE_SID=ORCL
export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH

sqlplus / as sysdba

SQL> STARTUP NOMOUNT PFILE='$ORACLE_HOME/dbs/initORCL.ora';
```

**Example 파라미터 확인:**  

```
SQL> SHOW PARAMETER db_name
SQL> SHOW PARAMETER control_files
SQL> SHOW PARAMETER enable_pluggable_database -- For multitenant
```

### 7단계: RMAN 활성 중복 수행
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-7"></a>

RMAN 활성 복제는 실행 중인 라이브 소스에서 대상으로 데이터베이스를 복사합니다. 소스 데이터베이스는 온라인 상태로 유지되며 이 프로세스 전반에 걸쳐 애플리케이션에서 액세스할 수 있습니다.

소스 인스턴스와 대상 인스턴스 모두에 RMAN을 연결합니다.

**Example**  

```
rman target sys/{{<password>}}@DB_SOURCE auxiliary sys/{{<password>}}@DB_TARGET
```

**Example 비CDB의 경우 예상 출력:**  

```
Recovery Manager: Release 19.0.0.0.0 - Production
connected to target database: ORCL (DBID=4089929259)
connected to auxiliary database: ORCL (not mounted)
```

**Example 멀티테넌트의 경우 예상 출력:**  

```
Recovery Manager: Release 19.0.0.0.0 - Production
connected to target database: RDSCDB (DBID=4089929259)
connected to auxiliary database: ORCL (not mounted)
```

**Example 활성 중복 명령 실행:**  

```
RMAN> DUPLICATE DATABASE TO 'ORCL' FROM ACTIVE DATABASE NOFILENAMECHECK;
```

**참고**  
**소스는 온라인 상태로 유지**: 소스 데이터베이스는 복제 중에 애플리케이션 요청을 계속 처리합니다.
**비CDB의 경우**: 온라인 상태로 유지되는 동안 전체 데이터베이스를 복제합니다.
**멀티테넌트의 경우**: 소스가 온라인 상태로 유지되는 동안 `CDB$ROOT`, `PDB$SEED` 및 모든 PDB를 포함한 전체 CDB를 복제합니다.
**NOFILENAMECHECK**: 파일 이름이 소스와 대상 간에 다르더라도 RMAN이 진행할 수 있도록 허용합니다.
**기간**: 데이터베이스 크기 및 네트워크 대역폭에 따라 다릅니다. 100GB 데이터베이스의 경우 30\~60분이 소요됩니다.
**네트워크 영향:** 복제 중 네트워크 대역폭 사용량이 높지만 소스 데이터베이스는 계속 액세스할 수 있음

**RMAN 활성 복제 프로세스에는 여러 단계가 포함됩니다.**

1. 소스 및 대상 데이터베이스에 연결

1. 대상의 메모리에서 `SPFILE` 생성

1. 제어 파일을 대상으로 복원

1. 대상 데이터베이스 탑재

1. 네트워크를 통해 소스에서 대상으로 모든 데이터 파일 복사(소스는 온라인 상태로 유지)

1. 대상 데이터베이스 복구

1. `RESETLOGS`를 사용하여 대상 데이터베이스 열기

**복제 중에 소스 데이터베이스는 다음을 수행합니다.**
+ `READ WRITE` 모드에서 유지
+ 연결을 계속 수락합니다.
+ 트랜잭션을 정상적으로 처리합니다.
+ 다시 실행 로그를 정상적으로 생성합니다.
+ 애플리케이션에 완전히 액세스할 수 있음

**Example 다른 세션의 진행 상황을 모니터링합니다.**  

```
SQL> SELECT sid, serial#, sofar, totalwork, ROUND(sofar/totalwork*100,2) pct_complete
FROM v$session_longops WHERE totalwork > 0 AND sofar <> totalwork;
```

 **RMAN 복제 중 세부 모니터링 및 문제 해결:** 

RMAN 복제가 실행되는 동안 몇 가지 방법을 사용하여 진행 상황을 모니터링할 수 있습니다.

1. **RMAN 출력 모니터링:**

   RMAN 세션에는 다음을 포함한 세부 진행 상황 정보가 표시됩니다.
   + 채널 할당
   + Datafile 복사 진행 상황
   + 예상 완료 시간
   + 처리된 바이트

   ```
   channel ORA_AUX_DISK_1: starting datafile copy
   input datafile file number=00001 name=/rdsdbdata/db/ORCL_A/datafile/system01.dbf
   output file name=/u01/app/oracle/oradata/ORCL/datafile/system01.dbf tag=TAG20260303T120000
   channel ORA_AUX_DISK_1: datafile copy complete, elapsed time: 00:05:23
   channel ORA_AUX_DISK_1: starting datafile copy
   input datafile file number=00003 name=/rdsdbdata/db/ORCL_A/datafile/sysaux01.dbf
   output file name=/u01/app/oracle/oradata/ORCL/datafile/sysaux01.dbf tag=TAG20260303T120000
   ```  
**Example 출력 예시:**  

   ```
   channel ORA_AUX_DISK_1: starting datafile copy
   input datafile file number=00001 name=/rdsdbdata/db/ORCL_A/datafile/system01.dbf
   output file name=/u01/app/oracle/oradata/ORCL/datafile/system01.dbf tag=TAG20260303T120000
   channel ORA_AUX_DISK_1: datafile copy complete, elapsed time: 00:05:23
   channel ORA_AUX_DISK_1: starting datafile copy
   input datafile file number=00003 name=/rdsdbdata/db/ORCL_A/datafile/sysaux01.dbf
   output file name=/u01/app/oracle/oradata/ORCL/datafile/sysaux01.dbf tag=TAG20260303T120000
   ```

1.  **장기 실행 작업 모니터링:**   
**Example 대상 EC2 인스턴스의 별도 SQL\*Plus 세션에서:**  

   ```
   SQL> SELECT sid, serial#, opname, sofar, totalwork,
          ROUND(sofar/totalwork*100,2) pct_complete,
          time_remaining, elapsed_seconds
   FROM v$session_longops
   WHERE totalwork > 0 AND sofar <> totalwork
   ORDER BY start_time;
   ```

**이 쿼리는 다음을 보여줍니다.**
   + `opname`: 작업 이름(예: ‘RMAN: 전체 데이터 파일 복원’)
   + `sofar`: 지금까지 처리된 블록
   + `totalwork`: 처리할 총 블록 수
   + `pct_complete`: 완료율
   + `time_remaining`: 남은 예상 초
   + `elapsed_seconds`: 지금까지 경과된 시간

1. **RMAN 채널 모니터링:**  
**Example**  

   ```
   SQL> SELECT sid, serial#, context, sofar, totalwork,
          ROUND(sofar/totalwork*100,2) pct_complete
          FROM v$session_longops
   WHERE opname LIKE 'RMAN%'
          AND totalwork > 0
          AND sofar <> totalwork;
   ```

1. **알림 로그 확인:**  
**Example 대상 EC2 인스턴스에서 오류 또는 경고가 있는지 알림 로그를 모니터링합니다.**  

   ```
   tail -f $ORACLE_BASE/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log
   ```

**RMAN 복제 중 일반적인 문제:**
   + **네트워크 제한 시간**

     ```
     RMAN-03009: failure of duplicate command on ORA_AUX_DISK_1 channel
     ORA-03135: connection lost contact
     ```

     **해결** 방법: 두 인스턴스 모두에서 `sqlnet.ora`의 네트워크 제한 시간 값을 늘립니다.

     ```
     SQLNET.RECV_TIMEOUT=600
     SQLNET.SEND_TIMEOUT=600
     ```
   + **대상에 공간 부족**

     ```
     RMAN-03009: failure of duplicate command
     ORA-19504: failed to create file "/u01/app/oracle/oradata/ORCL/datafile/users01.dbf"
     ORA-27040: file create error, unable to create file
     Linux-x86_64 Error: 28: No space left on device
     ```

     **솔루션**: 사용 가능한 공간을 확인하고 EBS 볼륨 용량을 더 추가합니다.

     ```
     df -h /u01/app/oracle/oradata
     ```
   + **파라미터 파일 오류**

     ```
     RMAN-05021: this configuration cannot be used
     RMAN-06004: ORACLE error from auxiliary database: ORA-01261: Parameter db_create_file_dest destination string cannot be translated
     ```

     **해결 방법**: 파라미터 파일의 모든 디렉터리가 존재하고 적절한 권한이 있는지 확인합니다.
   + **암호 파일 불일치**

     ```
     RMAN-00571: ===========================================================
     RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
     RMAN-00571: ===========================================================
     RMAN-03002: failure of duplicate command at 03/03/2026 12:00:00
     RMAN-06136: ORACLE error from auxiliary database: ORA-01017: invalid username/password; logon denied
     ```

     **해결 방법**: 대상의 암호 파일이 소스와 일치하고 올바른 이름(`orapwORCL`)이 있는지 확인합니다.

### 8단계: PDB 열기(멀티테넌트만 해당)
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-8"></a>

RMAN 복제가 완료되면 EC2의 CDB가 `READ WRITE` 모드에서 열려 있지만 모든 PDB는 `MOUNTED` 상태입니다. 이는 예상되는 동작입니다. 수동으로 열어야 합니다.

현재 PDB 상태 확인:

```
SQL> SELECT con_id, name, open_mode FROM v$pdbs;
```

예상 출력(`ORCLDB`라는 PDB 하나가 있는 예):

```
CON_ID     NAME                           OPEN_MODE
---------- ------------------------------ ----------
2          PDB$SEED                       READ ONLY
3          ORCLDB                         MOUNTED
```

모든 PDB를 엽니다.

```
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;
Pluggable database altered.
```

모든 PDB가 이제 `READ WRITE` 모드에서 열려 있는지 확인:

```
SQL> SELECT con_id, name, open_mode, restricted FROM v$pdbs;
```

예상 결과:

```
CON_ID     NAME                           OPEN_MODE  RES
---------- ------------------------------ ---------- ---
2          PDB$SEED                       READ ONLY  NO
3          ORCLDB                         READ WRITE NO
```

저장 상태 메서드(Oracle 19c 권장)를 사용하여 시작 시 자동 열기 구성:

```
SQL> ALTER PLUGGABLE DATABASE ALL SAVE STATE;
Pluggable database altered.
```

이렇게 하면 Oracle에 PDB하고 CDB 시작 시 복원하도록 지시합니다.

저장된 상태를 확인합니다.

```
SQL> SELECT con_name, instance_name, state FROM dba_pdb_saved_states;
```

PDB 서비스가 리스너에 등록되어 있는지 확인합니다.

```
lsnrctl services
```

예상 출력에는 CDB 및 각 PDB에 대한 서비스가 표시되어야 합니다. 서비스가 표시되지 않는 경우:

```
SQL> ALTER SYSTEM REGISTER;
```

그런 다음 `lsnrctl services`로 다시 확인합니다.

### 9단계: RDS Custom 객체 제거
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-9"></a>

이제 EC2의 자체 관리형 데이터베이스이므로 RDS 사용자 지정 사용자 및 객체를 제거해야 합니다. 정리 프로세스는 비CDB 아키텍처와 멀티테넌트 아키텍처 간에 다릅니다.

**중요**  
RDS별 사용자 및 테이블스페이스를 삭제하기 전에 다음 스키마 아래에 애플리케이션 객체가 없는지 확인합니다.

```
SQL> SELECT owner, object_type, COUNT(*)
FROM dba_objects
WHERE owner IN ('RDSADMIN', 'RDS_DATAGUARD')
  AND object_name NOT LIKE 'RDS%'
  AND object_name NOT LIKE 'SYS_%'
GROUP BY owner, object_type;
```

애플리케이션 객체가 발견되면 계속하기 전에 적절한 애플리케이션 스키마로 마이그레이션합니다.

**Example 비CDB:**  

```
SQL> DROP USER RDSADMIN CASCADE;
SQL> DROP USER RDS_DATAGUARD CASCADE;
SQL> DROP DIRECTORY OPATCH_INST_DIR;
SQL> DROP DIRECTORY OPATCH_LOG_DIR;
SQL> DROP DIRECTORY OPATCH_SCRIPT_DIR;
SQL> DROP TABLESPACE RDSADMIN INCLUDING CONTENTS AND DATAFILES;

-- Verify removal
SQL> SELECT username FROM dba_users WHERE username LIKE '%RDS%';
```

예상 결과: `no rows selected`

**멀티테넌트:**

멀티테넌트 환경에서 RDS Custom은 모든 PDB에서 볼 수 있는 `CDB$ROOT`에서 공통 사용자를 생성합니다. `CDB$ROOT`에서 정리해야 합니다.

```
-- Connect to CDB$ROOT
SQL> SHOW CON_NAME;
-- Check for RDS-specific common users (including C## prefixed users)
SQL> SELECT username, common, con_id FROM cdb_users
WHERE username LIKE '%RDS%' OR username LIKE 'C##RDS%'
ORDER BY username;

-- Drop non-common users
SQL> DROP USER RDSADMIN CASCADE;
SQL> DROP USER RDS_DATAGUARD CASCADE;

-- If any C## common users exist
-- SQL> DROP USER C##RDSADMIN CASCADE
;
-- Drop directories and tablespace
SQL> DROP DIRECTORY OPATCH_INST_DIR;
SQL> DROP DIRECTORY OPATCH_LOG_DIR;
SQL> DROP DIRECTORY OPATCH_SCRIPT_DIR;
SQL> DROP TABLESPACE RDSADMIN INCLUDING CONTENTS AND DATAFILES;

-- Verify removal from CDB$ROOT
SQL> SELECT username FROM dba_users WHERE username LIKE '%RDS%';

-- Verify removal from each PDB
SQL> ALTER SESSION SET CONTAINER = {{<PDB_NAME>}};
SQL> SELECT username FROM dba_users WHERE username LIKE '%RDS%';
```

모든 쿼리에 대한 예상 출력: `no rows selected`

### 10단계: 자동 시작 구성
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-10"></a>

`SPFILE` 생성:

```
SQL> CREATE SPFILE FROM PFILE='$ORACLE_HOME/dbs/initORCL.ora';
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;
```

멀티테넌트의 경우 PDB가 열려 있는지 확인합니다.

```
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;
```

편집 `/etc/oratab`:

```
ORCL:/u01/app/oracle/product/19.0.0/dbhome_1:Y
```

### 11단계: 최종 검증
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-step-11"></a>

**Example 비CDB:**  

```
SQL> SELECT name, open_mode, log_mode FROM v$database;
SQL> SELECT SUM(bytes)/1024/1024/1024 AS size_gb FROM dba_data_files;
SQL> SELECT COUNT(*) FROM dba_objects WHERE status = 'INVALID';
```

**Example 멀티테넌트:**  

```
SQL> SELECT name, open_mode, log_mode, cdb FROM v$database;
SQL> SELECT con_id, name, open_mode FROM v$pdbs;
SQL> SELECT SUM(bytes)/1024/1024/1024 AS total_size_gb FROM cdb_data_files;
SQL> SELECT con_id, COUNT(*) FROM cdb_objects WHERE status = 'INVALID' GROUP BY con_id;
```

```
Test application connectivity:
# Non-CDB
sqlplus {{<app_user>}}/{{<password>}}@{{<EC2_IP>}}:1521/ORCL

# Multitenant (connect to PDB)
sqlplus {{<app_user>}}/{{<password>}}@{{<EC2_IP>}}:1521/{{<PDB_NAME>}}
```

 **12단계: RDS Custom 자동화 다시 시작** 

```
aws rds modify-db-instance \
--db-instance-identifier my-custom-instance \
--automation-mode full \
--region us-east-1
```

 

## 옵션 2: Oracle Data Guard를 사용한 물리적 마이그레이션
<a name="RDS-Custom-for-Oracle-end-of-support-option-2"></a>



이 섹션에서는 Oracle Data Guard를 사용하여 Oracle 데이터베이스를 RDS Custom for Oracle에서 EC2로 마이그레이션하는 자세한 단계를 제공합니다. 이 방법은 가동 중지 시간을 최소화해야 하는 마이그레이션에 적합합니다.

### Oracle Data Guard를 사용해야 하는 경우
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-when-use-odg"></a>

**다음과 같은 경우 Oracle Data Guard를 선택합니다.**
+ 가동 중지 시간을 최소화해야 합니다(전환하는 데 몇 초에서 몇 분).
+ 프로덕션 또는 미션 크리티컬 데이터베이스를 마이그레이션하는 경우
+ 컷오버 전에 지속적인 동기화가 필요합니다.
+ 기본 제공 대체 기능을 원하는 경우
+ 마이그레이션을 커밋하기 전에 대상 데이터베이스를 테스트해야 합니다.

### Oracle Data Guard 개요
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-odg-overview"></a>

Oracle Data Guard는 기본 데이터베이스에서 다시 실행 로그를 지속적으로 전송하고 적용하여 동기화된 대기 데이터베이스를 유지합니다. 마이그레이션을 완료할 준비가 되면 가동 중지 시간을 최소화하면서(몇 초에서 몇 분) EC2 대기를 기본으로 승격하는 전환을 수행합니다. 멀티테넌트 데이터베이스의 경우 Data Guard는 모든 PDB를 포함한 전체 CDB를 자동으로 보호합니다. PDB에서 생성된 다시 실행은 대기 상태로 전송되고 대기 상태의 해당 PDB에 적용됩니다.

### Oracle Data Guard의 마이그레이션 워크플로
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-odg-workflow"></a>

**RDS Custom DB 인스턴스(기본) 단계:**

1. Amazon RDS Custom 자동화 일시 중지

1. 데이터베이스 아키텍처 확인(비 CDB 또는 PDB가 있는 CDB)

1. 기본 데이터베이스가 아카이브 로그 모드에서 실행 중이고 `FORCE_LOGGING`이 활성화되어 있는지 확인합니다.

1. 암호 파일 만들기

1. 기본 데이터베이스의 RMAN 온라인 백업 수행(또는 활성 중복 사용)

1. 소스 데이터베이스에서 파라미터 파일 생성

1. 백업 세트, 파라미터 파일 및 암호 파일을 대상 EC2 인스턴스에 복사합니다.

**EC2 DB 인스턴스(대기) 단계:**

1. 소스에서 EC2 인스턴스로 모든 파일 복사

1. EC2 인스턴스에 암호 파일 복사

1. EC2용 파라미터 파일 편집(아키텍처별)

1. 파라미터 파일에서 서버 파라미터 파일 생성

1. 대기 제어 파일 및 데이터베이스 복원

**데이터 보호 구성 단계:**

1. 두 인스턴스 모두에서 Oracle 리스너 구성

1. 두 인스턴스 모두에서 tnsnames.ora 구성

1. 두 인스턴스 모두에서 Oracle Data Guard 브로커 시작(선택 사항이지만 권장됨)

1. Oracle Data Guard 구성 활성화

1. EC2 대기 인스턴스에서 fal\_server 및 fal\_client 구성

1. 두 인스턴스 모두에서 대기 재실행 로그 파일 구성

1. 대기 인스턴스 복구

1. 수동 전환 실시

1. 데이터베이스(및 멀티테넌트용 PDB) 열기

1. PDB 자동 열기 구성(멀티테넌트만 해당)

1. RDS Custom 특정 사용자 및 객체 제거

1. SPFILE 생성 및 자동 시작 구성

### 1단계: Amazon RDS Custom 자동화 일시 중지
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-1"></a>

RDS Custom 인스턴스의 자동화 모드를 일시 중지합니다. `--resume-full-automation-mode-minute` 파라미터는 데이터베이스 크기와 예상 Data Guard 설정 시간에 따라 조정해야 합니다.

```
aws rds modify-db-instance \
  --db-instance-identifier my-custom-instance \
  --automation-mode all-paused \
  --resume-full-automation-mode-minute 480 \
  --region us-east-1
```

자동화 상태 검증:

```
aws rds describe-db-instances \
  --db-instance-identifier my-custom-instance \
  --region us-east-1 \
  --query 'DBInstances[0].AutomationMode'
```

예상 결과: ‘`all-paused`’

### 2단계: 아카이브 로그 모드 및 `FORCE_LOGGING` 확인
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-2"></a>

Oracle Data Guard를 사용하려면 기본 데이터베이스가 강제 로깅이 활성화된 아카이브 로그 모드에 있어야 합니다.

```
sqlplus / as sysdba
SQL> SELECT log_mode, force_logging FROM v$database;
```

예상 결과:

```
LOG_MODE     FORCE_LOGGING
------------ -------------
ARCHIVELOG   YES
```

강제 로깅이 활성화되지 않은 경우 다음을 실행합니다.

```
SQL> ALTER DATABASE FORCE LOGGING;
```

### 3단계: 암호 및 파라미터 파일 생성
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-3"></a>

`orapwd`를 사용하여 암호 파일을 생성합니다. AWS Secrets Manager에서 SYS 암호를 검색합니다.

```
# Non-CDB
$ORACLE_HOME/bin/orapwd file=/rdsdbdata/config/orapwORCL password={{<SYS_PASSWORD>}} entries=10

# Multitenant
$ORACLE_HOME/bin/orapwd file=/rdsdbdata/config/orapwRDSCDB password={{<SYS_PASSWORD>}} entries=10
```

소스 데이터베이스에서 파라미터 파일을 생성합니다.

```
sqlplus / as sysdba
SQL> CREATE PFILE='/tmp/initORCL.ora' FROM SPFILE; -- Non-CDB
SQL> CREATE PFILE='/tmp/initRDSCDB.ora' FROM SPFILE; -- Multitenant
```

### 4단계: RMAN 백업 수행 또는 활성 중복 사용
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-4"></a>

대기 데이터베이스를 생성하는 두 가지 옵션이 있습니다.

#### 옵션 A: RMAN 온라인 백업(대부분의 시나리오에서 권장됨)
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-4-a"></a>

백업 디렉터리를 생성하고 데이터베이스를 백업합니다.

```
mkdir -p /rdsdbdata/backup
rman target /
RMAN> run {
  backup as compressed backupset
  filesperset 2
  format '/rdsdbdata/backup/db_%U'
  database;
  sql 'alter system archive log current';
  backup as compressed backupset
  filesperset 50
  format '/rdsdbdata/backup/arch_%U'
  archivelog all;
}

RMAN> backup current controlfile for standby format '/rdsdbdata/backup/standby.ctl';
```

**참고**  
멀티테넌트 환경에서 데이터베이스 키워드를 사용하면 모든 PDB를 포함한 전체 CDB가 자동으로 백업됩니다.

#### 옵션 B: 활성 중복(대체 방법)
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-4-b"></a>

백업 단계를 건너뛰고 RMAN 활성 복제를 사용하여 네트워크를 통해 대기를 직접 빌드합니다. 따라서 백업 스토리지 및 파일 전송이 필요하지 않습니다. TNS 및 리스너를 구성한 후(아래 참조) 다음을 실행합니다.

```
RMAN> DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE DORECOVER;
```

이 지침은 옵션 A(백업 기반)에 초점을 맞추지만 옵션 B는 유효한 대안입니다.

### 5단계: EC2로 파일 전송
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-5"></a>

원하는 파일 전송 방법을 선택합니다. 이 지침에서는 Amazon S3를 예제로 사용합니다.

**Amazon S3 사용**

**Example 비 CDB의 경우:**  

```
# Copy files to Amazon S3 from the RDS Custom instance
aws s3 cp /rdsdbdata/backup s3://{{<YOUR_BUCKET>}}/ --recursive
aws s3 cp /tmp/initORCL.ora s3://{{<YOUR_BUCKET>}}/
aws s3 cp /rdsdbdata/config/orapwORCL s3://{{<YOUR_BUCKET>}}/

# On EC2, download files
aws s3 cp s3://{{<YOUR_BUCKET>}}/backup /u01/app/oracle/backup/ --recursive
aws s3 cp s3://{{<YOUR_BUCKET>}}/initORCL.ora $ORACLE_HOME/dbs/
aws s3 cp s3://{{<YOUR_BUCKET>}}/orapwORCL $ORACLE_HOME/dbs/
```

**Example 멀티테넌트의 경우:**  

```
# Copy files to Amazon S3 from the RDS Custom instance
aws s3 cp /rdsdbdata/backup s3://{{<YOUR_BUCKET>}}/ --recursive
aws s3 cp /tmp/initRDSCDB.ora s3://{{<YOUR_BUCKET>}}/
aws s3 cp /rdsdbdata/config/orapwRDSCDB s3://{{<YOUR_BUCKET>}}/

# On EC2, download and rename files to use ORCL naming
aws s3 cp s3://{{<YOUR_BUCKET>}}/backup /u01/app/oracle/backup/ --recursive
aws s3 cp s3://{{<YOUR_BUCKET>}}/initRDSCDB.ora $ORACLE_HOME/dbs/initORCL.ora
aws s3 cp s3://{{<YOUR_BUCKET>}}/orapwRDSCDB $ORACLE_HOME/dbs/orapwORCL
```

### 6단계: EC2에서 파라미터 파일 편집
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-6"></a>

EC2 인스턴스에서 `$ORACLE_HOME/dbs/initORCL.ora`를 편집하고 다음과 같이 중요한 변경을 수행합니다.

1. **데이터베이스 이름 업데이트**: 멀티테넌트의 경우 `RDSCDB`의 모든 발생을 `ORCL`로 변경합니다.

1. **db\_unique\_name**: `ORCL_A`(또는 `RDSCDB_A`)에서 `ORCL_B`로

1. **RDS Custom 경로를 EC2 경로로 변환**: `/u01/app/oracle/`을 `/rdsdbdata/`로 바꾸기

1. 

****RDS Custom 관련 파라미터 제거****
   + `dg_broker_config_file1` 및 `dg_broker_config_file2`(있는 경우)
   + `standby_file_management`(있는 경우)
   + `spfile`(나중에 새 `SPFILE` 생성)
   + 대기 대상을 가리키는 모든 `log_archive_dest` 파라미터

1. EC2 인스턴스 크기에 따라 **메모리 파라미터 조정**(선택 사항이지만 권장됨)

 **경로 매핑:** 

**비CDB:**
+ `/rdsdbdata/db/ORCL_A/datafile/` → `/u01/app/oracle/oradata/ORCL/datafile/`
+ `/rdsdbdata/db/ORCL_A/controlfile/` → `/u01/app/oracle/oradata/ORCL/controlfile/`
+ `/rdsdbdata/db/ORCL_A/onlinelog/` → `/u01/app/oracle/oradata/ORCL/onlinelog/`
+ `/rdsdbdata/admin/ORCL/adump` → `/u01/app/oracle/admin/ORCL/adump`

**멀티테넌트:**
+ `/rdsdbdata/db/cdb/RDSCDB/datafile/` → `/u01/app/oracle/oradata/ORCL/cdb/datafile/`
+ `/rdsdbdata/db/cdb/pdbseed/` → `/u01/app/oracle/oradata/ORCL/pdbseed/datafile/`
+ `/rdsdbdata/db/pdb/RDSCDB_A/` → `/u01/app/oracle/oradata/ORCL/pdb/datafile/`
+ `/rdsdbdata/db/cdb/RDSCDB_A/controlfile/` → `/u01/app/oracle/oradata/ORCL/controlfile/`
+ `/rdsdbdata/admin/RDSCDB/adump` → `/u01/app/oracle/admin/ORCL/adump`

**중요**: 멀티테넌트의 경우 파라미터 파일에 `enable_pluggable_database`=`TRUE`가 있는지 확인합니다.

### 7단계: `SPFILE` 생성 및 대기 데이터베이스 복원
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-7"></a>

인스턴스 시작 및 SPFILE 만들기:

```
sqlplus / as sysdba
SQL> STARTUP NOMOUNT PFILE='$ORACLE_HOME/dbs/initORCL.ora';
SQL> CREATE SPFILE='/u01/app/oracle/admin/ORCL/pfile/spfileORCL.ora' FROM PFILE='$ORACLE_HOME/dbs/initORCL.ora';
SQL> SHUTDOWN IMMEDIATE;
```

심볼 링크 만들기:

```
ln -sfn /u01/app/oracle/admin/ORCL/pfile/spfileORCL.ora $ORACLE_HOME/dbs/spfileORCL.ora
```

인스턴스를 시작하고 복원합니다.

```
SQL> STARTUP NOMOUNT;
rman target /
```

백업 파일이 소스와 다른 경로에 있는 경우 먼저 파일을 카탈로그화합니다.

```
RMAN> catalog start with '/u01/app/oracle/backup/';
```

대기 제어 파일 및 탑재 복원:

```
RMAN> restore standby controlfile from '/u01/app/oracle/backup/standby.ctl';
RMAN> alter database mount;
```

데이터 파일 경로가 다른 경우(예: ASM 사용) `SET NEWNAME`을 사용합니다.

```
RMAN> run {
set newname for database to '+DATA/%b';
restore database;
switch datafile all;
}
```

그렇지 않으면 복원하기만 하면 됩니다.

```
RMAN> restore database;
```

데이터베이스를 마지막으로 사용 가능한 시퀀스로 복구합니다.

```
RMAN> list backup of archivelog all;
RMAN> recover database until sequence <LAST_SEQ + 1>;
```

**참고**  
멀티테넌트의 경우 RMAN은 모든 PDB를 자동으로 복원하고 복구합니다. 각 PDB를 별도로 복원할 필요는 없습니다.

### 8단계: TNS 및 리스너 구성
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-8"></a>

두 인스턴스 모두에서 TNS 항목을 `tnsnames.ora`에 추가합니다.

**Example 비CDB:**  

```
ORCL_A = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {{<RDS_CUSTOM_IP>}})(PORT = 1521)) (CONNECT_DATA = (SID = ORCL)))
ORCL_B = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {{<EC2_IP>}})(PORT = 1521)) (CONNECT_DATA = (SID = ORCL)))
```

**Example 멀티테넌트:**  

```
RDSCDB_A = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {{<RDS_CUSTOM_IP>}})(PORT = 1521)) (CONNECT_DATA = (SID = RDSCDB)))
ORCL_B = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {{<EC2_IP>}})(PORT = 1521)) (CONNECT_DATA = (SID = ORCL)))
```

두 인스턴스 모두에서 리스너를 구성합니다. RDS Custom에서 `listener.ora`에 다음을 추가합니다.

**Example 비 CDB의 경우:**  

```
SID_LIST_L_ORCL_DG=(SID_LIST = (SID_DESC = (SID_NAME = ORCL)(GLOBAL_DBNAME = ORCL) (ORACLE_HOME = /rdsdbbin/oracle.19.custom.r1.EE.1)))
L_ORCL_DG=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(PORT = 1521)(HOST = {{<RDS_CUSTOM_IP>}})))
```

**Example 멀티테넌트의 경우:**  

```
SID_LIST_L_RDSCDB_DG=(SID_LIST = (SID_DESC = (SID_NAME = RDSCDB)(GLOBAL_DBNAME = RDSCDB) (ORACLE_HOME = /rdsdbbin/oracle.19.custom.r1.EE-CDB.1)))
L_RDSCDB_DG=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(PORT = 1521)(HOST = {{<RDS_CUSTOM_IP>}})))
```

리스너 시작:

```
$ORACLE_HOME/bin/lsnrctl start L_ORCL_DG # or L_RDSCDB_DG for multitenant
```

EC2에서 `$ORACLE_HOME/network/admin/listener.ora`를 생성합니다.

```
SID_LIST_L_ORCL_DG=(SID_LIST = (SID_DESC = (SID_NAME = ORCL)(GLOBAL_DBNAME = ORCL) (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1)))
L_ORCL_DG=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(PORT = 1521)(HOST = {{<EC2_IP>}})))
```

리스너 시작:

```
$ORACLE_HOME/bin/lsnrctl start L_ORCL_DG
```

**참고**  
원하는 경우 RDS Custom에서 기존 리스너를 사용할 수 있지만 별도의 Data Guard 리스너를 생성하면 격리가 향상됩니다.

**중요**  
`tnsping` 또는 `listener` 연결이 실패하면 EC2의 `iptables` 규칙을 확인합니다. 많은 EC2 Linux 인스턴스에는 포트 1521을 차단하는 기본 `iptables` 규칙이 있습니다. 규칙 추가: `sudo iptables -I INPUT 5 -p tcp --dport 1521 -j ACCEPT`

### 9단계: Data Guard 브로커 및 구성 활성화
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-9"></a>

두 인스턴스 모두에서 Data Guard 브로커를 활성화합니다.

```
sqlplus / as sysdba
SQL> ALTER SYSTEM SET dg_broker_start=true;
```

RDS Custom 기본에서 Data Guard 브로커에 연결하고 구성을 생성합니다.

```
dgmgrl /
```

**Example 비 CDB의 경우:**  

```
DGMGRL> CREATE CONFIGURATION my_dg_config AS PRIMARY DATABASE IS ORCL_A CONNECT IDENTIFIER IS ORCL_A;
DGMGRL> ADD DATABASE ORCL_B AS CONNECT IDENTIFIER IS ORCL_B MAINTAINED AS PHYSICAL;
```

 

**Example 멀티테넌트의 경우:**  

```
DGMGRL> CREATE CONFIGURATION my_dg_config AS PRIMARY DATABASE IS RDSCDB_A CONNECT IDENTIFIER IS RDSCDB_A;
DGMGRL> ADD DATABASE ORCL_B AS CONNECT IDENTIFIER IS ORCL_B MAINTAINED AS PHYSICAL;
```

정적 연결 식별자를 설정하고 다음을 활성화합니다.

 

**Example 비 CDB의 경우:**  

```
DGMGRL> edit database orcl_a set property StaticConnectIdentifier='(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(PORT=1521)(HOST=<RDS_CUSTOM_IP>))(CONNECT_DATA=(SID=ORCL)(SERVER=DEDICATED)))';
DGMGRL> edit database orcl_b set property StaticConnectIdentifier='(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(PORT=1521)(HOST={{<EC2_IP>}}))(CONNECT_DATA=(SID=ORCL)(SERVER=DEDICATED)))';
DGMGRL> ENABLE CONFIGURATION;
```

 

**Example 멀티테넌트의 경우:**  

```
DGMGRL> edit database rdscdb_a set property StaticConnectIdentifier='(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(PORT=1521)(HOST=<RDS_CUSTOM_IP>))(CONNECT_DATA=(SID=RDSCDB)(SERVER=DEDICATED)))';
DGMGRL> edit database orcl_b set property StaticConnectIdentifier='(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(PORT=1521)(HOST={{<EC2_IP>}}))(CONNECT_DATA=(SID=ORCL)(SERVER=DEDICATED)))';
DGMGRL> ENABLE CONFIGURATION;
```

**참고**  
Data Guard 브로커는 선택 사항이지만 더 쉬운 관리를 위해 권장됩니다. 간단한 마이그레이션을 위해 브로커 없이 Data Guard를 수동으로 구성할 수 있습니다.

**참고**  
CDB에 대해 Data Guard를 활성화하면 모든 PDB가 자동으로 보호됩니다. PDB에서 생성된 다시 실행은 대기 상태로 전송되고 대기 상태의 해당 PDB에 적용됩니다.

### 10단계: 대기 재실행 로그 구성 및 복구 시작
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-10"></a>

EC2 대기 인스턴스에서 대기 재실행 로그 파일(n\+1, 여기서 n은 온라인 재실행 로그 그룹 수)을 추가합니다.

```
ALTER DATABASE ADD STANDBY LOGFILE ('slog1.rdo') SIZE 128M;
ALTER DATABASE ADD STANDBY LOGFILE ('slog2.rdo') SIZE 128M;
ALTER DATABASE ADD STANDBY LOGFILE ('slog3.rdo') SIZE 128M;
ALTER DATABASE ADD STANDBY LOGFILE ('slog4.rdo') SIZE 128M;
ALTER DATABASE ADD STANDBY LOGFILE ('slog5.rdo') SIZE 128M;
```

**참고**  
멀티테넌트의 경우 대기 재실행 로그는 CDB 수준에서 생성되며 모든 PDB에서 공유됩니다.

대기 상태에서 FAL 파라미터를 구성합니다.

 

**Example 비 CDB의 경우:**  

```
SQL> alter system set fal_server = 'ORCL_A';
SQL> alter system set fal_client = 'ORCL_B';
```

 

**Example 멀티테넌트의 경우:**  

```
SQL> alter system set fal_server = 'RDSCDB_A';
SQL> alter system set fal_client = 'ORCL_B';
```

관리형 복구 시작:

```
SQL> recover managed standby database disconnect from session;
```

적용 지연을 모니터링합니다.

```
SQL> SELECT name, value FROM v$dataguard_stats WHERE name = 'apply lag';
```

**Data Guard 동기화의 세부 모니터링 및 관리:**

성공적인 마이그레이션을 위해서는 Data Guard 모니터링이 중요합니다. 포괄적인 모니터링 기법은 다음과 같습니다.

1. **Data Guard 통계 모니터링:**

   ```
   -- Comprehensive Data Guard statistics
   SQL> SELECT name, value, unit, time_computed, datum_time
   FROM v$dataguard_stats
   ORDER BY name;
   ```

   모니터링할 주요 지표:
   + 전송 지연: 기본에서 다시 실행이 생성된 시점과 대기 상태에서 수신된 시점 간의 시간 차이
   + 지연 적용: 다시 실행이 생성되고 대기 상태에서 적용된 시점 간의 시간 차이
   + 적용 속도: 다시 실행이 적용되는 속도(MB/초)
   + 다시 실행 수신됨: 대기에서 수신한 총 다시 실행 수
   + 다시 실행 적용됨: 대기에 의해 적용된 총 다시 실행

1. **아카이브 로그 전송 모니터링:**

   기본(RDS Custom)에서:

   ```
   -- Check archive log generation rate
   SQL> SELECT TO_CHAR(first_time, 'YYYY-MM-DD HH24') AS hour,
          COUNT(*) AS log_count,
          ROUND(SUM(blocks * block_size)/1024/1024/1024, 2) AS size_gb
   FROM v$archived_log
   WHERE first_time > SYSDATE - 1
   GROUP BY TO_CHAR(first_time, 'YYYY-MM-DD HH24')
   ORDER BY hour;
   
   -- Check archive log destination status
   SQL> SELECT dest_id, status, error, destination
   FROM v$archive_dest
   WHERE status != 'INACTIVE';
   ```

   대기(EC2)에서:

   ```
   -- Check archive log apply status
   SQL> SELECT sequence#, first_time, next_time, applied
   FROM v$archived_log
   WHERE applied = 'NO'
   ORDER BY sequence#;
   
   -- Check archive log gap
   SQL> SELECT thread#, low_sequence#, high_sequence#
   FROM v$archive_gap;
   ```

1. **관리형 복구 프로세스 모니터링:**

   ```
   -- Check if managed recovery is running
   SQL> SELECT process, status, thread#, sequence#, block#, blocks
   FROM v$managed_standby
   WHERE process LIKE 'MRP%' OR process LIKE 'RFS%';
   
   -- Check recovery progress
   SQL> SELECT process, status, sequence#,
          TO_CHAR(timestamp, 'YYYY-MM-DD HH24:MI:SS') AS timestamp
   FROM v$managed_standby
   ORDER BY process;
   ```

1. **멀티테넌트에 대한 다시 실행 적용률 모니터링:**

   멀티테넌트 데이터베이스의 경우 PDB당 적용률을 모니터링합니다.

   ```
   -- Check redo apply rate per container
   SQL> SELECT con_id, name,
          ROUND(SUM(value)/1024/1024, 2) AS redo_applied_mb
   FROM v$con_sysstat cs, v$containers c
   WHERE cs.con_id = c.con_id
     AND cs.name = 'redo size'
   GROUP BY con_id, name
   ORDER BY con_id;
   ```

1. **대기 재실행 로그 모니터링:**

   ```
   -- Check standby redo log status
   SQL> SELECT group#, thread#, sequence#, bytes/1024/1024 AS size_mb, status
   FROM v$standby_log
   ORDER BY group#;
   
   -- Check if standby redo logs are being used
   SQL> SELECT group#, thread#, sequence#, status, archived
   FROM v$standby_log
   WHERE status = 'ACTIVE';
   ```

1. **동기화 완료 추정:**

   적용률을 기준으로 남은 시간을 계산합니다.

   ```
   -- Calculate estimated time to catch up
   SQL> SELECT
          ROUND((SELECT value FROM v$dataguard_stats WHERE name = 'apply lag')/60, 2) AS lag_minutes,
          ROUND((SELECT value FROM v$dataguard_stats WHERE name = 'apply rate')/1024, 2) AS apply_rate_mbps,
          ROUND(
            (SELECT value FROM v$dataguard_stats WHERE name = 'apply lag') /
            NULLIF((SELECT value FROM v$dataguard_stats WHERE name = 'apply rate'), 0) / 60,
            2
          ) AS estimated_catchup_minutes
   FROM dual;
   ```

#### 일반적인 Data Guard 동기화 문제:
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-10-common-issues"></a>



##### 문제 1: 높은 적용 지연
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-10-common-issues-1"></a>

증상:

```
SQL> SELECT name, value FROM v$dataguard_stats WHERE name = 'apply lag';
NAME                             VALUE
-------------------------------- -----
apply lag                        +00 01:30:00
```

원인 및 해결 방법:
+ **대기 시 CPU/IO 부족**: EC2 인스턴스 유형 업그레이드 또는 EBS IOPS 증가
+ **네트워크 대역폭 제한**: 향상된 네트워킹 또는 더 높은 대역폭 인스턴스 유형 사용
+ **트랜잭션 속도가 높은 여러 PDB**: 다시 실행 적용 병렬 처리를 늘리는 것이 좋음(Active Data Guard 라이선스 필요).

```
-- Increase apply parallelism (requires Active Data Guard)
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE PARALLEL 4 DISCONNECT FROM SESSION;
```

##### 문제 2: 로그 갭 보관
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-10-common-issues-2"></a>

증상:

```
SQL> SELECT * FROM v$archive_gap;
THREAD# LOW_SEQUENCE# HIGH_SEQUENCE#
------- ------------- --------------
      1          1234           1240
```

해결 방법:

```
-- FAL (Fetch Archive Log) will automatically fetch missing logs
-- Verify FAL parameters are set correctly
SQL> SHOW PARAMETER fal_server
SQL> SHOW PARAMETER fal_client

-- Manually register missing archive logs if needed
-- On primary, check if logs still exist
SQL> SELECT name FROM v$archived_log WHERE sequence# BETWEEN 1234 AND 1240;

-- If logs are missing on primary, you may need to rebuild the standby
```

##### 문제 3: 전송 다시 실행 실패
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-10-common-issues-3"></a>

증상:

```
SQL> SELECT dest_id, status, error FROM v$archive_dest WHERE dest_id = 2;
DEST_ID STATUS    ERROR
------- --------- ----------------------------------------
2       ERROR     ORA-16191: Primary log shipping client not logged on standby
```

해결 방법:

```
-- Check network connectivity
-- Verify TNS configuration
-- Check listener status on standby
-- Restart log transport

SQL> ALTER SYSTEM SET log_archive_dest_state_2 = 'DEFER';
SQL> ALTER SYSTEM SET log_archive_dest_state_2 = 'ENABLE';
```

##### 문제 4: 다시 실행을 적용하지 않는 관리형 복구
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-10-common-issues-4"></a>

증상:

```
SQL> SELECT process, status FROM v$managed_standby WHERE process = 'MRP0';
PROCESS   STATUS
--------- ------------
MRP0      WAIT_FOR_LOG
```

해결 방법:

```
# Check if archive logs are arriving
ls -ltr /u01/app/oracle/oradata/ORCL/arch/

# Check alert log for errors
tail -100 $ORACLE_BASE/diag/rdbms/orcl_b/ORCL/trace/alert_ORCL.log

# Restart managed recovery
sqlplus / as sysdba
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
```

**멀티테넌트의 경우** 대기 상태에서 각 PDB의 상태를 확인할 수도 있습니다.

```
SQL> SELECT con_id, name, open_mode, restricted FROM v$pdbs;
```

예상 출력(대기 상태 `MOUNTED`의 PDB):

```
CON_ID     NAME                           OPEN_MODE  RES
---------- ------------------------------ ---------- ---
2          PDB$SEED                       MOUNTED
3          ORCLDB                         MOUNTED
```

**참고**  
물리적 대기 상태에서 PDB는 관리형 복구 중에 `MOUNTED` 상태를 유지합니다.

### 11단계: 전환 실시
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-11"></a>

대기 모드가 완전히 동기화되고 준비된 것으로 확인되면 전환을 수행합니다. 멀티테넌트의 경우 전환은 전체 CDB(모든 PDB)를 RDS Custom 기본에서 EC2 대기로 전환합니다.

RDS Custom 기본 인스턴스에서 Data Guard 브로커에 연결하고 두 데이터베이스 모두 전환할 준비가 되었는지 확인합니다.

**Example 비 CDB의 경우:**  

```
DGMGRL> VALIDATE DATABASE ORCL_A;
DGMGRL> VALIDATE DATABASE ORCL_B;
```

 

**Example 멀티테넌트의 경우:**  

```
DGMGRL> VALIDATE DATABASE RDSCDB_A;
DGMGRL> VALIDATE DATABASE ORCL_B;
```

둘 다 `Ready for Switchover: Yes`를 표시해야 합니다.

RDS Custom 기본에서 EC2 대기로 전환합니다.

```
DGMGRL> SWITCHOVER TO ORCL_B;
```

전환이 성공했는지 확인합니다.

```
DGMGRL> SHOW CONFIGURATION VERBOSE;
```

이제 EC2 인스턴스(`ORCL_B`)가 기본 데이터베이스가 되고 RDS Custom 인스턴스가 물리적 대기 상태입니다.

### 12단계: PDB 열기(멀티테넌트만 해당)
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-12"></a>

전환 후 EC2의 CDB는 READ WRITE 모드에서 열리지만 모든 PDB는 MOUNTED 상태입니다. 수동으로 열어야 합니다.

EC2의 새 프라이머리에 연결합니다.

```
sqlplus / as sysdba
SQL> SELECT name, open_mode, database_role, cdb FROM v$database;
```

예상 결과:

```
NAME      OPEN_MODE            DATABASE_ROLE    CDB
--------- -------------------- ---------------- ---
ORCL      READ WRITE           PRIMARY          YES
```

현재 PDB 상태 확인:

```
SQL> SELECT con_id, name, open_mode, restricted FROM v$pdbs;
```

예상 출력(`MOUNTED` 상태의 PDB - 이름이 `ORCLDB`인 PDB 하나가 있는 예):

```
CON_ID     NAME                           OPEN_MODE  RES
---------- ------------------------------ ---------- ---
2          PDB$SEED                       READ ONLY  NO
3          ORCLDB                         MOUNTED
```

모든 PDB를 엽니다.

```
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;
```

플러그형 데이터베이스가 변경되었습니다.

모든 PDB가 이제 `READ WRITE` 모드에서 열려 있는지 확인:

```
SQL> SELECT con_id, name, open_mode, restricted FROM v$pdbs;
```

예상 결과:

```
CON_ID     NAME                           OPEN_MODE  RES
---------- ------------------------------ ---------- ---
2          PDB$SEED                       READ ONLY  NO
3          ORCLDB                         READ WRITE NO
```

### 13단계: 시작 시 PDB 자동 열기 구성(멀티테넌트만 해당)
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-13"></a>

CDB 시작 시 PDB가 자동으로 열리도록 상태 저장 방식을 구성합니다(Oracle 19c에 권장).

```
SQL> ALTER PLUGGABLE DATABASE ALL SAVE STATE;
Pluggable database altered.
```

저장된 상태를 확인합니다.

```
SQL> SELECT con_name, instance_name, state FROM dba_pdb_saved_states;
```

PDB 서비스가 리스너에 등록되어 있는지 확인합니다.

```
lsnrctl services
```

예상 출력에는 CDB 및 각 PDB에 대한 서비스가 표시되어야 합니다. 서비스가 표시되지 않는 경우:

```
SQL> ALTER SYSTEM REGISTER;
```

그런 다음 `lsnrctl services`로 다시 확인합니다.

### 14단계: RDS Custom 객체 제거
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-14"></a>

이제 EC2의 자체 관리형 데이터베이스이므로 RDS Custom 특정 사용자 및 객체를 제거해야 합니다. 정리 프로세스는 비CDB 아키텍처와 멀티테넌트 아키텍처 간에 약간 다릅니다.

**중요**  
RDS별 사용자 및 테이블스페이스를 삭제하기 전에 다음 스키마 아래에 애플리케이션 객체가 없는지 확인합니다.

```
SQL> SELECT owner, object_type, COUNT(*)
FROM dba_objects
WHERE owner IN ('RDSADMIN', 'RDS_DATAGUARD')
  AND object_name NOT LIKE 'RDS%'
  AND object_name NOT LIKE 'SYS_%'
GROUP BY owner, object_type;
```

애플리케이션 객체가 발견되면 계속하기 전에 적절한 애플리케이션 스키마로 마이그레이션합니다.

**비 CDB 정리:**

```
sqlplus / as sysdba

-- Drop RDS-specific users
SQL> DROP USER RDSADMIN CASCADE;
SQL> DROP USER RDS_DATAGUARD CASCADE;

-- Drop RDS-specific directories
SQL> DROP DIRECTORY OPATCH_INST_DIR;
SQL> DROP DIRECTORY OPATCH_LOG_DIR;
SQL> DROP DIRECTORY OPATCH_SCRIPT_DIR;

-- Drop the RDSADMIN tablespace
SQL> DROP TABLESPACE RDSADMIN INCLUDING CONTENTS AND DATAFILES;

-- Verify removal
SQL> SELECT username FROM dba_users WHERE username LIKE '%RDS%';
```

예상 결과: `no rows selected`

**멀티테넌트 정리:**

멀티테넌트 환경에서 RDS Custom은 모든 PDB에서 볼 수 있는 `CDB$ROOT`에서 공통 사용자를 생성합니다. `CDB$ROOT`에서 정리해야 합니다.

```
sqlplus / as sysdba

-- Verify you are in CDB$ROOT
SQL> SHOW CON_NAME;

-- Check for RDS-specific common users (including C## prefixed users)
SQL> SELECT username, common, con_id FROM cdb_users
WHERE username LIKE 'RDS%' OR username LIKE 'C##RDS%'
ORDER BY username;

-- Drop non-common users
SQL> DROP USER RDSADMIN CASCADE;
SQL> DROP USER RDS_DATAGUARD CASCADE;

-- If any C## common users exist
-- Example (adjust based on your findings):
-- SQL> DROP USER C##RDS_DATAGUARD CASCADE;
-- Drop RDS-specific directories
SQL> DROP DIRECTORY OPATCH_INST_DIR;
SQL> DROP DIRECTORY OPATCH_LOG_DIR;
SQL> DROP DIRECTORY OPATCH_SCRIPT_DIR;

-- Drop the RDSADMIN tablespace
SQL> DROP TABLESPACE RDSADMIN INCLUDING CONTENTS AND DATAFILES;

-- Verify removal from CDB$ROOT
SQL> SELECT username FROM dba_users WHERE username LIKE '%RDS%';

-- Verify removal from each PDB (example with one PDB named ORCLDB)
SQL> ALTER SESSION SET CONTAINER = ORCLDB;
SQL> SELECT username FROM dba_users WHERE username LIKE '%RDS%';
```

모든 쿼리에 대한 예상 출력: 선택된 행 없음

### 15단계: 자동 시작 구성
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-15"></a>

`SPFILE`가 사용 중인지 확인합니다.

```
sqlplus / as sysdba
SQL> SHOW PARAMETER spfile;
```

`spfile` 경로가 올바르면 아무 작업도 필요하지 않습니다. 없는 경우 만들기:

```
SQL> CREATE SPFILE FROM MEMORY;
```

데이터베이스 다시 시작:

```
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;
```

멀티테넌트의 경우 모든 PDB를 엽니다(이전에 상태를 저장한 경우 자동으로 열어야 함).

```
SQL> SELECT con_id, name, open_mode FROM v$pdbs;
```

PDB가 열려 있지 않으면 수동으로 엽니다.

```
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;
```

편집 `/etc/oratab`:

```
vi /etc/oratab
```

`ORCL`의 줄을 `N`에서 `Y`로 변경합니다.

```
ORCL:/u01/app/oracle/product/19.0.0/dbhome_1:Y
```

### 16단계: 최종 검증
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-16"></a>

마이그레이션된 데이터베이스에 대해 포괄적인 검증을 수행합니다.

**Example 비 CDB의 경우:**  

```
sqlplus / as sysdba

-- Verify database role and status
SQL> SELECT name, open_mode, log_mode, database_role FROM v$database;

-- Check database size
SQL> SELECT SUM(bytes)/1024/1024/1024 AS size_gb FROM dba_data_files;

-- Verify all objects are valid
SQL> SELECT owner, object_type, COUNT(*)
     FROM dba_objects
     WHERE status = 'INVALID'
     GROUP BY owner, object_type;

-- Verify data files
SQL> SELECT name, status FROM v$datafile;

-- Test application connectivity
SQL> SELECT username, machine, program FROM v$session WHERE username IS NOT NULL;
```

**Example 멀티테넌트의 경우:**  

```
sqlplus / as sysdba

-- Verify CDB status
SQL> SELECT name, open_mode, log_mode, cdb, database_role FROM v$database;

-- Verify all PDBs are open
SQL> SELECT con_id, name, open_mode, restricted FROM v$pdbs;

-- Check total CDB size
SQL> SELECT SUM(bytes)/1024/1024/1024 AS total_size_gb FROM cdb_data_files;

-- Check size per PDB
SQL> SELECT p.name AS pdb_name,
       ROUND(SUM(d.bytes)/1024/1024/1024, 2) AS size_gb
FROM v$pdbs p
JOIN cdb_data_files d ON p.con_id = d.con_id
GROUP BY p.name,p.con_id
ORDER BY p.con_id;

-- Verify all objects are valid across all PDBs
SQL> SELECT con_id, owner, object_type, COUNT(*)
     FROM cdb_objects
     WHERE status = 'INVALID'
     GROUP BY con_id, owner, object_type;

-- Verify PDB services are registered
SQL> SELECT name FROM v$services ORDER BY name;

Test application connectivity:

# Non-CDB
sqlplus {{<app_user>}}/{{<password>}}@{{<EC2_IP>}}:1521/ORCL

# Multitenant (connect to PDB)
sqlplus {{<app_user>}}/{{<password>}}@{{<EC2_IP}}>:1521/{{<PDB_NAME>}}
```

애플리케이션 연결 테스트:

```
# Non-CDB
sqlplus {{<app_user>}}/{{<password>}}@{{<EC2_IP>}}:1521/ORCL

# Multitenant (connect to PDB)
sqlplus {{<app_user>}}/{{<password>}}@{{<EC2_IP>}}:1521/{{<PDB_NAME>}}
```

### 17단계: 백업 파일 정리
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-17"></a>

검증에 성공한 후 백업 파일을 제거하고 별도의 EBS 볼륨을 사용하는 경우 백업 볼륨을 분리합니다.

```
rm -rf /u01/app/oracle/backup/*
```

백업에 별도의 EBS 볼륨을 사용하는 경우:

```
# Unmount the volume
sudo umount /u01/app/oracle/backup

# Detach and delete the EBS volume from AWS Console or CLI
aws ec2 detach-volume --volume-id {{<volume-id>}}
aws ec2 delete-volume --volume-id {{<volume-id>}}
```

### 18단계: RDS Custom 자동화 다시 시작
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-step-18"></a>

검증 기간 동안 RDS Custom 인스턴스를 폴백으로 계속 실행하려면 자동화를 재개합니다.

```
aws rds modify-db-instance \
  --db-instance-identifier my-custom-instance \
  --automation-mode full \
  --region us-east-1
```

## 일반적인 문제 해결
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting"></a>



이 섹션에서는 RMAN 복제 및 Oracle Data Guard 접근 방식 모두에서 마이그레이션 중에 발생할 수 있는 일반적인 문제를 다루며, 비CDB 및 멀티테넌트 아키텍처를 모두 다룹니다.

### ORA-09925: 감사 추적 파일을 생성할 수 없음
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-ora-09925"></a>

**원인:** `audit_file_dest` 파라미터에 지정된 감사 디렉터리가 대상 EC2 인스턴스에 존재하지 않습니다.

 **해결 방법:** 

감사 디렉터리가 존재하고 적절한 권한이 있는지 확인합니다.

```
mkdir -p /u01/app/oracle/admin/ORCL/adump
chown -R oracle:oinstall /u01/app/oracle/admin/ORCL
chmod -R 755 /u01/app/oracle/admin/ORCL
```

### ORA-01261: 파라미터 `db_create_file_dest` 대상 문자열을 변환할 수 없음
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-ora-01261"></a>

**원인:** `db_create_file_dest` 파라미터에 지정된 디렉터리가 대상 EC2 인스턴스에 존재하지 않습니다.

 **해결 방법:** 

비 CDB의 경우:

```
mkdir -p /u01/app/oracle/oradata/ORCL
chown -R oracle:oinstall /u01/app/oracle/oradata/ORCL
chmod -R 755 /u01/app/oracle/oradata/ORCL
```

멀티테넌트의 경우:

```
mkdir -p /u01/app/oracle/oradata/ORCL/pdb/datafile
chown -R oracle:oinstall /u01/app/oracle/oradata/ORCL
chmod -R 755 /u01/app/oracle/oradata/ORCL
```

### ORA-01804: 시간대 정보 초기화 실패
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-ora-01804"></a>

이 오류는 RDS 소스의 시간대 버전이 EC2 $ORACLE\_HOME에 설치된 것보다 높은 경우 `RDSADMIN` 사용자를 삭제할 때 발생할 수 있습니다.

 **해결 방법:** 

1. 시간대 버전을 확인합니다.

   ```
   SELECT * FROM v$timezone_file;
   SELECT PROPERTY_NAME, PROPERTY_VALUE
   FROM database_properties
   WHERE PROPERTY_NAME LIKE '%DST%';
   ```

1. 해결 방법으로 $ORACLE\_HOME에서 사용할 수 있는 것과 일치하도록 시간대 파일 환경 변수를 설정합니다.

   ```
   ls $ORACLE_HOME/oracore/zoneinfo/timezlrg_*.dat
   export ORA_TZFILE=$ORACLE_HOME/oracore/zoneinfo/timezone_40.dat
   ```

   설치에서 사용할 수 있는 버전과 일치하도록 번호를 조정합니다.

1. 드롭을 다시 시도합니다.

   ```
   sqlplus / as sysdba
   SQL> DROP USER RDSADMIN CASCADE;
   ```

### RU 간 마이그레이션 문제(다른 릴리스 업데이트)
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-cross-ru-migration"></a>

**원인:** 대상 EC2 인스턴스에 소스 RDS Custom 인스턴스와 다른 Oracle 릴리스 업데이트(RU) 또는 일회성 패치가 있어 마이그레이션 도중 또는 이후에 호환성 오류가 발생합니다.

**일반적인 오류:**
+ 다시 실행 적용 중 ORA-00600 내부 오류(Data Guard)
+ ORA-39700 데이터베이스는 `UPGRADE` 옵션으로 열어야 함
+ 마이그레이션 후 사전 불일치
+ `DBA_REGISTRY` 또는 `DBA_OBJECTS`의 잘못된 객체

 **해결 방법:** 

 **모범 사례 - RU 버전과 일회성 패치를 정확히 일치시킵니다.**

1. 소스와 대상 모두에서 정확한 RU 버전을 확인합니다.

   ```
   -- On both source and target
   SQL> SELECT * FROM v$version;
   
   SQL> SELECT patch_id, patch_uid, version, action, status, description
   FROM dba_registry_sqlpatch
   ORDER BY action_time DESC;
   ```

1. $ORACLE\_HOME 패치 수준을 확인합니다.

   ```
   # On both instances
   $ORACLE_HOME/OPatch/opatch lsinventory
   ```

1. 버전이 일치하지 않는 경우 필요에 따라 패치를 적용하거나 롤백하여 마이그레이션하기 전에 정렬합니다.

1. 일치하지 않는 RU를 진행해야 하는 경우 마이그레이션 후 datapatch를 실행합니다.

   ```
   cd $ORACLE_HOME/OPatch
   ./datapatch -verbose
   ```

1. 잘못된 객체가 있는지 확인하고 다시 컴파일합니다.

   ```
   SQL> @?/rdbms/admin/utlrp.sql
   
   SQL> SELECT owner, object_type, COUNT(*)
   FROM dba_objects
   WHERE status = 'INVALID'
   GROUP BY owner, object_type;
   ```

### 네트워크 연결 문제
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-network-connectivity"></a>

 

**원인:** 보안 그룹, 네트워크 ACL 또는 `iptables`가 Oracle 리스너 포트 차단.

 **해결 방법:** 

1. 보안 그룹이 포트를 양방향으로 허용하는지 확인

1. EC2에서 iptable을 확인합니다.

   ```
   sudo iptables -L INPUT -n -v
   ```

1. 필요한 경우 규칙을 추가합니다.

   ```
   # Insert rule before the REJECT rule (typically position 5)
   sudo iptables -I INPUT 5 -p tcp --dport 1521 -j ACCEPT
   
   # For enhanced security, allow only from specific source IPs
   sudo iptables -I INPUT 5 -p tcp -s {{<RDS_Custom_IP>}} --dport 1521 -j ACCEPT
   
   # Save rules permanently
   sudo service iptables save
   ```

1. 연결 테스트:

   ```
   telnet {{<EC2_instance_IP>}} 1521
   tnsping DB_SOURCE
   tnsping DB_TARGET
   ```

### 마이그레이션 후 PDB가 열리지 않음(멀티테넌트만 해당)
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-pdbs-not-opening"></a>

**원인:** 이는 정상적인 동작입니다. RMAN 복제 또는 Data Guard 전환 후 CDB는 열려 있지만 PDB는 `MOUNTED` 상태입니다.

 **해결 방법:** 

수동으로 엽니다.

```
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;
```

특정 PDB가 열리지 않으면 알림 로그에서 오류를 확인합니다.

```
tail -100 $ORACLE_BASE/diag/rdbms/orcl/ORCL/trace/alert_ORCL.log
```

일반적인 원인으로는 데이터 파일 누락 또는 경로 매핑 문제가 있습니다.

### PDB 데이터 파일을 찾을 수 없거나 경로 불일치(멀티테넌트만 해당)
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-pdb-data-files-not-found"></a>

**원인:** 마이그레이션이 모든 소스 경로를 올바르게 매핑하지 못했습니다. 특히 OMF 기반 PDB 데이터 파일의 경우 더욱 그렇습니다.

 **해결 방법:** 

1. 누락된 데이터 파일을 확인합니다.

   ```
   SQL> SELECT name, status FROM v$datafile WHERE status != 'ONLINE';
   ```

1. 파일이 잘못된 디렉터리에 배치된 경우 제어 파일에서 파일 이름을 바꿉니다.

   ```
   SQL> ALTER DATABASE RENAME FILE '/wrong/path/datafile.dbf' TO '/correct/path/datafile.dbf';
   ```

1. 이를 방지하려면 파라미터 파일을 구성하기 전에 항상 `SELECT con_id, name FROM v$datafile ORDER BY con_id;`를 사용하여 소스 데이터 파일 경로를 확인합니다.

### 리스너에 등록하지 않는 PDB 서비스(멀티테넌트만 해당)
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-pdb-services-not-registering"></a>

**원인**: PDB를 연 후 리스너가 PDB 서비스를 인식하지 못합니다.

 **해결 방법:** 

1. 강제 서비스 등록:

   ```
   SQL> ALTER SYSTEM REGISTER;
   ```

1. 서비스가 여전히 표시되지 않으면 `local_listener` 파라미터를 확인합니다.

   ```
   SQL> SHOW PARAMETER local_listener;
   ```

   올바른 리스너 주소를 가리키는지 확인합니다. 필요한 경우 업데이트합니다.

   ```
   SQL> ALTER SYSTEM SET local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST={{<EC2_instance_IP>}})(PORT=1521))';
   SQL> ALTER SYSTEM REGISTER;
   ```

1. 다음을 사용하여 확인합니다.

   ```
   lsnrctl services
   ```

### PDB 자동으로 열리지 않음(멀티테넌트만 해당)
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-pdbs-not-opening-after-cdb-restart"></a>

**원인:** PDB 저장 상태가 구성되지 않았습니다.

 **해결 방법:** 

PDB 저장 상태가 구성되었는지 확인합니다.

```
SQL> SELECT con_name, instance_name, state FROM dba_pdb_saved_states;
```

반환되는 행이 없으면 상태를 저장합니다.

```
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;
SQL> ALTER PLUGGABLE DATABASE ALL SAVE STATE;
```

### Data Guard 다시 실행 전송이 작동하지 않음
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-odg-redo-transport-failure"></a>

**원인:** 네트워크 연결 문제, 잘못된 TNS 구성 또는 FAL 파라미터가 설정되지 않았습니다.

 **해결 방법:** 

1. 대기 모드가 마운트 모드인지 확인합니다.

   ```
   SQL> SELECT status FROM v$instance;
   ```

1. 대기 상태에서 fal\_server 및 fal\_client가 올바르게 설정되었는지 확인합니다.

   ```
   SQL> SHOW PARAMETER fal_server
   SQL> SHOW PARAMETER fal_client
   ```

1. 네트워크 연결 확인:

   ```
   tnsping ORCL_A # or RDSCDB_A for multitenant
   ```

1. 대기를 가리키는 기본 지점의 log\_archive\_dest\_2 파라미터를 확인합니다(브로커 없이 수동으로 구성된 경우).

 **여러 PDB에 따른 Data Guard 적용 지연 증가(멀티테넌트만 해당)** 

**원인:** 여러 PDB가 있는 CDB의 경우 모든 컨테이너의 변경 볼륨으로 인해 다시 실행 적용 속도가 느려질 수 있습니다.

 **해결 방법:** 

1. 적용률을 확인합니다.

   ```
   SQL> SELECT name, value, unit FROM v$dataguard_stats WHERE name IN ('apply rate', 'apply lag');
   ```

1. 다시 실행 적용을 위해 병렬 처리를 늘리는 것이 좋습니다(Active Data Guard 라이선스 필요).

   ```
   SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
   SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE PARALLEL 4 DISCONNECT FROM SESSION;
   ```

1. 대기 인스턴스에 리소스 제약 조건(CPU, I/O)이 없는지 확인합니다.

 **ORA-19625에서 RMAN 아카이브 로그 백업 실패** 

**원인:** RDS Custom 자동화가 디스크에서 이전 아카이브 로그를 제거했지만 RMAN의 제어 파일에는 여전히 레코드가 있습니다.

 **해결 방법:** 

1. 오래된 아카이브 로그 항목을 교차 확인하고 정리합니다.

   ```
   RMAN> CROSSCHECK ARCHIVELOG ALL;
   RMAN> DELETE NOPROMPT EXPIRED ARCHIVELOG ALL;
   ```

1. 아카이브 로그 백업만 다시 실행합니다.

   ```
   RMAN> RUN {
   SQL 'ALTER SYSTEM ARCHIVE LOG CURRENT';
   BACKUP AS COMPRESSED BACKUPSET
   FILESPERSET 50
   FORMAT '/rdsdbdata/backup/arch_%U'
   ARCHIVELOG ALL;
   }
   ```

### 멀티테넌트에서 일반적인 사용자 삭제 실패(멀티테넌트만 해당)
<a name="RDS-Custom-for-Oracle-end-of-support-troubleshoting-multitenant-user-drop-fails"></a>

 

**원인:** 일반 사용자(C\#\# 접두사)는 `CONTAINER=ALL` 절과 함께 삭제해야 합니다.

 **해결 방법:** 

```
-- For common users
SQL> DROP USER C##RDS_DATAGUARD CASCADE CONTAINER=ALL;

-- For non-common users in CDB$ROOT
SQL> DROP USER RDSADMIN CASCADE;
```

`CDB$ROOT`에 연결되어 있는지 확인합니다.

```
SQL> SHOW CON_NAME;
```

## 마이그레이션 작업
<a name="RDS-Custom-for-Oracle-end-of-support-post-migration"></a>

마이그레이션에 성공한 후 이러한 추가 작업을 완료하여 EC2의 자체 관리형 Oracle 데이터베이스가 프로덕션 준비가 되었는지 확인합니다.

 **애플리케이션 연결 문자열 업데이트** 

**비 CDB의 경우:**
+ 애플리케이션이 새 EC2 인스턴스 엔드포인트를 가리키도록 설정
+ EC2 인스턴스 IP 또는 호스트 이름을 사용하도록 연결 문자열 업데이트
+ 모든 애플리케이션 기능을 철저하게 테스트

**멀티테넌트의 경우:**
+ 애플리케이션이 새 EC2 인스턴스 PDB 서비스 이름(예: ORCLDB 또는 특정 PDB 이름)을 가리키도록 합니다.
+ 애플리케이션이 CDB가 아닌 올바른 PDB에 연결되는지 확인
+ PDB 서비스 이름을 사용하도록 연결 문자열 업데이트
+ 각 PDB에 대한 모든 애플리케이션 기능 테스트

예제 연결 문자열:

```
# Non-CDB
jdbc:oracle:thin:@{{<EC2_IP>}}:1521/ORCL

# Multitenant (connect to PDB)
jdbc:oracle:thin:@{{<EC2_IP>}}:1521/ORCLDB
```

 **백업 전략 구성** 

자체 관리형 데이터베이스에 대한 포괄적인 백업 전략을 설정합니다.

**RMAN 백업:**
+ 전체, 증분 및 아카이브 로그 백업을 위한 자동 RMAN 백업 스크립트 구성
+ 목표 복구 시점(RPO)을 기반으로 백업 보존 정책 설정
+ 내구성과 비용 효율성을 위해 Amazon S3에 백업 저장
+ 백업 복원 절차를 정기적으로 테스트

**AWS Backup:**
+ EBS 볼륨 스냅샷에 [AWS Backup](https://aws.amazon.com/backup/) 사용
+ 백업 일정 및 보존 정책 구성
+ 재해 복구를 위해 리전 간 백업 복사본 활성화

**멀티테넌트의 경우:**
+ RMAN을 이용한 CDB 백업에는 모든 PDB가 자동으로 포함됩니다.
+ 필요한 경우 개별 PDB를 백업할 수도 있습니다.
+ 비즈니스 요구 사항에 따라 PDB별 백업 일정 고려

RMAN 백업 스크립트 예제:

```
#!/bin/bash
export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
export ORACLE_SID=ORCL
export PATH=$ORACLE_HOME/bin:$PATH
rman target / << EOF
run {
  backup as compressed backupset database plus archivelog;
  delete noprompt obsolete;
}
exit;
EOF
```

 **모니터링 설정** 

EC2 호스팅된 Oracle 데이터베이스에 대한 포괄적인 모니터링을 구현합니다.

**Amazon CloudWatch**
+ EC2 인스턴스 상태, 디스크 사용량 및 사용자 지정 Oracle 지표에 대한 CloudWatch 지표 설정
+ 중요 임계값에 대한 CloudWatch 경보 생성
+ 데이터베이스 알림 로그 모니터링에 CloudWatch Logs 사용

**Oracle Enterprise Manager(OEM):**
+ 사용 가능한 경우 데이터베이스 모니터링을 위해 OEM 구성
+ 성능 모니터링 및 진단 설정
+ 중요한 이벤트에 대한 자동 알림 구성

**타사 도구:**
+ 데이터베이스 모니터링을 위해 Datadog, New Relic 또는 Prometheus와 같은 도구 고려
+ 기존 모니터링 인프라와 통합

**모니터링할 주요 지표:**
+ 테이블스페이스 사용량
+ 아카이브 로그 공간
+ 유효하지 않은 객체
+ 세션 수
+ 대기 이벤트
+ CPU 및 메모리 사용률
+ I/O 성능

**멀티테넌트의 경우:**
+ CDB 수준 및 PDB 수준 지표 모두 모니터링
+ PDB 리소스 사용량 및 할당량에 대한 알림 설정
+ PDB별 성능 지표 추적

 **보안 그룹 및 네트워크 ACL 구성** 

EC2 인스턴스의 보안을 검토하고 강화합니다.

**보안 그룹**
+ 데이터베이스 포트 액세스를 승인된 애플리케이션 서버 및 배스천 호스트로만 제한
+ 마이그레이션 중에 생성된 지나치게 허용적인 규칙 제거
+ 보안 그룹 규칙 및 그 목적 문서화

**네트워크 ACL:**
+ 추가 보안 계층을 위한 VPC 네트워크 ACL 구성
+ 심층 방어 보안 전략 구현

**SSH 액세스:**
+ SSH 액세스를 특정 IP 범위로 제한하거나 AWS Systems Manager Session Manager 사용
+ 암호 인증 비활성화 및 키 기반 인증만 사용
+ 권한 있는 액세스를 위한 다중 인증(MFA) 구현

**암호화:**
+ EBS 볼륨에 대해 저장 데이터 암호화 활성화
+ Oracle 네이티브 네트워크 암호화 또는 TLS를 사용하여 데이터베이스 연결에 대해 전송 중 암호화 활성화
+ 암호화 키를 정기적으로 교체

**고가용성 구현**

워크로드에 고가용성이 필요한 경우 다음을 구현하는 것이 좋습니다.

**Oracle Data Guard:**
+ 재해 복구를 위해 다른 EC2 인스턴스에서 새 대기 데이터베이스 구성
+ 멀티테넌트 환경에서 Data Guard는 모든 PDB를 포함한 전체 CDB를 보호합니다.
+ 대기 모드는 다른 가용 영역 또는 리전에 있을 수 있습니다.
+ 스크립트 또는 타사 도구를 사용하여 자동화된 장애 조치 메커니즘 구현

**AWS 다중 AZ 배포:**
+ 다른 가용 영역에 대기 인스턴스 배포
+ DNS 장애 조치에 Amazon Route 53 사용
+ 장애 조치 지원을 통해 애플리케이션 수준 연결 풀링 구현

**백업 및 복구:**
+ 테스트된 복원 절차로 정기적인 백업 유지
+ 문서 목표 복구 시간(RTO) 및 목표 복구 시점(RPO)
+ 정기적인 재해 복구 훈련 수행

**철저한 애플리케이션 테스트 수행**

RDS Custom 인스턴스를 폐기하기 전에:

**기능 테스트:**
+ 모든 애플리케이션 기능이 올바르게 작동하는지 확인
+ 모든 데이터베이스 종속 기능 테스트
+ 데이터 무결성 및 일관성 검증

**성능 테스트:**
+ 성능 지표를 RDS Custom 기준과 비교
+ 성능 회귀 식별 및 해결
+ 필요에 따라 쿼리 및 인덱스 최적화

**로드 테스트:**
+ 예상 피크 로드에서 데이터베이스 테스트
+ 리소스 사용률이 허용 한도 내에 있는지 확인
+ 병목 현상 식별 및 해결

**장애 조치 테스트(HA가 구성된 경우):**
+ 장애 조치 시나리오 테스트
+ 애플리케이션 재연결 로직 확인
+ 실제 RTO 및 RPO 측정

**백업 및 복원 테스트:**
+ 백업 및 복원 절차가 올바르게 작동하는지 확인
+ 시점 복구 테스트
+ 백업 무결성 검증

**멀티테넌트의 경우:**
+ 각 PDB를 독립적으로 테스트
+ PDB 격리 및 리소스 할당 확인
+ PDB 관련 작업 테스트(복제, 분리/플러그 등)

**RDS Custom 인스턴스 폐기**

검증 기간이 성공한 후(일반적으로 1\~2주):

1. **최종 백업**: 보관 목적으로 RDS Custom 인스턴스의 최종 백업 가져오기

   ```
   # Create final snapshot
   aws rds create-db-snapshot \
     --db-instance-identifier my-custom-instance \
     --db-snapshot-identifier my-custom-instance-final-snapshot \
     --region us-east-1
   ```

1. **마이그레이션 문서화**: 새 EC2 구성으로 런북 및 설명서 업데이트

1. **RDS Custom 인스턴스 삭제**: AWS Console 또는 CLI를 사용하여 인스턴스 삭제

   ```
   # Delete RDS Custom instance without final snapshot (if already created above)
   aws rds delete-db-instance \
     --db-instance-identifier my-custom-instance \
     --skip-final-snapshot \
     --region us-east-1
   
   # Or create a final snapshot before deletion
   aws rds delete-db-instance \
     --db-instance-identifier my-custom-instance \
     --final-db-snapshot-identifier my-custom-instance-final-snapshot \
     --region us-east-1
   ```

1. **리소스 정리**: 더 이상 필요하지 않은 경우 연결된 스냅샷, 파라미터 그룹 및 옵션 그룹 제거

1. **설명서 업데이트**: 모든 운영 설명서가 새로운 EC2 기반 아키텍처를 반영하는지 확인

## 비교: RMAN Active Duplication과 Oracle Data Guard 비교
<a name="RDS-Custom-for-Oracle-end-of-support-RMAN-vs-ODG"></a>

다음 표는 두 가지 마이그레이션 옵션 간의 주요 차이점을 요약한 것입니다.


|  **속성**  |  **RMAN 활성 복제**  |  **Oracle Data Guard**  | 
| --- | --- | --- | 
| **소스 데이터베이스 가용성** | 전체 복제 중 온라인 | 전체 프로세스 중 온라인 | 
| **다운타임** | 몇 분(최종 컷오버만 해당) | 몇 초에서 몇 분(전환) | 
| **복잡성** | 낮음 | 높음 | 
| **마이그레이션 기간** | 단일 중복 작업 | 초기 설정 \+ 지속적 동기화 | 
| **연속 동기화** | 아니요 | 예 | 
| **폴백 기능** | 수동(소스 실행 유지) | 내장(자동) | 
| **컷오버 전 테스트** | 제한적(중복 후 테스트) | 전체 테스트 가능(대기 테스트 가능) | 
| **네트워크 대역폭** | 중복 중 높음 | 보통(연속) | 
| **소스 데이터베이스 영향** | 최소(읽기 작업) | 최소(재실행 전송) | 
| **최적의 용도** | 대부분의 마이그레이션, 간단한 컷오버 | 미션 크리티컬, 가동 중지 시간이 거의 없음 | 
| **비CDB 지원** | 예 | 예 | 
| **멀티테넌트 지원** | 예(전체 CDB) | 예(전체 CDB) | 
| **마이그레이션 후 PDB 상태** | CDB 열림, PDB MOUNTED | CDB 열림, PDB MOUNTED | 
| **RMAN 필요** | 예 | 예(백업 기반 접근 방식의 초기 백업용) | 
| **Data Guard 필요** | 아니요 | 예 | 
| **필요한 스킬 수준** | 중급 | Advanced | 
| **컷오버 프로세스** | EC2로 애플리케이션 리디렉션 | 전환 명령 \+ 애플리케이션 리디렉션 | 

## 비교: 비CDB 마이그레이션과 멀티테넌트 마이그레이션 비교
<a name="RDS-Custom-for-Oracle-end-of-support-non-cdb-va-multitenant"></a>

 

다음 표에는 비CDB 데이터베이스와 멀티테넌트 데이터베이스 마이그레이션의 주요 차이점이 요약되어 있습니다.


|  **속성**  |  **비 CDB 마이그레이션**  |  **멀티테넌트(PDB가 있는 CDB) 마이그레이션**  | 
| --- | --- | --- | 
| **데이터베이스 유형** | 단일 인스턴스 비CDB(예: ORCL) | CDB$ROOT \+ PDB$SEED \+ 하나 이상의 PDB가 있는 CDB(소스: RDSCDB, 대상: ORCL) | 
| **마이그레이션 범위** | 단일 데이터베이스 | 전체 CDB(모든 PDB가 자동으로 포함됨) | 
| **RMAN 복제 범위** | 단일 데이터베이스 복제 | 전체 CDB 복제(모든 컨테이너) | 
| **Data Guard 범위** | 단일 데이터베이스 보호 | 전체 CDB 보호(모든 PDB가 자동으로 포함됨) | 
| **파라미터 파일** | 표준 init 파라미터 | enable\_pluggable\_database=TRUE를 포함해야 함 | 
| **마이그레이션 후 데이터베이스 상태** | READ WRITE 모드에서 데이터베이스가 열림 | CDB가 READ WRITE 모드에서 열리고 PDB는 MOUNTED 상태로 유지됨 | 
| **PDB 열기** | 해당 사항 없음 | ALTER PLUGGABLE DATABASE ALL OPEN을 사용하여 모든 PDB를 수동으로 열어야 합니다. | 
| **시작 시 PDB 자동 열기** | 해당 사항 없음 | PDB 저장 상태 또는 시작 트리거를 구성해야 합니다. | 
| **검증**: | 단일 데이터베이스 검사 | CDB와 각 PDB를 개별적으로 검증해야 합니다. | 
| **RDS별 정리** | 단일 데이터베이스에서 사용자/객체 삭제 | CDB$ROOT(캐스케이드에서 PDB로)에서 일반 사용자 삭제, C\#\# 사용자 처리 | 
| **TNS/리스너 구성** | 데이터베이스에 대한 단일 서비스 | CDB 서비스 \+ 동적으로 등록된 개별 PDB 서비스 | 
| **애플리케이션 연결 문자열** | 단일 데이터베이스에 연결 | 개별 PDB 서비스에 연결(CDB 아님) | 
| **백업 전략** | 단일 데이터베이스 백업 | 전체 CDB(모든 PDB 포함) 또는 개별 PDB 백업 | 
| **리소스 관리** | 데이터베이스 수준 리소스 관리 | Resource Manager를 사용한 CDB 수준 및 PDB 수준 리소스 관리 | 
| **복잡성** | 복잡성 감소 | 여러 컨테이너 및 OMF 경로로 인한 복잡성 증가 | 

## 모범 사례 및 권장 사항
<a name="RDS-Custom-for-Oracle-end-of-support-best-practices"></a>

이 섹션에서는 RDS Custom for Oracle에서 EC2로 성공적으로 마이그레이션하기 위한 포괄적인 모범 사례를 제공합니다.

### 마이그레이션 전 계획 수립
<a name="RDS-Custom-for-Oracle-end-of-support-best-practices-pre-migration"></a>

1. 철저한 평가를 수행합니다.

   마이그레이션을 시작하기 전에 환경에 대한 포괄적인 평가를 수행합니다.
   + **데이터베이스 인벤토리**: 모든 데이터베이스, 크기, 아키텍처(비CDB 대 멀티테넌트) 및 종속성 문서화
   + **애플리케이션 종속성**: 데이터베이스에 연결하는 모든 애플리케이션과 해당 연결 방법 식별
   + **성능 기준**: 마이그레이션 후 비교를 위한 성능 지표(CPU, 메모리, I/O, 네트워크) 캡처
   + **백업 및 복구 요구 사항**: RPO(복구 시점 목표) 및 RTO(복구 시간 목표) 문서화
   + **규정 준수 요구 사항**: 마이그레이션에 영향을 미칠 수 있는 규제 또는 규정 준수 요구 사항 식별

1. 적절한 EC2 인스턴스 유형 선택:

   워크로드 특성에 따라 EC2 인스턴스 유형을 선택합니다.    
[See the AWS documentation website for more details](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/RDS-Custom-for-Oracle-end-of-support.html)

    **인스턴스 크기 조정 지침:** 
   + RDS Custom 인스턴스와 동일한 인스턴스 클래스로 시작
   + 테스트 마이그레이션 중 리소스 사용률 모니터링
   + 권장 사항에 AWS Compute Optimizer 사용 고려
   + 성장 및 최대 부하를 위한 20\~30%의 헤드룸 계획

1. 스토리지 아키텍처 설계:

   **EBS 볼륨 유형:**    
[See the AWS documentation website for more details](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/RDS-Custom-for-Oracle-end-of-support.html)

   **스토리지 레이아웃 권장 사항:**

   ```
   # Recommended layout for production databases
         /u01/app/oracle          # Oracle software (50-100 GB, gp3)
         /u01/app/oracle/oradata  # Data files (sized for database, gp3 or io2)
         /u01/app/oracle/arch     # Archive logs (separate volume, gp3)
         /u01/app/oracle/backup   # Backups (separate volume, gp3, can be detached post-migration)
   ```

    **별도 볼륨의 이점:** 
   + 독립 IOPS 할당
   + 더 쉬운 용량 관리
   + 간소화된 백업 및 스냅샷 전략
   + 성능 격리 개선

1.  롤백 계획 수립:

   항상 롤백 전략 수립:
   + 검증 기간 동안 **RDS Custom 인스턴스 실행 유지**(1\~2주 권장)
   + 소스 및 대상 모두에 대한 **정기적인 백업 유지**
   + 연결 문자열 변경을 포함한 **문서 롤백 절차**
   + 비프로덕션 환경에서 **롤백 프로세스 테스트**
   + **롤백 기준 정의**(성능 저하, 데이터 불일치, 애플리케이션 오류)

### 마이그레이션 실행 모범 사례
<a name="RDS-Custom-for-Oracle-end-of-support-migration-best-practices"></a>

1. **마이그레이션 타이밍:**

   최적의 기간을 선택합니다.
   + **트래픽이 적은 기간**: 주말, 공휴일 또는 사용량이 적은 시간
   + **유지 관리 기간**: 가능하면 예약된 유지 관리에 맞게 조정
   + **월말/분기말은 피함**: 이러한 기간은 일반적으로 트랜잭션 볼륨이 많음
   + **시간대 고려**: 글로벌 애플리케이션의 경우 리전 간 영향을 최소화하는 시간을 선택

1. **통신 계획:**

   명확한 통신 설정:
   + **이해관계자 알림**: 모든 이해관계자에게 최소 2주 전에 알림
   + **애플리케이션 팀**: 연결 문자열 업데이트를 위해 애플리케이션 팀과 조정
   + **상태 업데이트**: 마이그레이션 중에 정기적인 업데이트 제공
   + **에스컬레이션 경로**: 문제에 대한 명확한 에스컬레이션 절차 정의
   + **마이그레이션 후 커뮤니케이션**: 성공적인 완료 및 후속 조치 확인

1. **검증 체크포인트:**

   각 단계에서 검증을 구현합니다.

    **마이그레이션 전 검증:** 

   ```
   -- Capture object counts
   SQL> SELECT object_type, COUNT(*) FROM dba_objects GROUP BY object_type ORDER BY object_type;
   
   -- Capture tablespace usage
   SQL> SELECT tablespace_name, ROUND(SUM(bytes)/1024/1024/1024, 2) AS size_gb
   FROM dba_data_files GROUP BY tablespace_name;
   
   -- Capture user counts
   SQL> SELECT COUNT(*) FROM dba_users;
   
   -- For multitenant, capture PDB information
   SQL> SELECT con_id, name, open_mode FROM v$pdbs;
   ```

    **마이그레이션 후 검증:** 

   ```
   -- Verify object counts match
   SQL> SELECT object_type, COUNT(*) FROM dba_objects GROUP BY object_type ORDER BY object_type;
   
   -- Verify no invalid objects
   SQL> SELECT owner, object_type, object_name FROM dba_objects WHERE status = 'INVALID';
   
   -- Verify tablespace usage
   SQL> SELECT tablespace_name, ROUND(SUM(bytes)/1024/1024/1024, 2) AS size_gb
   FROM dba_data_files GROUP BY tablespace_name;
   
   -- Verify database size matches
   SQL> SELECT SUM(bytes)/1024/1024/1024 AS total_size_gb FROM dba_data_files;
   
   -- For multitenant, verify all PDBs are open
   SQL> SELECT con_id, name, open_mode FROM v$pdbs;
   ```

1. **성능 검증:**

   마이그레이션 전후의 성능 지표를 비교합니다.

   ```
   -- Capture AWR snapshots before migration (on RDS Custom)
   SQL> EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT;
   
   -- After migration (on EC2), compare metrics
   SQL> SELECT snap_id, begin_interval_time, end_interval_time
   FROM dba_hist_snapshot
   ORDER BY snap_id DESC
   FETCH FIRST 10 ROWS ONLY;
   
   -- Generate AWR report for comparison
   SQL> @?/rdbms/admin/awrrpt.sql
   ```

   비교할 주요 지표:
   + 평균 활성 세션
   + 트랜잭션당 DB 시간
   + 초당 물리적 읽기 수
   + 초당 논리적 읽기 수
   + 초당 다시 실행 크기
   + 초당 사용자 직접 호출
   + 실행당 구문 분석 시간

### 마이그레이션 후 최적화
<a name="RDS-Custom-for-Oracle-end-of-support-best-practices-post-migration-optimization"></a>

1. 마이그레이션 후 데이터베이스 성능을 최적화합니다.

   1. **데이터베이스 성능 튜닝:**

       **통계 수집:** 

      ```
      -- Gather dictionary statistics
      SQL> EXEC DBMS_STATS.GATHER_DICTIONARY_STATS;
      
      -- Gather fixed object statistics
      SQL> EXEC DBMS_STATS.GATHER_FIXED_OBJECTS_STATS;
      
      -- Gather schema statistics
      SQL> EXEC DBMS_STATS.GATHER_SCHEMA_STATS('SCHEMA_NAME', cascade=>TRUE);
      
      -- For multitenant, gather statistics for each PDB
      SQL> ALTER SESSION SET CONTAINER = PDB_NAME;
      SQL> EXEC DBMS_STATS.GATHER_DATABASE_STATS(cascade=>TRUE);
      ```

      **메모리 파라미터 최적화:**

      ```
      -- Enable Automatic Memory Management (if not already enabled)
      SQL> ALTER SYSTEM SET MEMORY_TARGET = 24G SCOPE=SPFILE;
      SQL> ALTER SYSTEM SET MEMORY_MAX_TARGET = 28G SCOPE=SPFILE;
      SQL> SHUTDOWN IMMEDIATE;
      SQL> STARTUP;
      
      -- Or use Automatic Shared Memory Management
      SQL> ALTER SYSTEM SET SGA_TARGET = 16G SCOPE=SPFILE;
      SQL> ALTER SYSTEM SET PGA_AGGREGATE_TARGET = 8G SCOPE=SPFILE;
      ```

      **결과 캐시 구성:**

      ```
      -- Enable result cache for frequently accessed queries
      SQL> ALTER SYSTEM SET RESULT_CACHE_MAX_SIZE = 1G;
      SQL> ALTER SYSTEM SET RESULT_CACHE_MODE = MANUAL;
      ```

   1. 스토리지 최적화:

      **압축 활성화:**

      ```
      -- For tables with infrequent updates
      ALTER TABLE large_table MOVE COMPRESS FOR OLTP;
      
      -- For archive/historical data
      ALTER TABLE archive_table MOVE COMPRESS FOR ARCHIVE HIGH;
      
      -- Rebuild indexes after compression
      ALTER INDEX index_name REBUILD ONLINE;
      ```

      **파티셔닝 구현:**

      ```
      -- For large tables, consider partitioning
      -- Example: Range partitioning by date
      CREATE TABLE sales_partitioned (
          sale_id NUMBER,
          sale_date DATE,
          amount NUMBER
      )
      PARTITION BY RANGE (sale_date) (
          PARTITION sales_2024 VALUES LESS THAN (TO_DATE('2025-01-01', 'YYYY-MM-DD')),
          PARTITION sales_2025 VALUES LESS THAN (TO_DATE('2026-01-01', 'YYYY-MM-DD')),
          PARTITION sales_2026 VALUES LESS THAN (MAXVALUE)
      );
      ```

   1. 모니터링 및 알림 구현:

      **CloudWatch 사용자 지정 지표:**

      스크립트를 생성하여 CloudWatch에 Oracle 지표를 게시합니다.

      ```
      #!/bin/bash
      # publish_oracle_metrics.sh
      
      INSTANCE_ID=$(ec2-metadata --instance-id | cut -d " " -f 2)
      REGION=$(ec2-metadata --availability-zone | cut -d " " -f 2 | sed 's/[a-z]$//')
      
      # Get tablespace usage
      TABLESPACE_USAGE=$(sqlplus -s / as sysdba << EOF
      SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
      SELECT ROUND(MAX(percent_used), 2)
      FROM (
           SELECT tablespace_name,
                  ROUND((used_space/tablespace_size)*100, 2) AS percent_used
           FROM dba_tablespace_usage_metrics
      );
      EXIT;
      EOF
      )
      
      # Publish to CloudWatch
      aws cloudwatch put-metric-data \
        --region $REGION \
        --namespace "Oracle/Database" \
        --metric-name "TablespaceUsage" \
        --value $TABLESPACE_USAGE \
        --unit Percent \
        --dimensions InstanceId=$INSTANCE_ID,Database=ORCL
      # Add more metrics as needed (sessions, wait events, etc.)
      ```

      **CloudWatch 경보를 설정합니다.**

      ```
      # Create alarm for high tablespace usage
      aws cloudwatch put-metric-alarm \
        --alarm-name oracle-high-tablespace-usage \
        --alarm-description "Alert when tablespace usage exceeds 85%" \
        --metric-name TablespaceUsage \
        --namespace Oracle/Database \
        --statistic Maximum \
        --period 300 \
        --evaluation-periods 2 \
        --threshold 85 \
        --comparison-operator GreaterThanThreshold \
        --alarm-actions arn:aws:sns:region:account-id:topic-name
      ```

   1. 보안 하드닝:

      **데이터베이스 보안:**

      ```
      -- Enforce password complexity
      ALTER PROFILE DEFAULT LIMIT
          PASSWORD_LIFE_TIME 90
          PASSWORD_GRACE_TIME 7
          PASSWORD_REUSE_TIME 365
          PASSWORD_REUSE_MAX 5
          FAILED_LOGIN_ATTEMPTS 5
          PASSWORD_LOCK_TIME 1;
      
      -- Enable audit
      ALTER SYSTEM SET AUDIT_TRAIL = DB, EXTENDED SCOPE=SPFILE;
      SHUTDOWN IMMEDIATE;
      STARTUP;
      
      -- Audit critical operations
      AUDIT ALL ON SYS.AUD$ BY ACCESS;
      AUDIT CREATE USER BY ACCESS;
      AUDIT DROP USER BY ACCESS;
      AUDIT ALTER USER BY ACCESS;
      AUDIT CREATE SESSION BY ACCESS WHENEVER NOT SUCCESSFUL;
      ```

      **네트워크 보안:**

      ```
      # Restrict SSH access
      sudo vi /etc/ssh/sshd_config
      # Set: PermitRootLogin no
      # Set: PasswordAuthentication no
      
      # Configure firewall
      sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" port port="1521" protocol="tcp" accept'
      sudo firewall-cmd --reload
      
      # Enable Oracle Native Network Encryption
      # Edit sqlnet.ora
      SQLNET.ENCRYPTION_SERVER = REQUIRED
      SQLNET.ENCRYPTION_TYPES_SERVER = (AES256, AES192, AES128)
      SQLNET.CRYPTO_CHECKSUM_SERVER = REQUIRED
      SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (SHA256, SHA384, SHA512)
      ```

1. 백업 및 복구 전략:

   **포괄적인 백업 전략을 구현합니다.**

   ```
   #!/bin/bash
   # rman_backup.sh - Daily incremental backup script
   
   export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
   export ORACLE_SID=ORCL
   export PATH=$ORACLE_HOME/bin:$PATH
   
   # Backup to local disk
   rman target / << EOF
   RUN {
       ALLOCATE CHANNEL ch1 DEVICE TYPE DISK FORMAT '/u01/app/oracle/backup/inc_%U';
       BACKUP INCREMENTAL LEVEL 1 DATABASE PLUS ARCHIVELOG;
       DELETE NOPROMPT OBSOLETE;
       CROSSCHECK BACKUP;
       DELETE NOPROMPT EXPIRED BACKUP;
   }
   EXIT;
   EOF
   
   # Copy backups to S3
   aws s3 sync /u01/app/oracle/backup/ s3://my-oracle-backups/$(date +%Y%m%d)/ \
       --storage-class STANDARD_IA \
       --exclude "*" \
       --include "inc_*" \
       --include "arch_*"
   
   # Clean up local backups older than 7 days
   find /u01/app/oracle/backup/ -name "inc_*" -mtime +7 -delete
   find /u01/app/oracle/backup/ -name "arch_*" -mtime +7 -delete
   ```

   **cron을 사용하여 백업 예약:**

   ```
   # Edit crontab
   crontab -e
   
   # Add backup schedule
   # Full backup on Sunday at 2 AM
   0 2 * * 0 /home/oracle/scripts/rman_full_backup.sh >> /home/oracle/logs/backup_full.log 2>&1
   
   # Incremental backup Monday-Saturday at 2 AM
   0 2 * * 1-6 /home/oracle/scripts/rman_incremental_backup.sh >> /home/oracle/logs/backup_inc.log 2>&1
   
   # Archive log backup every 4 hours
   0 */4 * * * /home/oracle/scripts/rman_archivelog_backup.sh >> /home/oracle/logs/backup_arch.log 2>&1
   ```

### 비용 최적화
<a name="RDS-Custom-for-Oracle-end-of-support-cost-optimization"></a>

 **1. 적정 규모 조정:** 

마이그레이션 후 비용을 모니터링하고 최적화합니다.
+ **AWS Cost Explorer를 사용**하여 EC2 및 EBS 비용 분석
+ 인스턴스 유형 추천을 위해 **AWS Compute Optimizer 활성화**
+ **CloudWatch 지표를 검토**하여 활용도가 낮은 리소스 식별
+ 예측 가능한 워크로드를 위해 **예약 인스턴스 또는 절감형 플랜 고려**

 **2. 스토리지 최적화:** 
+ S3 백업에 대한 **수명 주기 정책 구현**(30일 후 Glacier로 이동)
+ **사용하지 않는 EBS 스냅샷을 정기적으로 삭제**
+ 동일한 성능으로 비용을 절감하려면 **gp2 대신 gp3를 사용**
+ 마이그레이션 완료 후 **백업 볼륨 분리 및 삭제**

 **3. 자동화** 
+ 업무 시간 동안 비프로덕션 데이터베이스의 **시작/중지 자동화**
+ 패치 관리에 **AWS Systems Manager 사용**
+ Data Guard를 사용하는 경우 읽기 복제본에 대한 **Auto Scaling 구현**

## 결론
<a name="RDS-Custom-for-Oracle-end-of-support-conclusion"></a>

이 규범적 지침은 Oracle 데이터베이스를 Amazon RDS Custom for Oracle에서 Amazon EC2의 자체 관리형 Oracle 데이터베이스로 이동하기 위한 자세한 마이그레이션 전략을 제공했습니다. 2027년 3월 31일부터 적용되는 RDS Custom for Oracle 서비스 사용 중단으로 마이그레이션을 미리 계획하고 실행하는 것이 중요합니다.

 **핵심 고려 사항** 

 **마이그레이션 옵션 **  
+ **RMAN Active Duplication**: 대부분의 마이그레이션에 적합하고, 중복 중에 소스 데이터베이스를 온라인 상태로 유지하며, 애플리케이션 리디렉션을 위해 짧은 컷오버 기간만 필요함
+ **Oracle Data Guard**: 가동 중지 시간이 거의 0에 가까워야 하는 미션 크리티컬 워크로드에 가장 적합하여 지속적인 동기화 및 내장 전환 기능 제공

 **아키텍처 지원:** 
+ 두 마이그레이션 옵션 모두 비CDB(기존 단일 인스턴스) 및 멀티테넌트(PDB가 있는 CDB) 아키텍처를 지원합니다.
+ 멀티테넌트의 경우 두 방법 모두 단일 작업으로 모든 PDB를 포함한 CDB를 자동으로 처리합니다.
+ PDB는 마이그레이션 후 수동 열기 및 자동 열기 구성이 필요합니다.

 **중요한 성공 요인:** 
+ 소스와 대상 간의 적절한 네트워크 구성 및 연결
+ 정확한 버전 호환성(주요 버전, 마이너 버전, 릴리스 업데이트 및 일회성 패치)
+ 데이터 전송(RMAN) 또는 재실행 전송(Data Guard)을 위한 적절한 네트워크 대역폭
+ RMAN 활성 중복이 소스를 온라인 상태로 유지한다는 것을 이해 - 짧은 컷오버만 필요
+ 소스 폐기 전 철저한 테스트 및 검증
+ 백업, 모니터링 및 보안 구성을 포함한 포괄적인 마이그레이션 후 작업

 **다음 단계:** 

1. 데이터베이스 아키텍처 평가(비CDB 또는 멀티테넌트)

1. 가동 중지 시간 허용 범위 및 복잡성 요구 사항에 따라 적절한 마이그레이션 옵션 선택

1. EC2 인스턴스 설정 및 네트워크 구성을 포함한 모든 사전 조건 단계 완료

1. 선택한 옵션에 대해 자세한 마이그레이션 단계 따르기

1. 철저한 검증 및 테스트 수행

1. 마이그레이션 후 작업을 완료하여 프로덕션 준비 보장

1. 검증 성공 후 RDS Custom 인스턴스 폐기

 **추가 리소스**.
+ [Amazon RDS Custom for Oracle 사용 설명서](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/custom.html)
+ [Oracle Database 설명서](https://docs.oracle.com/en/database/)
+ [Oracle RMAN 설명서](https://docs.oracle.com/en/database/oracle/oracle-database/19/bradv/)
+ [Oracle Data Guard 설명서](https://docs.oracle.com/en/database/oracle/oracle-database/19/sbydb/)
+ [AWS Database Migration Service](https://aws.amazon.com/dms/)
+ [AWS 권장 가이드](https://aws.amazon.com/prescriptive-guidance/)

 ** 지원** 

마이그레이션에 도움이 필요한 경우:
+ AWS Management Console을 통해 AWS Support에 문의
+ 데이터베이스 관련 질문은 Oracle Support에 문의

## **문서 정보**
<a name="RDS-Custom-for-Oracle-end-of-support-document-information"></a>

**최종 업데이트 날짜:** 2026년 3월

**기여자:**
+ Sharath Chandra Kampili, Amazon Web Services Database Specialist Solutions Architect
+ Ibrahim Emara, Amazon Web Services Database Specialist Solution Architect
+ Vetrivel Subramani, Amazon Web Services Database Specialist Solution Architect