【发布时间】:2013-12-17 21:39:55
【问题描述】:
我想将一个表从 Amazon RedShift 迁移到 MySQL,但是使用“卸载”会生成多个难以直接导入 MySQL 的数据文件。
有没有办法将表卸载到单个 CSV 文件中,以便我可以直接将其导入 MySQL?
【问题讨论】:
-
我对@987654321@ 的回答应该适合你
标签: mysql amazon-web-services amazon-redshift
我想将一个表从 Amazon RedShift 迁移到 MySQL,但是使用“卸载”会生成多个难以直接导入 MySQL 的数据文件。
有没有办法将表卸载到单个 CSV 文件中,以便我可以直接将其导入 MySQL?
【问题讨论】:
标签: mysql amazon-web-services amazon-redshift
当然,没有办法强制 Redshift 只生成一个输出文件。
在标准 UNLOAD 下,您将创建与系统切片数量相等的输出文件,即具有 8 个切片的系统将为单个卸载命令创建 8 个文件(这是最快的卸载方法。)
如果您在卸载命令中添加子句 PARALLEL OFF,您的输出将创建为单个文件,直到数据提取大小不超过 6.25GB,之后 Redshift 会自动将文件拆分为一个新的块。
如果您也生成压缩的输出文件,情况也是如此(当然,考虑到您的文件可以容纳更多的记录,您将有更大的机会生成单个输出文件。)。
【讨论】:
在这一点上这是一个老问题,但我觉得所有现有的答案都有点误导。如果您的问题是“我可以绝对 100% 保证 Redshift 将始终卸载到 S3 中的单个文件吗?”,答案很简单否。
话虽如此,在大多数情况下,您通常可以限制查询,使您最终得到一个文件。根据文档 (https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html),限制生成的文件数量的主要因素是导出的实际原始大小(以字节为单位)(不是行数)。 Redshift UNLOAD 命令生成的输出文件大小限制为 6.2GB。
因此,如果您想确保从 UNLOAD 获得单个输出文件,您应该尝试以下方法:
PARALLEL OFF。 Parallel 默认为“ON”,通常会写入多个文件,除非您有一个很小的集群(设置“PARALLEL ON”的输出文件的数量与集群中的切片数量成正比)。 PARALLEL OFF 会将文件串行写入 S3 而不是并行写入,并且只有在超出大小限制时才会溢出到使用多个文件。WHERE 子句或使用LIMIT 子句来减少记录数。不幸的是,这些技术都不是完美的,因为行可以是可变大小的。我也不清楚GZIP 选项是否会影响输出文件大小溢出限制(不清楚 6.2GB 是 GZIP 之前的大小限制还是 GZIP 之后的大小限制)。对我来说,在大多数情况下最终生成单个 CSV 文件的 UNLOAD 命令是:
UNLOAD
('SELECT <fields> FROM <table> WHERE <restrict_query>')
TO 's3://<bucket_name>/<filename_prefix>'
CREDENTIALS 'aws_access_key_id=<access_key>;aws_secret_access_key=<secret_key>'
DELIMITER AS ','
ADDQUOTES
NULL AS ''
PARALLEL OFF;
PARALLEL OFF 的另一个不错的副作用是,它会尊重您的 ORDER BY 子句,如果您有一个子句,并按照使所有记录保持有序的顺序生成文件,即使跨多个输出文件也是如此。
附录:似乎有一些关于使用 LIMIT 2147483647 强制领导节点进行所有处理并生成单个输出文件的民间知识,但这似乎并没有在 Redshift 文档的任何地方实际记录,并且因此,依赖它似乎是个坏主意,因为它随时可能发生变化。
【讨论】:
为了发送到单个文件,请使用并行关闭
unload ('select * from venue')
to 's3://mybucket/tickit/unload/venue_' credentials
'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>'
parallel off;
我还建议使用 Gzip,以使下载的文件更小。
unload ('select * from venue')
to 's3://mybucket/tickit/unload/venue_' credentials
'aws_access_key_id=<access-key-id>;aws_secret_access_key=<secret-access-key>'
parallel off
gzip;
【讨论】:
不。 {你可以use a manifest and tell Redshift to direct all output to a single file.} 以前的答案是错误的,我使用清单进行加载而不是卸载。
似乎有两种可能的方式来获取单个文件:
cat utility to join the files togethercat File1.txt File2.txt > union.txt。这将要求您首先从 S3 下载文件。【讨论】:
这是一种解决方法,但您需要将查询设为子查询并包含限制。然后它将输出到一个文件。例如
select * from (select * from bizdata LIMIT 2147483647);
所以基本上你是从有限的集合中选择所有的。这是它工作的唯一方式。 2147483647 是您的最大限制,因为限制子句采用无符号整数参数。
所以以下内容将卸载到一个文件中:
unload(' select * from (
select bizid, data
from biztable
limit 2147483647);
') to 's3://.......' CREDENTIALS 'aws_access_key_id=<<aws_access_key_id>>;aws_secret_access_key=<<aws_secret_access_key>>' csv ;
【讨论】: