AWS RDS Aurora PostgreSQL通过S3扩展导出/导入160GB大表的问题排查及最优方案咨询
背景
我花了不少时间研究PostgreSQL的AWS S3扩展细节,包括扩展配置、角色、策略以及函数输入参数这些内容,目的是能便捷地导出导入大表,用来测试索引、生成列、分区等优化数据库性能的功能。选择这个扩展主要是想避开本地中转的方式——比如下面这种操作,不仅会产生大量网络IO,还容易因为慢网络、操作系统中断连接导致管道破裂这类大表相关的问题:
# 将S3中的CSV存储到本地 aws s3 cp s3://my_bucket/my_sub_path/my_file.csv /my_local_directory/my_file.csv # 从本地CSV导入到AWS RDS Aurora PostgreSQL psql -h my_rds.amazonaws.com -U my_username -d my_dbname -c '\COPY table FROM ''my_file.csv'' CSV HEADER'
导出情况:分块文件的疑惑
我已经成功把一个160GB的大表导出成CSV文件存到S3了,用的命令是:
SELECT * from aws_s3.query_export_to_s3( 'SELECT * FROM my_schema.my_large_table', aws_commons.create_s3_uri( 'my_bucket/my_subpath', 'my_file.csv', 'eu-central-1' ), options:='format csv' );
但导出后在S3里生成了多个分块文件:第一个是my_file.csv,剩下的是my_file.csv_part2到my_file.csv_part20这类命名的文件。我不确定这种分块存储是不是合理的,也不知道能不能配置成直接导出单个160GB的CSV文件。
导入遇到的报错与问题
在导入环节,我尝试用PL/pgSQL循环导入所有分块文件,但在字符串格式化S3路径这些细节上碰了壁,还出现了好几种错误(包括导出和导入阶段的)。单个文件导入大概要20分钟,排查错误特别繁琐。
导入代码
DO $$ DECLARE my_csv_s3_sub_path text; BEGIN FOR cnt IN 2..26 LOOP my_csv_s3_sub_path := 'my_subpath/my_file.csv_part' || cnt; RAISE NOTICE '% START loading CSV file % from S3', now(), cnt; SELECT aws_s3.table_import_from_s3( 'my_schema.my_large_table_new', '', '(format csv)', aws_commons.create_s3_uri( 'my_bucket', my_csv_s3_sub_path, 'eu-central-1' ) ); RAISE NOTICE '% STOP loading CSV file % from S3', now(), cnt; END LOOP; END; $$
报错信息
首先是这个语法错误:
SQL Error [42601]: ERROR: query has no destination for result data
Hint: If you want to discard the results of a SELECT, use PERFORM instead.
Where: PL/pgSQL function inline_code_block line 8 at SQL statement
我觉得这个错误和变量、字符串插值有关,因为我需要动态生成S3里的CSV文件名给PostgreSQL AWS扩展用。另外之前还遇到过因为S3存储桶子路径语法不一致导致的HTTP 400错误:
SQL Error [XX000]: ERROR: HTTP 400. Check your arguments and try again.
Where: SQL function "table_import_from_s3" statement 1
我的疑问
- 上面的导入代码到底哪里出问题了?
- 处理160GB级别的大表,有没有更优的导出/导入方案?
- 导出时生成分块文件是合理的吗?能不能配置成导出单个完整的160GB CSV文件?
内容的提问来源于stack exchange,提问作者TPPZ




