

# 在 Amazon RDS for Oracle 和 Amazon S3 存储桶之间传输文件
<a name="oracle-s3-integration.using"></a>

要在 RDS for Oracle 数据库实例和 Amazon S3 桶之间传输文件，您可以使用 Amazon RDS 软件包 `rdsadmin_s3_tasks`。您可以在上传文件时使用 GZIP 压缩文件，并在下载时解压缩它们。

**Topics**
+ [文件传输功能的要求和限制](#oracle-s3-integration.using.reqs)
+ [将文件从 RDS for Oracle 数据库实例上传到 Amazon S3 存储桶](#oracle-s3-integration.using.upload)
+ [将文件从 Amazon S3 存储桶下载到 Oracle 数据库实例](#oracle-s3-integration.using.download)
+ [监控文件传输的状态](#oracle-s3-integration.using.task-status)

## 文件传输功能的要求和限制
<a name="oracle-s3-integration.using.reqs"></a>

在您的数据库实例和 Amazon S3 存储桶之间传输文件之前，请注意以下事项：
+ `rdsadmin_s3_tasks` 软件包传输位于单个目录中的文件。您不能在传输中包括子目录。
+ Amazon S3 存储桶中的最大对象大小为 5 TB。
+ `rdsadmin_s3_tasks` 创建的任务以异步方式运行。
+ 您可以从 Data Pump 目录（例如 `DATA_PUMP_DIR`）或用户创建的任何目录上传文件。您不能从 Oracle 后台进程使用的目录（例如 `adump`、`bdump` 或 `trace` 目录）上传文件。
+ 对于 `download_from_s3`，每次过程调用的下载限制为 2000 个文件。如果您需要从 Amazon S3 下载超过 2000 个文件，请将您的下载分成多个单独的操作，每个过程调用不超过 2000 个文件。
+ 如果您的下载文件夹中存在文件，并且您尝试下载同名的文件，`download_from_s3` 将跳过下载。要从下载目录中移除文件，请使用 PL/SQL 过程 [UTL\$1FILE.FREMOVE](https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/UTL_FILE.html#GUID-09B09C2A-2C21-4F70-BF04-D0EEA7B59CAF)。

## 将文件从 RDS for Oracle 数据库实例上传到 Amazon S3 存储桶
<a name="oracle-s3-integration.using.upload"></a>

要将文件从数据库实例上传到 Amazon S3 存储桶，请使用 `rdsadmin.rdsadmin_s3_tasks.upload_to_s3` 过程。例如，您可以上传 Oracle Recovery Manager（RMAN）备份文件或 Oracle Data Pump 文件。有关使用对象的更多信息，请参阅 [Amazon Simple Storage Service 用户指南](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingObjects.html)。有关执行 RMAN 备份的更多信息，请参阅 [执行 Oracle 数据库实例的常见 RMAN 任务](Appendix.Oracle.CommonDBATasks.RMAN.md)。

`rdsadmin.rdsadmin_s3_tasks.upload_to_s3` 过程具有以下参数。


****  

| 参数名称 | 数据类型 | 默认值 | 必需 | 描述 | 
| --- | --- | --- | --- | --- | 
|  `p_bucket_name`  |  VARCHAR2  |  –  |  必需  |  要将文件上传到其中的 Amazon S3 存储桶的名称。  | 
|  `p_directory_name`  |  VARCHAR2  |  –  |  必需  |  要从其中上传文件的 Oracle 目录对象的名称。该目录可以是用户创建的任何目录对象或 Data Pump 目录，例如 `DATA_PUMP_DIR`。您不能从后台进程使用的目录（例如 `adump`、`bdump` 和 `trace`）上传文件。  您只可以从指定目录上传文件。您不能上传指定目录的子目录中的文件。   | 
|  `p_s3_prefix`  |  VARCHAR2  |  –  |  必需  |  待上传文件的 Amazon S3 文件名前缀。如果前缀为空，则将所有文件上传到指定 Amazon S3 存储桶的最顶层，且不为文件名添加前缀。 例如，如果前缀为 `folder_1/oradb`，则文件上传到 `folder_1`。在这个例子中，`oradb` 前缀添加到每个文件。  | 
|  `p_prefix`  |  VARCHAR2  |  –  |  必需  |  一个文件名前缀，文件名必须与其匹配才会上传。如果前缀为空，则将所有文件上传到指定目录。  | 
|  `p_compression_level`  |  NUMBER  |  `0`   |  optional  |  GZIP 压缩级别。有效值范围为 `0` 至 `9`： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/oracle-s3-integration.using.html)  | 
|  `p_bucket_owner_full_control`  |  VARCHAR2  |  –  |  可选  |  存储桶的访问控制设置。有效值仅为 null 和 `FULL_CONTROL`。仅当您从一个账户（账户 A）将文件上传到另一账户（账户 B）拥有的存储桶，并且账户 B 需要完全控制这些文件时，才需要此设置。  | 

`rdsadmin.rdsadmin_s3_tasks.upload_to_s3` 过程的返回值是任务 ID。

下面的示例将 `DATA_PUMP_DIR` 目录中的所有文件上传到名为 *amzn-s3-demo-bucket* 的 Amazon S3 存储桶。文件不会被压缩。

```
SELECT rdsadmin.rdsadmin_s3_tasks.upload_to_s3(
      p_bucket_name    =>  'amzn-s3-demo-bucket',
      p_prefix         =>  '', 
      p_s3_prefix      =>  '', 
      p_directory_name =>  'DATA_PUMP_DIR') 
   AS TASK_ID FROM DUAL;
```

下面的示例将 `db` 目录中前缀为 `DATA_PUMP_DIR` 的所有文件上传到名为 `amzn-s3-demo-bucket` 的 Amazon S3 存储桶。Amazon RDS 将最高级别的 GZIP 压缩应用于这些文件。

```
SELECT rdsadmin.rdsadmin_s3_tasks.upload_to_s3(
      p_bucket_name       =>  'amzn-s3-demo-bucket', 
      p_prefix            =>  'db', 
      p_s3_prefix         =>  '', 
      p_directory_name    =>  'DATA_PUMP_DIR',
      p_compression_level =>  9) 
   AS TASK_ID FROM DUAL;
```

下面的示例将 `DATA_PUMP_DIR` 目录中的所有文件上传到名为 `amzn-s3-demo-bucket` 的 Amazon S3 存储桶。文件上传到 `dbfiles` 文件夹。在此示例中，GZIP 压缩级别为 *1*，这是速度最快的压缩级别。

```
SELECT rdsadmin.rdsadmin_s3_tasks.upload_to_s3(
      p_bucket_name       =>  'amzn-s3-demo-bucket', 
      p_prefix            =>  '', 
      p_s3_prefix         =>  'dbfiles/', 
      p_directory_name    =>  'DATA_PUMP_DIR',
      p_compression_level =>  1) 
   AS TASK_ID FROM DUAL;
```

下面的示例将 `DATA_PUMP_DIR` 目录中的所有文件上传到名为 `amzn-s3-demo-bucket` 的 Amazon S3 存储桶。文件上传到 `dbfiles` 文件夹，且 `ora` 添加到每个文件名的开头。不应用压缩。

```
SELECT rdsadmin.rdsadmin_s3_tasks.upload_to_s3(
      p_bucket_name    =>  'amzn-s3-demo-bucket', 
      p_prefix         =>  '', 
      p_s3_prefix      =>  'dbfiles/ora', 
      p_directory_name =>  'DATA_PUMP_DIR') 
   AS TASK_ID FROM DUAL;
```

以下示例假定该命令在账户 A 中运行，但账户 B 需要完全控制存储桶内容。命令 `rdsadmin_s3_tasks.upload_to_s3` 将 `s3bucketOwnedByAccountB` 目录中的所有文件传输到名为 `DATA_PUMP_DIR` 的存储桶。访问控制设置为 `FULL_CONTROL`，以便账户 B 可以访问存储桶中的文件。GZIP 压缩级别为 *6*，它可平衡速度和文件大小。

```
SELECT rdsadmin.rdsadmin_s3_tasks.upload_to_s3(
      p_bucket_name               =>  's3bucketOwnedByAccountB', 
      p_prefix                    =>  '', 
      p_s3_prefix                 =>  '', 
      p_directory_name            =>  'DATA_PUMP_DIR',
      p_bucket_owner_full_control =>  'FULL_CONTROL',
      p_compression_level         =>  6) 
   AS TASK_ID FROM DUAL;
```

在每个示例中，`SELECT` 语句返回 `VARCHAR2` 数据类型的任务 ID。

您可以通过显示任务的输出文件来查看结果。

```
SELECT text FROM table(rdsadmin.rds_file_util.read_text_file('BDUMP','dbtask-task-id.log'));
```

将 *`task-id`* 替换为由此过程返回的任务 ID。

**注意**  
任务以异步方式执行。

## 将文件从 Amazon S3 存储桶下载到 Oracle 数据库实例
<a name="oracle-s3-integration.using.download"></a>

要将文件从 Amazon S3 桶下载到 RDS for Oracle 实例，请使用 Amazon RDS 过程 `rdsadmin.rdsadmin_s3_tasks.download_from_s3`。

`download_from_s3` 过程具有以下参数。


****  

| 参数名称 | 数据类型 | 默认值 | 必需 | 描述 | 
| --- | --- | --- | --- | --- | 
|  `p_bucket_name`  |  VARCHAR2  |  –  |  必需  |  要从中下载文件的 Amazon S3 存储桶的名称。  | 
|  `p_directory_name`  |  VARCHAR2  |  –  |  必需  |  要将文件下载到其中的 Oracle 目录对象的名称。该目录可以是用户创建的任何目录对象或 Data Pump 目录，例如 `DATA_PUMP_DIR`。  | 
|  `p_error_on_zero_downloads`  |  VARCHAR2  | FALSE |  可选  |  一个标志，用于确定当 Amazon S3 桶中没有与前缀匹配的对象时，任务是否引发错误。如果此参数未设置或设置为 FALSE（原定设置），则任务会输出一条消息，指出未找到任何对象，但不会引发异常或失败。如果此参数为 TRUE，则任务会引发异常并失败。 可能无法通过匹配测试的前缀规范的示例包括前缀中的空格（如在 `' import/test9.log'` 中）和大小写不匹配（如在 `test9.log` 和 `test9.LOG` 中）。  | 
|  `p_s3_prefix`  |  VARCHAR2  |  –  |  必需  |  一个文件名前缀，文件名必须与其匹配才会下载。使用空前缀将下载指定 Amazon S3 存储桶中的所有顶级文件，但不包括存储桶中文件夹内的文件。 该过程仅从匹配前缀的第一级文件夹下载 Amazon S3 对象。匹配指定前缀的嵌套目录结构不会下载。 例如，假定 Amazon S3 存储桶拥有文件夹结构 `folder_1/folder_2/folder_3`。您可以指定 `'folder_1/folder_2/'` 前缀。在这种情况下，只会下载 `folder_2` 中的文件，不会下载 `folder_1` 或 `folder_3` 中的文件。 如果您改为指定 `'folder_1/folder_2'` 前缀，则将下载 `folder_1` 中与 `'folder_2'` 前缀匹配的所有文件，不下载 `folder_2` 中的文件。  | 
|  `p_decompression_format`  |  VARCHAR2  |  –  |  可选  |  解压缩格式。不解压缩时有效值为 `NONE`；解压缩时有效值为 `GZIP`。  | 

`rdsadmin.rdsadmin_s3_tasks.download_from_s3` 过程的返回值是任务 ID。

下面的示例将名为 `amzn-s3-demo-bucket` 的 Amazon S3 桶中的所有文件下载到 `DATA_PUMP_DIR` 目录。这些文件没有被压缩，因此不会应用解压缩。

```
SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3(
      p_bucket_name    =>  'amzn-s3-demo-bucket',
      p_directory_name =>  'DATA_PUMP_DIR') 
   AS TASK_ID FROM DUAL;
```

下面的示例将名为 `db` 的 Amazon S3 存储桶中前缀为 `amzn-s3-demo-bucket` 的所有文件下载到 `DATA_PUMP_DIR` 目录。这些文件是用 GZIP 压缩的，因此将应用解压缩。参数 `p_error_on_zero_downloads` 开启前缀错误检查，因此，如果前缀与桶中的任何文件都不匹配，则任务会引发异常并失败。

```
SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3(
      p_bucket_name               =>  'amzn-s3-demo-bucket', 
      p_s3_prefix                 =>  'db', 
      p_directory_name            =>  'DATA_PUMP_DIR',
      p_decompression_format      =>  'GZIP',
      p_error_on_zero_downloads   =>  'TRUE') 
   AS TASK_ID FROM DUAL;
```

下面的示例将名为 `myfolder/` 的 Amazon S3 存储桶中的 `amzn-s3-demo-bucket` 文件夹中的所有文件下载到 `DATA_PUMP_DIR` 目录。使用 `p_s3_prefix` 参数来指定 Amazon S3 文件夹。上传的文件使用 GZIP 压缩，但在下载期间不会解压缩。

```
SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3(
      p_bucket_name          =>  'amzn-s3-demo-bucket', 
      p_s3_prefix            =>  'myfolder/', 
      p_directory_name       =>  'DATA_PUMP_DIR',
      p_decompression_format =>  'NONE')
   AS TASK_ID FROM DUAL;
```

以下示例会将名为 `amzn-s3-demo-bucket` 的 Amazon S3 存储桶中的所有文件 `mydumpfile.dmp` 下载到 `DATA_PUMP_DIR` 目录。不应用解压缩。

```
SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3(
      p_bucket_name    =>  'amzn-s3-demo-bucket', 
      p_s3_prefix      =>  'mydumpfile.dmp', 
      p_directory_name =>  'DATA_PUMP_DIR') 
   AS TASK_ID FROM DUAL;
```

在每个示例中，`SELECT` 语句返回 `VARCHAR2` 数据类型的任务 ID。

您可以通过显示任务的输出文件来查看结果。

```
SELECT text FROM table(rdsadmin.rds_file_util.read_text_file('BDUMP','dbtask-task-id.log'));
```

将 *`task-id`* 替换为由此过程返回的任务 ID。

**注意**  
任务以异步方式执行。  
您可以使用 `UTL_FILE.FREMOVE` Oracle 过程从目录中删除文件。有关更多信息，请参阅 Oracle 文档中的 [FREMOVE 过程](https://docs.oracle.com/database/121/ARPLS/u_file.htm#ARPLS70924)。

## 监控文件传输的状态
<a name="oracle-s3-integration.using.task-status"></a>

文件传输任务开始和结束时会发布 Amazon RDS 事件。事件消息包含文件传输的任务 ID。有关查看事件的信息，请参阅 [查看 Amazon RDS 事件](USER_ListEvents.md)。

您可以查看 bdump 文件中的持续任务的状态。bdump 文件位于 `/rdsdbdata/log/trace` 目录下。每个 bdump 文件名称格式如下。

```
dbtask-task-id.log
```

将 `task-id` 替换为您想要监控的任务的 ID。

**注意**  
任务以异步方式执行。

您可以使用 `rdsadmin.rds_file_util.read_text_file` 存储过程查看 bdump 文件的内容。例如，以下查询将返回 `dbtask-1234567890123-1234.log` bdump 文件的内容。

```
SELECT text FROM table(rdsadmin.rds_file_util.read_text_file('BDUMP','dbtask-1234567890123-1234.log'));
```

以下示例显示传输失败的日志文件。

```
TASK_ID                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1234567890123-1234


TEXT                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-04-17 18:21:33.993 UTC [INFO ] File #1: Uploading the file /rdsdbdata/datapump/A123B4CDEF567890G1234567890H1234/sample.dmp to Amazon S3 with bucket name amzn-s3-demo-bucket and key sample.dmp.
2023-04-17 18:21:34.188 UTC [ERROR] RDS doesn't have permission to write to Amazon S3 bucket name amzn-s3-demo-bucket and key sample.dmp.
2023-04-17 18:21:34.189 UTC [INFO ] The task failed.
```