跳至内容

如何对 Amazon Redshift 中 UNLOAD 命令的问题进行故障排除?

3 分钟阅读
0

我想使用 UNLOAD 命令将数据从我的 Amazon Redshift 集群卸载到 Amazon Simple Storage Service (Amazon S3)。但是,我收到了一条错误消息。

简短描述

运行 UNLOAD 命令时,可能会收到一条类似于以下内容之一的错误消息:

  • “错误: 用户 arn:aws:redshift:us-west-2:account-id:dbuser:cluster-identifier/dbuser 用户名无权代入 IAM 角色 arn:aws:iam::account-id:role/Role name”
  • “[Amazon](500310) 操作无效: S3ServiceException:Access Denied,Status 403,Error AccessDenied,”
  • “错误: S3 上指定的卸载目标不为空。考虑使用不同的存储桶/前缀,手动删除 S3 中的目标文件,或使用 ALLOWOVERWRITE 选项。”

要解决此问题,请根据您收到的错误消息执行以下操作之一:

  • 授权数据库代入 AWS Identity and Access Management (IAM) 角色。
  • 向您的 Amazon S3 操作授予适当的权限。
  • 移除或覆盖目标存储桶中的对象。更改 S3 密钥前缀。或者,使用其他存储桶。

解决方法

授权数据库代入 IAM 角色

要解决此问题,请将 IAM 角色与您的 Amazon Redshift 集群关联。在 UNLOAD 命令中包含 IAM 角色时,请确保尾部没有空格。此外,请确保为分配给 Amazon Redshift 集群的 IAM 角色使用正确的信任关系。

向您的 Amazon S3 操作授予适当的权限

如果您从 S3 存储桶收到 403 Access Denied(403 访问被拒绝)错误,请向您的 S3 API 操作授予适当的权限。

策略示例:

{
"Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:Get*",       
        "s3:List*",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::your_bucket",
        "arn:aws:s3:::your_bucket/*"
      ]
    }
  ]
}

如果您使用服务器端加密和 Amazon S3 托管加密密钥 (SSE-S3),则您的 S3 存储桶会使用唯一密钥对每个对象进行加密。

要加密已卸载的静态数据,请运行以下命令将 S3 存储桶策略中的 s3:x-amz-server-side-encryption 参数设置为 true

"Condition": {   "Null": {
           "s3:x-amz-server-side-encryption": "true"
           }

运行以下命令以确认您对 KMS_KEY_ID 进行了加密,以便您可以将加密的数据卸载到 S3 存储桶:

unload ('select * from a') to 's3://mybucket/test/varchar/' iam_role 'arn:aws:iam::xxxxxx:role/RedshiftS3Access' ALLOWOVERWRITE CSV
KMS_KEY_ID '11111111111111111111111111'
encrypted;

对于您使用 AWS Key Management Service (AWS KMS) 根密钥加密的 S3 存储桶,添加以下 IAM 策略权限:

"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]

解决存储桶问题

当您尝试卸载存在相同文件名的文件夹中的文件时,您会收到一条错误消息。

要解决此问题,请执行以下操作之一:

  • 创建新的 S3 存储桶或使用不同的 S3 存储桶。
  • 更改 S3 密钥前缀。
  • 移除目标 S3 存储桶中的文件。
  • UNLOAD 命令中包含 ALLOWOVERWRITE 选项。

创建新的 S3 存储桶或使用不同的 S3 存储桶

  1. 创建新的 S3 存储桶,或选择不同的 S3 存储桶。
  2. 更新新的或不同 S3 存储桶的存储桶策略,以包括以下权限:
{
    "Version": "2012-10-17",
    "Id": "ExamplePolicy01",
    "Statement": [
        {
            "Sid": "ExampleStatement01",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::0123456789:user/<UserName>"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::testbucket/*",
                "arn:aws:s3:::testbucket",
                "arn:aws:s3:::testbucket2/*",  --> Additional permission for new bucket
                "arn:aws:s3:::testbucket2"       
            ]
        }
    ]
}

3.在 UNLOAD 命令中使用新的存储桶路径。
命令示例:

unload ('select * from test_unload')   
to 's3://testbucket2/unload/test_unload_file1'
iam_role 'arn:aws:iam::0123456789:role/redshift_role';

更改 S3 密钥前缀

运行 UNLOAD 命令时,更改 S3 路径中的 S3 存储桶密钥前缀。

包含 unload2 作为更改前缀的命令示例:

unload ('select * from test_unload')   
to 's3://testbucket/unload2/test_unload_file1'
iam_role 'arn:aws:iam::0123456789:role/redshift_role';

有关详细信息,请参阅使用前缀组织对象

移除目标 S3 存储桶中的文件

**重要事项:**当您使用 CLEANPATH 选项移除文件时,将永久删除文件并且无法恢复它们。此外,如果您指定 ALLOWOVERWRITE 选项,则无法指定 CLEANPATH 选项。

要使用 CLEANPATH 选项,您必须拥有 S3 存储桶上的 s3:DeleteObject 权限。

权限策略示例:

{
    "Version": "2012-10-17",
    "Id": "ExamplePolicy01",
    "Statement": [
        {
            "Sid": "ExampleStatement01",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::0123456789:user/<UserName>"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetBucketLocation",
                "s3:ListBucket",
                "s3:DeleteObject"  --> Additional Action added for delete object
            ],
            "Resource": [
                "arn:aws:s3:::testbucket/*",
                "arn:aws:s3:::testbucket"
            ]
        }
    ]
}

要仅从分区文件夹中移除现有文件,请包含 PARTITION BY

包含 CLEANPATHPARTITION BYUNLOAD 命令示例:

unload ('select * from test_unload')  
to 's3://testbucket/unload/test_unload_file1
iam_role 'arn:aws:iam::0123456789:role/redshift_role'
partition by (col1,col2) include
CLEANPATH;

**注意:**如果您不想从卸载的文件中移除分区列,请使用 INCLUDE 选项指定 PARTITION BY

使用 ALLOWOVERWRITE 选项

如果 UNLOAD 命令发现可能覆盖的文件,则卸载操作将失败。当您在命令中包含 ALLOWOVERWRITE 时,UNLOAD 会覆盖现有文件,包括清单文件。

要使用 ALLOWOVERWRITE 选项,您必须拥有 S3 存储桶上的 s3:PutObject 权限。

权限策略示例:

{
    "Version": "2012-10-17",
    "Id": "ExamplePolicy01",
    "Statement": [
        {
            "Sid": "ExampleStatement01",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::0123456789:user/<UserName>"
            },
            "Action": [
                "s3:GetObject",
                "s3:GetBucketLocation",
                "s3:ListBucket",
                "s3:PutObject"  --> Additional Action added for overwriting objects
            ],
            "Resource": [
                "arn:aws:s3:::testbucket/*",
                "arn:aws:s3:::testbucket"
            ]
        }
    ]
}

包含 ALLOWOVERWRITE 选项的 UNLOAD 命令示例:

unload ('select * from test_unload')   
to 's3://testbucket/unload/test_unload_file1
iam_role 'arn:aws:iam::0123456789:role/redshift_role' allowoverwrite;

相关信息

授权 Amazon Redshift 代表您访问 AWS 服务

如何防止将未加密的对象上传到 Amazon S3

查询似乎挂起,有时无法到达集群

卸载加密的数据文件

Amazon S3 中的策略和权限

AWS 官方已更新 9 个月前