

# RDS Custom for Oracle 终止支持
<a name="RDS-Custom-for-Oracle-end-of-support"></a>

**注意**  
终止支持通知：AWS 将于 2027 年 3 月 31 日终止对 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 企业版的 Amazon RDS Custom for Oracle 实例
+ 拥有创建和管理 EC2 实例的相应 AWS Identity and Access Management（IAM）权限
+ 了解您的数据库架构（非 CDB 或带有 PDB 的多租户 CDB）
+ 源实例与目标实例之间的网络连接规划
+ 针对迁移的备份和恢复策略

## 迁移选项
<a name="RDS-Custom-for-Oracle-end-of-support-migration_options"></a>

作为迁移过程的一部分，您可以根据业务需求和使用案例从两个迁移选项中选择一个：

### 选项 1：RMAN 主动复制（在线/离线迁移）
<a name="RDS-Custom-for-Oracle-end-of-support-migration_options-RMAN"></a>

**最适合**
+ 在最终割接期间能够承受计划内停机时间的工作负载
+ 移动部件较少，迁移要求较简单
+ 您想要在其中进行简单、一次性迁移的数据库
+ 在割接之前不需要持续同步的场景

**主要特性**
+ **停机时间**：最终割接过程中的最短停机时间（数据库在复制过程中保持在线，最终割接时停机时间很短）
+ **复杂度**：通过直接数据库复制来降低复杂度
+ **持续时间**：迁移时间取决于数据库大小和网络带宽
+ **回退**：需要保留源数据库直至验证完成
+ **在线功能**：在复制过程中，源数据库保持在线状态并可供访问

**迁移方法：**RMAN 主动复制通过网络从实时、运行的源数据库中复制数据库文件，从而在目标上创建源数据库的精确副本。在复制过程中，源数据库保持在线状态，可供应用程序访问。对于多租户数据库，RMAN 在单个操作中自动复制整个 CDB，包括 `CDB$ROOT`、`PDB$SEED` 和所有可插拔数据库。只需一个简短的割接时段，即可将应用程序重定向到新的 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 会自动保护整个 CDB，包括所有 PDB。

 **决策矩阵** 

使用以下矩阵来协助选择适当的迁移选项：


|  **方面**  |  **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）** 

托管多个可插拔数据库（PDB）的容器数据库（CDB），在 Oracle 12c 中引入。这些数据库：
+ 具有一个带有 `CDB$ROOT` 和 `PDB$SEED` 的容器数据库（CDB）
+ 托管一个或多个可插拔数据库（PDB）
+ 提供数据库整合和资源隔离
+ 在 RDS Custom for Oracle 中通常命名为 RDSCDB
+ 对于 PDB 数据文件，使用 Oracle 托管式文件（OMF）来管理，并采用基于 GUID 的子目录

**多租户迁移的重要注意事项**：在迁移过程中，目标数据库将重命名为 ORCL（源：RDSCDB → 目标：ORCL）。这可简化目标配置并与标准命名约定保持一致。

 **迁移方法的主要区别** 


|  **方面**  |  **非 CDB**  |  **多租户（带有 PDB 的 CDB）**  | 
| --- | --- | --- | 
| **迁移范围** | 单个数据库 | 包含所有 PDB 的整个 CDB | 
| **迁移后状态**  | 数据库打开 READ WRITE | CDB 打开 READ WRITE；PDB 处于 MOUNTED 状态 | 
| **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 操作系统版本匹配或兼容）
   + **Oracle 软件**：安装 Oracle Database 软件（与 RDS Custom 相同的主要版本、次要版本、版本更新，最好是相同的一次性补丁）。确保 Oracle 软件安装在 /u01/app/oracle/ 中或您的首选位置。
   + **存储**：将 Amazon EBS 卷配置为适当的大小和 IOPS，以满足您的工作负载要求。考虑使用 gp3 卷来获得经济高效的性能，或者使用 io2 Block Express 来处理高性能工作负载。

1. 配置存储架构

   1. 文件系统存储（建议用于大多数场景）
      + 使用标准文件系统目录来处理 Oracle 数据文件
      + 管理更简单，适用于大多数工作负载
      + 本指南使用文件系统存储示例

   1. Oracle Automatic Storage Management（ASM）
      + 如果您的工作负载需要 ASM，请在 EC2 实例上安装和配置独立的 ASM
      + 相应地调整 init 文件中的所有路径参数以使用 ASM 磁盘组（例如 \+DATA、\+FRA）
      + 用于 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 使用 Oracle 托管式文件（OMF）来管理 PDB 数据文件，并采用基于 GUID 的子目录（例如 `/rdsdbdata/db/pdb/RDSCDB_A/{{{GUID}}}/datafile/`）。迁移过程将自动在目标上创建必要的子目录结构。您只需创建父目录即可。

   **存储策略**：考虑为 /u01/app/oracle/backup 使用单独的 EBS 卷，以便在迁移完成后轻松将其分离和移除，从而节省存储成本。

1. 验证源数据库配置

在开始迁移之前，请验证您的源数据库配置：

1. 以 rdsdb 用户身份登录 RDS Custom 数据库主机并设置环境：  
**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;
   ```

   预期输出（具有 1 个名为 ORCLDB 的 PDB 的示例）：  
**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 可确保复制的数据库是一致的
+ **单个操作**：对于多租户，在一个操作中复制整个 CDB，包括所有 PDB

复制过程在目标上创建源数据库的精确副本，包括所有数据文件、控制文件和重做日志。在整个复制过程中，源数据库继续为应用程序请求提供服务。最后只需要一个短暂的割接时段，即可将应用程序从源重定向到目标。

**典型时间表**

1. **复制阶段**（源保持在线）：30 分钟到几个小时，具体取决于数据库大小

1. **验证阶段**（源保持在线）：根据需要，数小时到数天

1. **割接阶段**（短暂的停机时间）：将应用程序重定向到 EC2 需要几分钟

### RMAN 主动复制的迁移工作流程
<a name="RDS-Custom-for-Oracle-end-of-support-option-1-migration-workflow"></a>

**RDS Custom 数据库实例（源）步骤：**

1. 暂停 Amazon RDS Custom 自动化

1. 验证数据库架构（非 CDB 或带有 PDB 的 CDB）

1. 从源数据库创建密码文件和参数文件

1. 将密码文件和参数文件复制到目标 EC2 实例

1. 验证源数据库是否在归档日志模式下运行

1. 在 RDS Custom 数据库服务器上配置 tnsnames.ora

**EC2 数据库实例（目标）步骤：**

1. 编辑 EC2 的参数文件（架构特定）

1. 在 EC2 上配置 tnsnames.ora

1. 配置 EC2 实例的环境

1. 在 EC2 上配置 Oracle 侦听器

1. 在 EC2 上以 NOMOUNT 状态启动数据库

**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>

在继续执行迁移步骤之前，请在 RDS Custom 实例上暂停自动化模式，以确保自动化不会干扰 RMAN 活动。应根据数据库大小和预期的复制时间调整 --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 使用 OMF 来管理 PDB 数据文件，并采用基于 GUID 的子目录，而路径映射会自动处理这一情况。

 **完整的示例参数文件：**

**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 托管式文件（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 | 12 GB（12884901888 字节） | 14 GB（15032385536 字节） | 
| 32 GB | 24 GB（25769803776 字节） | 28 GB（30064771072 字节） | 
| 64 GB | 48 GB（51539607552 字节） | 56 GB（60129542144 字节） | 
| 128 GB | 96 GB（103079215104 字节） | 112 GB（120259084288 字节） | 

将大约 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，包括 `CDB$ROOT`、`PDB$SEED` 和所有 PDB
**NOFILENAMECHECK**：即使文件名在源和目标之间不同，也支持 RMAN 继续运行
**持续时间**：取决于数据库大小和网络带宽。对于 100 GB 的数据库，预计为 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 会话将显示详细的进度信息，包括：
   + 通道分配
   + 数据文件复制进度
   + 估计的完成时间
   + 已处理的字节数

   ```
   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: full datafile restore”）
   + `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 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;
```

如果找到了任何应用程序对象，请在继续操作之前将其迁移到相应的应用程序架构。

**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 会在 `CDB$ROOT` 中创建可在所有 PDB 中看到的普通用户。您必须从 `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 会自动保护整个 CDB，包括所有 PDB。任何 PDB 生成的重做都将传送到备用数据库并应用于备用数据库上相应的 PDB。

### Oracle Data Guard 的迁移工作流程
<a name="RDS-Custom-for-Oracle-end-of-support-option-2-odg-workflow"></a>

**RDS Custom 数据库实例（主实例）步骤：**

1. 暂停 Amazon RDS Custom 自动化

1. 验证数据库架构（非 CDB 或带有 PDB 的 CDB）

1. 确认主数据库正在归档日志模式下运行并且已启用 `FORCE_LOGGING`

1. 创建密码文件

1. 对主数据库执行 RMAN 在线备份（或使用主动复制）

1. 从源数据库创建参数文件

1. 将备份集、参数文件和密码文件复制到目标 EC2 实例

**EC2 数据库实例（备用实例）步骤：**

1. 将源中的所有文件复制到 EC2 实例

1. 将密码文件复制到 EC2 实例

1. 编辑 EC2 的参数文件（架构特定）

1. 从参数文件创建服务器参数文件

1. 还原备用控制文件和数据库

**Data Guard 配置步骤：**

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 实例上的自动化模式。应根据数据库大小和预期 Data Guard 设置时间调整 `--resume-full-automation-mode-minute` 参数。

```
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';
```

**注意**  
对于多租户，数据库关键字会自动备份整个 CDB，包括所有 PDB。

#### 选项 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 路径**：将 `/rdsdbdata/` 替换为 `/u01/app/oracle/`

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;
```

预期输出（PDB 在备用实例上处于 `MOUNTED` 状态）：

```
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;
```

预期输出（PDB 处于 `MOUNTED` 状态 - 具有一个名为 `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>

使用保存状态方法将 PDB 配置为在 CDB 启动时自动打开（建议用于 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 会在 `CDB$ROOT` 中创建可在所有 PDB 中看到的普通用户。您必须从 `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` 路径正确，则无需执行任何操作。否则，请创建一个 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 实例的 Oracle 版本更新（RU）或一次性补丁与源 RDS Custom 实例不同，导致在迁移期间或迁移后出现兼容性错误。

**常见错误：**
+ 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 上检查 iptables：

   ```
   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
   ```

### CDB 重启后 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. 验证备用实例是否处于 MOUNT 模式：

   ```
   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 参数指向备用实例（如果在没有代理的情况下手动配置）。

 **Data Guard 应用滞后随着多个 PDB 而增加（仅限多租户）** 

**原因：**对于具有多个 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）。

 **RMAN 归档日志备份失败并显示 ORA-19625** 

**原因：**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>

 

**原因：**必须使用 `CONTAINER=ALL` 子句删除普通用户（以 C\#\# 为前缀）。

 **解决方案：**

```
-- 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 名称）
+ 确保应用程序连接到正确的 PDB，而不是 CDB
+ 更新连接字符串以使用 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:**
+ 使用 [AWS Backup](https://aws.amazon.com/backup/) 制作 EBS 卷快照
+ 配置备份计划和保留策略
+ 启用跨区域备份副本以实现灾难恢复

**对于多租户：**
+ CDB 的 RMAN 备份自动包含所有 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 会话管理器
+ 禁用密码身份验证并仅使用基于密钥的身份验证
+ 实施多重身份验证（MFA）以进行特权访问

**加密：**
+ 为 EBS 卷启用静态加密
+ 使用 Oracle Native Network Encryption 或 TLS 为数据库连接启用传输中加密
+ 定期轮换加密密钥

**实施高可用性**

如果您的工作负载需要高可用性，请考虑实施：

**Oracle Data Guard：**
+ 在另一个 EC2 实例上配置新的备用数据库以进行灾难恢复
+ 对于多租户，Data Guard 保护整个 CDB，包括所有 PDB
+ 备用数据库可以位于不同的可用区或区域
+ 使用脚本或第三方工具实施自动失效转移机制

**AWS 多可用区部署：**
+ 在不同的可用区中部署备用实例
+ 使用 Amazon Route 53 进行 DNS 失效转移
+ 通过失效转移支持实施应用程序级连接池

**备份和恢复：**
+ 使用经过测试的还原过程维护定期备份
+ 记录恢复时间目标（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 控制台或 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 主动复制与 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** | 否 | 是 | 
| **所需的技能等级** | 中间 | 高级 | 
| **割接过程** | 将应用程序重定向到 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 | 
| **资源管理** | 数据库级资源管理 | 使用资源管理器管理 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/zh_cn/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/zh_cn/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.  制定回滚计划：

   始终具有回滚策略：
   + 在验证期（建议 1-2 周）内**保持 RDS Custom 实例运行**
   + **保持定期备份**源和目标
   + **记录回滚过程**，包括连接字符串更改
   + 在非生产环境中**测试回滚过程**
   + **定义回滚标准**（性能降级、数据不一致、应用程序错误）

### 迁移执行最佳实践
<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
   ```

   要比较的关键指标：
   + 平均活动会话数
   + 每个事务的数据库时间
   + 每秒物理读取次数
   + 每秒逻辑读取次数
   + 每秒重做大小
   + 每秒用户调用数
   + 每次执行的解析时间

### 迁移后优化
<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 自定义指标：**

      创建脚本以将 Oracle 指标发布到 CloudWatch：

      ```
      #!/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 快照**
+ **使用 gp3 而不是 gp2**，以便在性能相同的情况下节省成本
+ 迁移完成后**分离和删除备份卷**

 **3. – 自动化** 
+ 在非生产时间**自动启动/停止**非生产数据库
+ **使用 AWS Systems Manager** 进行补丁管理
+ 如果使用 Data Guard，则对只读副本**实施自动扩缩**

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

本规范性指南提供了详细的迁移策略，用于将 Oracle 数据库从 Amazon RDS Custom for Oracle 迁移到 Amazon EC2 上自行管理的 Oracle 数据库。随着 RDS Custom for Oracle 服务弃用将于 2027 年 3 月 31 日生效，提前规划和执行迁移非常重要。

 **关键要点** 

 **迁移选项 **  
+ **RMAN 主动复制**：最适合大多数迁移，在复制期间保持源数据库在线，只需短暂的割接时段即可实现应用程序重定向
+ **Oracle Data Guard**：最适合要求停机时间接近零的任务关键型工作负载，可提供持续同步和内置切换功能

 **架构支持**：
+ 这两种迁移选项都支持非 CDB（传统单实例）和多租户（带有 PDB 的 CDB）架构
+ 对于多租户，这两种方法都可以在单个操作中自动处理整个 CDB，包括所有 PDB
+ 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 管理控制台联系 AWS Support
+ 有关数据库特定的问题，请咨询 Oracle 支持

## **文档信息**
<a name="RDS-Custom-for-Oracle-end-of-support-document-information"></a>

**上次更新时间：**2026 年 3 月

**贡献者：**
+ Sharath Chandra Kampili，Amazon Web Services 数据库专家解决方案架构师
+ Ibrahim Emara，Amazon Web Services 数据库专家解决方案架构师
+ Vetrivel Subramani，Amazon Web Services 数据库专家解决方案架构师