如何排查 Amazon Redshift 中的 UNLOAD 问题?
我正在尝试将数据从我的 Amazon Redshift 集群卸载到 Amazon Simple Storage Service (Amazon S3)。但发生了错误。如何排查此问题?
简短描述
将数据从 Amazon Redshift 集群卸载到 Amazon S3 桶时,您可能会遇到以下错误:
数据库用户无权代入 AWS Identity and Access Management(IAM)角色错误
error: User arn:aws:redshift:us-west-2:<account-id>:dbuser:<cluster-identifier>/<dbuser username> is not authorized to assume IAM Role arn:aws:iam::<account-id>:role/<Role name>
403 访问被拒绝错误
[Amazon](500310) Invalid operation: S3ServiceException:Access Denied,Status 403,Error AccessDenied,
**注意:**将数据卸载到 S3 存储桶时,请使用带 SELECT 语句的 UNLOAD 命令。以分隔格式或固定宽度格式卸载文本数据(无论加载时使用的数据格式如何)。您还可以指定是否应该归档压缩的 gzip 文件。
S3 上指定的卸载目标不为空
ERROR: Specified unload destination on S3 is not empty. Consider using a different bucket / prefix, manually removing the target files in S3, or using the ALLOWOVERWRITE option.
当您尝试运行相同的 UNLOAD 命令并在已经存在数据文件的同一个文件夹中卸载文件时,可能会发生此错误。
例如,如果您运行以下命令两次,就会出现此错误:
unload ('select * from test_unload') to 's3://testbucket/unload/test_unload_file1' iam_role 'arn:aws:iam::0123456789:role/redshift_role';
解决方法
数据库用户无权代入 AWS IAM 角色错误
如果数据库用户无权代入 IAM 角色,请检查以下内容:
- 验证 IAM 角色是否与您的 Amazon Redshift 集群相关联。
- 验证 UNLOAD 命令中使用的 IAM 角色中是否没有尾随空格。
- 验证分配给 Amazon Redshift 集群的 IAM 角色是否使用了正确的信任关系。
403 访问被拒绝错误
如果您收到来自 S3 桶的 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/*" ] } ] }
如果您将服务器端加密与 S3 托管的加密密钥结合使用,则 S3 桶会使用唯一密钥对其每个对象进行加密。作为额外的保护措施,密钥本身也使用定期轮换的根密钥进行加密。
要加密已卸载的静态数据,请验证 S3 桶策略中的 s3:x-amz-server-side-encryption 参数是否设置为“true”:
"Condition": { "Null": { "s3:x-amz-server-side-encryption": "true" }
确认 KMS_KEY_ID 已加密,以便您可以将加密的数据 UNLOAD 到 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;
如果您的 S3 桶使用 AWS Key Management Service (AWS KMS) 中的根密钥进行加密,请将以下权限添加到您的 IAM policy 中:
"Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ]
S3 上指定的卸载目标不为空
如果您尝试在存在相同文件名的文件夹中UNLOAD(卸载)文件,则会出现 S3 上指定的卸载目标不为空错误。
选择以下选项之一来解决错误消息:
- 创建新的 Amazon S3 桶或使用不同的 S3 桶
- 更改 S3 密钥前缀
- 清理目标 Amazon S3 桶中存在的文件
- 在 UNLOAD 命令中使用 ALLOWOVERWRITE 选项
创建新的 Amazon 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 命令中使用新的桶路径。在以下示例中,s3://testbucket2/unload/test_unload_file1 是新的桶路径:
iam_role 'arn:aws:iam::0123456789:role/redshift_role'; unload ('select * from test_unload') to 's3://testbucket2/unload/test_unload_file1'
更改 S3 密钥前缀
使用 UNLOAD 命令时,更改 S3 路径中的 S3 Bucket Key (桶密钥)前缀。在以下示例中,unload2 是更改后的前缀:
iam_role 'arn:aws:iam::0123456789:role/redshift_role'; unload ('select * from test_unload') to 's3://testbucket/unload2/test_unload_file1'
有关更多信息,请参阅使用前缀整理对象。
清理目标 Amazon S3 桶中存在的文件
在将文件卸载到指定位置之前,使用 CLEANPATH 选项删除位于 TO 子句中指定的 Amazon S3 路径中的现有文件。如果包含 PARTITION BY 子句,则仅从分区文件夹中删除现有文件。这允许 Amazon S3 桶接收由 UNLOAD 操作生成的新文件。
**重要提示:**使用 CLEANPATH 选项删除的文件将被永久删除且无法恢复。
要使用 CLEANPATH 选项,您必须拥有 Amazon 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" ] } ] }
**注意:**如果您指定 ALLOWOVERWRITE 选项,则无法指定 CLEANPATH 选项。
在 UNLOAD 命令中使用 ALLOWOVERWRITE 选项
如果 UNLOAD 命令找到可能被覆盖的文件,则该命令失败。如果指定了 ALLOWOVERWRITE,则 UNLOAD 会覆盖现有文件,包括清单文件。在以下示例中,之前的文件被覆盖,桶已更新新记录。
iam_role 'arn:aws:iam::0123456789:role/redshift_role' allowoverwrite; unload ('select * from test_unload') to 's3://testbucket/unload/test_unload_file1'
要使用 ALLOWOVERWRITE 选项,您必须拥有 Amazon 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" ] } ] }
相关信息
相关内容
- AWS 官方已更新 3 个月前
- AWS 官方已更新 2 年前
- AWS 官方已更新 3 年前
- AWS 官方已更新 1 年前