

# 对复制进行问题排查
<a name="replication-troubleshoot"></a>

本节列出了 Amazon S3 复制的问题排查提示以及有关 S3 批量复制错误的信息。

**Topics**
+ [S3 复制问题排查提示](#troubleshoot-replication-tips)
+ [批量复制错误](#troubleshoot-batch-replication-errors)

## S3 复制问题排查提示
<a name="troubleshoot-replication-tips"></a>

如果在您配置复制之后，对象副本未出现在目标桶中，请使用以下问题排查提示确定并修复问题。
+ 大多数对象会在 15 分钟内复制。Amazon S3 复制对象所需的时间取决于多个因素，包括源和目标区域对，以及对象的大小。对于大型对象，复制可能需要几个小时。要想了解复制时间，您可以[使用 S3 Replication Time Control（S3 RTC）](https://docs.amazonaws.cn/AmazonS3/latest/userguide/replication-time-control.html#enabling-replication-time-control)。

  如果要复制的对象较大，请稍候片刻，然后再检查它是否出现在目标桶中。还可以检查源对象的复制状态。如果对象复制状态为 `PENDING`，表示 Amazon S3 尚未完成复制。如果对象复制状态为 `FAILED`，请检查对源桶设置的复制配置。

  此外，要在复制期间接收有关失败的信息，您可以设置 Amazon S3 事件通知来接收复制失败事件。有关更多信息，请参阅[使用 Amazon S3 事件通知接收复制失败事件](https://docs.amazonaws.cn/AmazonS3/latest/userguide/replication-metrics.html)。
+ 要检查对象的复制状态，可以调用 `HeadObject` API 操作。`HeadObject` API 操作返回对象的 `PENDING`、`COMPLETED` 或 `FAILED` 复制状态。在对 `HeadObject` API 调用的响应中，复制状态将在 `x-amz-replication-status` 标头中返回。
**注意**  
要运行 `HeadObject`，您必须对您请求的对象拥有读取权限。`HEAD` 请求与 `GET` 请求具有相同的选项，无需执行 `GET` 操作。例如，要使用 Amazon Command Line Interface（Amazon CLI）运行 `HeadObject` 请求，可以运行以下命令。将 `{{user input placeholders}}` 替换为您自己的信息。  

  ```
  aws s3api head-object --bucket {{amzn-s3-demo-source-bucket}} --key {{index.html}}
  ```
+ 如果 `HeadObject` 返回复制状态为 `FAILED` 的对象，则可以使用 S3 批量复制来复制这些失败的对象。有关更多信息，请参阅 [使用批量复制以复制现有对象](s3-batch-replication-batch.md)。或者，您可以将失败的对象重新上传到源桶，这将启动新对象的复制。
+ 在源桶上的复制配置中，验证以下几点：
  + 目标存储桶的 Amazon 资源名称 (ARN) 是否正确。
  + 键名前缀是否正确。例如，如果将配置设置为复制具有前缀 `Tax` 的对象，则仅复制具有 `Tax/document1` 或 `Tax/document2` 等键名的对象。不会复制具有键名 `document3` 的对象。
  + 复制规则的状态为 `Enabled`。
+ 在复制配置中验证尚未对任何存储桶暂停版本控制。源桶和目标桶必须均已启用版本控制。
+ 如果将复制规则设置为**将对象所有权更改为目标桶拥有者**，则用于复制的 Amazon Identity and Access Management（IAM）角色必须具有 `s3:ObjectOwnerOverrideToBucketOwner` 权限。此权限是对资源（在本例中为目标桶）授予的。例如，以下 `Resource` 语句显示如何授予对目标桶的这一权限：

  ```
  {
    "Effect":"Allow",
    "Action":[
      "s3:ObjectOwnerOverrideToBucketOwner"
    ],
    "Resource":"arn:aws:s3:::{{amzn-s3-demo-destination-bucket}}/*"
  }
  ```
+ 如果目标桶由另一个账户拥有，则目标桶的拥有者还必须通过目标桶策略向源桶拥有者授予 `s3:ObjectOwnerOverrideToBucketOwner` 权限。要使用以下示例桶策略，请将 `{{user input placeholders}}` 替换为您自己的信息：

------
#### [ JSON ]

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Id": "Policy1644945280205",
    "Statement": [
      {
        "Sid": "Stmt1644945277847",
        "Effect": "Allow",
        "Principal": {
          "AWS": "arn:aws:iam::{{123456789101}}:role/{{s3-replication-role}}"
        },
        "Action": [
          "s3:ReplicateObject",
          "s3:ReplicateTags",
          "s3:ObjectOwnerOverrideToBucketOwner"
        ],
        "Resource": "arn:aws:s3:::{{amzn-s3-demo-destination-bucket}}/*"
      }
    ]
  }
  ```

------
**注意**  
如果目标桶的对象所有权设置包括**强制桶拥有者**，则无需在复制规则中将此设置更新为**将对象所有权更改为目标桶拥有者**。原定设置情况下，对象所有权将发生变化。有关更改副本所有权的更多信息，请参阅[更改副本所有权](https://docs.amazonaws.cn/AmazonS3/latest/userguide/replication-change-owner.html)。
+ 如果您要在跨账户场景（即源存储桶和目标存储桶由不同的 Amazon Web Services 账户拥有）中设置复制配置，则目标存储桶无法配置为申请方付款存储桶。有关更多信息，请参阅 [使用申请方付款通用存储桶进行存储传输和使用](RequesterPaysBuckets.md)。
+ 如果存储桶的源对象使用具有 Amazon Key Management Service（Amazon KMS）密钥的服务器端加密（SSE-KMS）来进行加密，则必须将复制规则配置为包含 Amazon KMS 加密的对象。确保在 Amazon S3 控制台中的**加密**设置下选择**复制使用 Amazon KMS 加密的对象**。然后，选择用于加密目标对象的 Amazon KMS 密钥。
**注意**  
如果目标桶位于其他账户中，请指定目标账户拥有的 Amazon KMS 客户自主管理型密钥。不要使用原定设置的 Amazon S3 托管式密钥（`aws/s3`）。使用默认密钥会使用由源账户拥有的 Amazon S3 托管式密钥来加密对象，从而防止与其它账户共享对象。因此，目标账户将无法访问目标桶中的对象。

  要使用属于目标账户的 Amazon KMS 密钥加密目标对象，目标账户必须在 KMS 密钥策略中向复制角色授予 `kms:GenerateDataKey` 和 `kms:Encrypt` 权限。要在 KMS 密钥策略中使用以下示例语句，请将 `{{user input placeholders}}` 替换为您自己的信息：

  ```
  {    
      "Sid": "AllowS3ReplicationSourceRoleToUseTheKey",
      "Effect": "Allow",
      "Principal": {
          "AWS": "arn:aws:iam::{{123456789101}}:role/{{s3-replication-role}}"
      },
      "Action": ["kms:GenerateDataKey", "kms:Encrypt"],
      "Resource": "*"
  }
  ```

  如果您在 Amazon KMS 密钥策略中的 `Resource` 语句中使用星号（`*`），则该策略将使用 KMS 密钥的权限仅授予复制角色。该策略不允许复制角色提升其权限。

  原定设置情况下，KMS 密钥策略向根用户授予对密钥的完全权限。这些权限可以委派给同一账户中的其他用户。除非源 KMS 密钥策略中具有 `Deny` 语句，否则，使用 IAM policy 向复制角色授予对源 KMS 密钥的权限就足够了。
**注意**  
将访问权限限制到特定 CIDR 范围、虚拟私有云（VPC）端点或 S3 接入点的 KMS 密钥策略可能会导致复制失败。

  如果源或目标 KMS 密钥根据加密上下文授予权限，请确认对于桶开启了 Amazon S3 桶密钥。如果桶已开启了 S3 桶密钥，则加密上下文必须是桶级资源，如下所示：

  ```
  "kms:EncryptionContext:arn:aws:arn": [
       "arn:aws:s3:::{{amzn-s3-demo-source-bucket}}"
       ]
  "kms:EncryptionContext:arn:aws:arn": [
       "arn:aws:s3:::{{amzn-s3-demo-destination-bucket}}"
       ]
  ```

  除了 KMS 密钥策略授予的权限外，源账户还必须向复制角色的 IAM policy 添加以下最低权限：

  ```
  {
      "Effect": "Allow",
      "Action": [
          "kms:Decrypt",
          "kms:GenerateDataKey"
      ],
      "Resource": [
          "{{Source-KMS-Key-ARN}}"
      ]
  },
  {
      "Effect": "Allow",
      "Action": [
          "kms:GenerateDataKey",
          "kms:Encrypt"
      ],
      "Resource": [
          "{{Destination-KMS-Key-ARN}}"
      ]
  }
  ```
**重要**  
如果您使用 S3 批量复制来跨区域复制数据集，并且您的对象之前已将其服务器端加密类型从 SSE-S3 更新为 SSE-KMS，则您可能需要额外的权限。在源区域存储桶上，您必须拥有 `kms:decrypt` 权限。然后，您将需要针对目标区域中存储桶的 `kms:decrypt` 和 `kms:encrypt` 权限。

  有关如何复制使用 Amazon KMS 加密的对象的更多信息，请参阅[复制加密的对象](https://docs.amazonaws.cn/AmazonS3/latest/userguide/replication-walkthrough-4.html)。
+ 如果目标桶由另一个 Amazon Web Services 账户拥有，请验证桶拥有者是否对目标桶设置了允许源桶拥有者复制对象的桶策略。有关示例，请参阅[针对不同账户中的存储桶配置复制](replication-walkthrough-2.md)。
+ 要将对象锁定与复制功能结合使用，您必须在用于设置复制的 Amazon Identity and Access Management（IAM）角色中，授予对源 S3 存储桶的两项额外的权限。这两项额外的权限是 `s3:GetObjectRetention` 和 `s3:GetObjectLegalHold`。如果角色已有 `s3:Get*` 权限声明，则该声明已满足要求。有关更多信息，请参阅 [将对象锁定与 S3 复制结合使用](object-lock-managing.md#object-lock-managing-replication)。
+ 如果在验证权限后您的对象仍无法复制，请检查以下位置是否存在任何显式 `Deny` 语句：
  + 源或目标桶策略中的 `Deny` 语句。如果桶策略拒绝针对以下任一操作访问复制角色，则复制将失败：

    源桶：

    ```
    1.            "s3:GetReplicationConfiguration",
    2.            "s3:ListBucket",
    3.            "s3:GetObjectVersionForReplication",
    4.            "s3:GetObjectVersionAcl",
    5.            "s3:GetObjectVersionTagging"
    ```

    目标桶：

    ```
    1.            "s3:ReplicateObject",
    2.            "s3:ReplicateDelete",
    3.            "s3:ReplicateTags"
    ```
  + 附加到 IAM 角色的 `Deny` 语句或权限边界可能导致复制失败。
  + 附加到源账户或目标账户的 Amazon Organizations 服务控制策略（SCP）中的 `Deny` 语句可能导致复制失败。
  + 附加到源或目标存储桶的 Amazon Organizations 资源控制策略（RCP）中的 `Deny` 语句可能导致复制失败。
+ 如果对象副本未出现在目标桶中，以下问题可能会禁止复制：
  + 若源桶中的某对象是另一个复制配置所创建的副本，Amazon S3 不会复制该对象。例如，如果您设置从桶 A 到桶 B 再到桶 C 的复制配置，则 Amazon S3 不会将桶 B 中的对象副本复制到桶 C。
  + 源桶拥有者可以向其他 Amazon Web Services 账户授予上载对象的权限。默认情况下，源桶拥有者对于其他账户创建的对象没有权限。复制配置仅复制源桶拥有者对其具有访问权限的对象。为避免出现此问题，源存储桶拥有者可以向其它 Amazon Web Services 账户授予有条件地创建对象的权限，从而要求针对这些对象的显式访问权限。有关策略示例，请参阅 [在授予上传对象的跨账户权限的同时，确保存储桶拥有者拥有完全控制权](example-bucket-policies.md#example-bucket-policies-acl-2)。
+ 假设在复制配置中，您添加了一个规则以复制具有特定标签的对象子集。在这种情况下，您必须在创建对象时分配特定的标签键和值，以供 Amazon S3 复制对象。如果您先创建对象，然后向现有对象添加标签，Amazon S3 将不会复制对象。
+ 使用 Amazon S3 事件通知，以便您在对象未复制到其目标 Amazon Web Services 区域的情况下收到通知。Amazon S3 事件通知可以通过 Amazon Simple Queue Service（Amazon SQS）、Amazon Simple Notification Service（Amazon SNS）或 Amazon Lambda 提供。有关更多信息，请参阅 [使用 Amazon S3 事件通知接收复制失败事件](replication-metrics-events.md)。

  您还可以使用 Amazon S3 事件通知查看复制失败原因。要查看失败原因的列表，请参阅 [Amazon S3 复制失败原因](https://docs.amazonaws.cn/AmazonS3/latest/userguide/replication-failure-codes.html)。

## 批量复制错误
<a name="troubleshoot-batch-replication-errors"></a>

要对未复制到目标存储桶的对象进行故障排除，请检查存储桶、复制角色和用于创建批量复制任务的 IAM 角色的不同权限类型。此外，请务必检查存储桶的屏蔽公共访问权限设置和 S3 对象所有权设置。

有关使用批量复制的更多故障排除提示，请参阅[排查 S3 批量操作问题](troubleshooting-batch-operations.md)。

如果您已设置复制但对象未复制，请参阅 Amazon Web Services re:Post 知识中心中的[在存储桶之间设置复制时，为什么我的 Amazon S3 对象不复制？](https://repost.aws/knowledge-center/s3-troubleshoot-replication)

当使用批量复制时，可能会遇到以下错误之一：
+ 生成清单时未找到符合筛选条件的密钥。

  出现此错误的原因为以下之一：
  + 当源存储桶中的对象存储在 S3 Glacier Flexible Retrieval 或 S3 Glacier Deep Archive 存储类中时。

    要对这些对象使用批量复制，请先在批量操作任务中使用**还原** (`S3InitiateRestoreObjectOperation`) 操作，将它们还原到 S3 Standard 存储类。有关更多信息，请参阅[恢复已归档的对象](restoring-objects.md)和[还原对象（批量操作）](batch-ops-initiate-restore-object.md)。还原对象后，您可以使用批量复制任务来复制它们。
  + 当提供的筛选条件与源存储桶中的任何有效对象都不匹配时。

    验证并更正筛选条件。例如，在批量复制规则中，筛选条件负责查找源存储桶中带有 `Tax/` 前缀的所有对象。如果前缀名称输入不准确，开头和结尾都有一个斜杠（即 `/Tax/`），而不是仅在结尾处有斜杠，则找不到任何 S3 对象。要解决此错误，请更正前缀，在本例中就是将复制规则中的 `/Tax/` 更改为 `Tax/`。
+ 批量操作状态为失败，原因是：无法将任务报告写入报告桶。

  如果用于批量操作任务的 IAM 角色无法将完成报告放到您创建任务时指定的位置，则会出现此错误。要解决此错误，请检查 IAM 角色是否对您要保存批量操作完成报告的存储桶具有 `s3:PutObject` 权限。我们建议将报告发送到与源存储桶不同的存储桶。
+ 批量操作已完成但出现失败，并且失败总数不是 0。

  如果正在运行的批量复制任务存在对象权限不足问题，则会出现此错误。如果您对批量复制任务使用复制规则，请确保用于复制的 IAM 角色具有适当的权限，可访问源存储桶或目标存储桶中的对象。也可以检查[批量复制完成报告](https://docs.amazonaws.cn/AmazonS3/latest/userguide/s3-batch-replication-batch.html#batch-replication-completion-report)，以查看特定的 [Amazon S3 复制失败原因](https://docs.amazonaws.cn/AmazonS3/latest/userguide/replication-failure-codes.html)。
+ 批量任务成功运行，但目标桶中预期的对象数量不相同。

  当批量复制任务中提供的清单中列出的对象与您在创建任务时选择的筛选条件不匹配时，就会出现此错误。当源桶中的对象与任何复制规则不匹配且未包含在生成的清单中时，您也可能会收到此消息。

### 向现有复制配置添加新的复制规则后，会出现批量操作失败
<a name="new-replication-rule"></a>

批量操作尝试对源桶的复制配置中的每条规则执行现有对象复制。如果任何现有复制规则出现问题，则可能会出现失败。

批量操作任务的完成报告解释了任务失败的原因。有关常见错误的列表，请参阅[Amazon S3 复制失败原因](replication-metrics-events.md#replication-failure-codes)。