![](/img/trans.png)
[英]AWS - S3 to RDS(postgres) import using aws_s3 extension (provided by RDS) is failing
[英]Import Postgres data into RDS using S3 and aws_s3
我很难将数据从 S3 导入 RDS postgres 实例。 根据文档,您可以使用以下语法:
aws_s3.table_import_from_s3 (
table_name text,
column_list text,
options text,
bucket text,
file_path text,
region text,
access_key text,
secret_key text,
session_token text
)
因此,在 pgAdmin 中,我这样做了:
SELECT aws_s3.table_import_from_s3(
'contacts_1',
'firstname,lastname,imported',
'(format csv)',
'com.foo.mybucket',
'mydir/subdir/myfile.csv',
'us-east-2',
'AKIAYYXUMxxxxxxxxxxx',
'3zB4S5jb1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
);
我还尝试使用明确的 NULL 作为最后一个参数。
我得到的错误信息是:
NOTICE: CURL error code: 51 when attempting to validate pre-signed URL, 1 attempt(s) remaining
NOTICE: CURL error code: 51 when attempting to validate pre-signed URL, 0 attempt(s) remaining
ERROR: Unable to generate pre-signed url, look at engine log for details.
SQL state: XX000
我检查了服务器日志,没有进一步的信息。
我已经三重检查了所有参数的正确性。 我该如何进行这项工作?
更新:
我可以确认我可以使用这些相同的凭据在 Java aws sdk 中执行 s3.getObject()。
这里的主要问题是您需要 1) 将 IAM 角色添加到 RDS 实例以访问 S3 存储桶,2) 将 S3 终端节点添加到运行 RDS 实例的 VPC 以允许通信。
这是我遵循使其工作的过程,在 shell 中使用 AWS cli 命令(正确处理所涉及的环境变量的值),希望它可以提供帮助:
$ aws iam create-role \
--role-name $ROLE_NAME \
--assume-role-policy-document '{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Principal": {"Service": "rds.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'
$ aws iam create-policy \
--policy-name $POLICY_NAME \
--policy-document '{"Version": "2012-10-17", "Statement": [{"Sid": "s3import", "Action": ["s3:GetObject", "s3:ListBucket"], "Effect": "Allow", "Resource": ["arn:aws:s3:::${BUCKET_NAME}", "arn:aws:s3:::${BUCKET_NAME}/*"]}]}'
$ aws iam attach-role-policy \
--policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/$POLICY_NAME \
--role-name $ROLE_NAME
$ aws rds add-role-to-db-instance \
--db-instance-identifier $RDS_INSTANCE_NAME \
--feature-name s3Import \
--role-arn arn:aws:iam::$AWS_ACCOUNT_ID:role/$ROLE_NAME \
--region $REGION
$ aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--service-name com.amazonaws.$REGION.s3
--route-table-ids $ROUTE_TABLE_ID
可以通过命令获取与创建端点的VPC相关的路由表id
$ aws ec2 describe-route-tables | jq -r '.RouteTables[] | "\(.VpcId) \(.RouteTableId)"'
目前(2020-10-16)至少使用 RDS Postgres 12.4,如果文件不在 S3 存储桶的根目录中,则无法从 S3 导入文件。
导入文件myfile.csv
有效,导入文件mydir/subdir/myfile.csv
无效。 如果权限和其他一切正常,后者将给出这些类型的错误:
[XX000] ERROR: HTTP 403. Permission denied. Check bucket or provided credentials as they may no longer be valid.
这是 AWS 已知的问题,根据 AWS Support,他们正在解决这个问题。
此外,您似乎需要在添加文档中描述的角色后重新启动 RDS 实例。 否则角色没有任何作用。 文档中没有提到需要重新启动。
一般来说,RDS s3Import 会给出非常混乱的错误消息。 例如,导入长度为 0 的文件,会出现以下错误:
[Amazon](500310) Invalid operation: HTTP 416. Check your arguments and try again.;
为了重现您的情况,我执行了以下操作:
s3import
分配了AmazonRDSServiceRolePolicy
SELECT aws_s3.table_import_from_s3()
命令(如上)加载数据它对我来说很好。
鉴于您的错误消息与预签名的 URL 相关,这表明您提供的凭据无权访问 S3 中的 CSV 文件。 但是,您随后说您已成功使用这些凭据检索 object。 因此,这不太可能是原因。
基于Reddit:使用 RDS s3Import 功能从 S3 导入 AWS RDS Postgres 11+ 时遇到问题: aws ,该问题可能与Amazon RDS 实例无法访问 Amazon S3的事实有关。 这可能是因为它位于 VPC 中没有 NAT 网关的私有子网中。 如果是这种情况,那么您可以添加一个 NAT 网关以提供 Internet 连接,或者如链接中所述,为 S3 添加一个 VPC 端点。
该帖子中的另一条评论报告了安全组中缺少出站规则的相同问题,该规则阻止了 RDS 实例访问 Amazon S3。
检查您的 RDS 和 S3 是否在同一区域。 我遇到了同样的问题,并使用我的 Aurora RDS 同一区域中的存储桶修复了它。
在私有子网下部署生产集群时,我解决了同样的问题。
请检查您的集群安全组的出站(我的情况)
并且还将 rds-import-role 添加到“管理 IAM 角色”中,select 功能是 s3import
我希望它有所帮助。
我遇到过同样的问题。
ERROR: Unable to generate pre-signed url, look at engine log for details
该问题与错误有关:
:LOG: S3 bucket names with a period (.) are not supported
就我而言,问题的根本原因是.
(点)在存储桶的名称中。
假设您已正确配置所有内容,此问题的一个原因可能是网络 ACL。 确保有明确允许 DB 和 S3 之间连接的 NACL 规则。
在我们的案例中,我们使用terraform-aws-modules/vpc/aws
模块进行 VPC 配置,它提供了广泛的 VPC 配置,包括 NACL。 在 AWS 控制台中手动检查生成的配置后,我们发现提供给模块的配置生成的规则过于严格。 这没有反映在任何错误消息中,因为从 RDS 到 S3 的请求只是在网络级别被阻止。
有类似的问题,私有子网中的 Postgres
使用 S3 的 VPC 端点解决了这个问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.