Redshift COPY 无法从 S3 读取 tar.gz。错误代码 1216。缺少换行符:在位置 1 发现意外字符 0x2f

Posted

技术标签:

【中文标题】Redshift COPY 无法从 S3 读取 tar.gz。错误代码 1216。缺少换行符:在位置 1 发现意外字符 0x2f【英文标题】:Redshift COPY failing to read tar.gz from S3. Error code 1216. Missing newline: Unexpected character 0x2f found at location 1 【发布时间】:2015-07-22 11:35:34 【问题描述】:

tar --list

当我列出 tar.gz 文件的内容时,我得到以下信息:

$ tar --list --verbose --file /tmp/tmp.tar.gz | head -5
drwxrwxr-x user/user     0 2015-07-22 19:51 ./
-rw-rw-r-- user/user 113376 2015-07-13 06:29 ./NASDAQ_20140324.txt
-rw-rw-r-- user/user 116101 2015-07-13 06:29 ./NASDAQ_20140602.txt
-rw-rw-r-- user/user 120710 2015-07-13 06:30 ./NASDAQ_20140822.txt
-rw-rw-r-- user/user 123969 2015-07-13 06:31 ./NASDAQ_20141104.txt

zcat

当我zcat 我得到的文件时:

$ zcat /tmp/tmp.tar.gz | head -5
./0000775000175000017500000000000012553663674010514 5ustar  useruser./NASDAQ_20140324.txt0000664000175000017500000033534012550547030013173 0ustar  useruserAAIT,D,20140324,31.1,31.29,30.97,31.11,14600
AAL,D,20140324,36.25,36.86,36.03,36.8,6514500
AAME,D,20140324,3.71,3.75,3.71,3.73,5900
AAOI,D,20140324,25.76,26.15,24.84,25.81,213300
AAON,D,20140324,19.2267,19.2933,18.8667,19.1667,149700

stl_load_errors

stl_load_errors(仅列出相关列)对于在s3://<bucket>/<key> 中找到的<files> 的问题是:

filename        =>  <file>.tar.gz
line_number     =>  1
colname         =>  (empty)
type            =>  (empty)
col_length      =>  (empty)
position        =>  0
raw_line        =>  ./
raw_field_value =>  (empty)
err_code        =>  1216
err_reason      =>  Missing newline: Unexpected character 0x2f found at location 1

进一步分解:

error_code1216 是 Invalid input line. error_reason0x2f 这是 forward slash UTF-8 character

注意:在line_number = 1,在0position 上, raw_line./,除了句号(.)是转发 error_reason中提到的斜线字符

这似乎与zcat 输出提供的内容一致,它的第一行格式错误。这是否是红鲱鱼,我不知道。


但等等,还有更多……

文本文件最初是压缩的,所以我转换了 zip 存档 以这种方式将文件放入tar.gz归档文件中...

    zip 文件被unziped 到一个临时目录中 临时目录中的文本文件被转换 2.1。 sed 从文件中删除标题行并通过管道传输到 ... 2.2. awk 在输出前添加一列并保存到临时文本文件 2.3. mv 只是将临时文件重命名为临时工作目录中的原始文件名 tar.gz 文件是从转换后的临时文件创建的

1.

unzip -q "$in_archive_file_path" -d "$tmp_working_dir"

2.

for in_file_path in `find "$tmp_working_dir" -type f -iname "*_????????.txt" | sort -n`;
do  
    sed -e "1/^$quote_header_mask/d;" "$in_file_path" |
    awk -v in_var="$exchange" 'print in_var,$0' OFS=, > "$tmp_working_dir/tmp.txt"
    mv -f "$tmp_working_dir/tmp.txt" "$in_file_path"
done

quote_header_mask="&lt;ticker&gt;,&lt;date&gt;,&lt;open&gt;,&lt;high&gt;,&lt;low&gt;,&lt;close&gt;,&lt;vol&gt;"

3.

tar c -C "$tmp_working_dir/" . | pigz --best -p4 > "$working_dir/tmp.tar.gz"
mv -f "$working_dir/tmp.tar.gz" "$out_file_path"

working_dirtmp_working_dir 的父级


复制

copy source.quote_daily
(
    exchange_code
    ,ticker_code    
    ,date_key_local
    ,price_open     
    ,price_high     
    ,price_low      
    ,price_close    
    ,volume
)
from 's3://<bucket>/<key>' 
credentials 'aws_access_key_id=<key value>;aws_secret_access_key=<secret key value>' 
delimiter  ','
gzip
trimblanks
compupdate off
statupdate off
;   

问题

    zcat 是否为我指明了在解压缩存档时 Redshift 将“看到”的内容的正确方向...? ...这可能意味着我的tar.gz 创建脚本搞砸了?

【问题讨论】:

【参考方案1】:

我认为 Redshift 不支持为 COPY 命令导入归档文件 (tar)。您应该使用 gzip 格式压缩每个文件并将它们上传到 s3。 s3上的文件应该是这样的。

s3://<bucket>/<key>/XXXXX.gz
s3://<bucket>/<key>/YYYYY.gz
...

您可以使用单个 COPY 命令复制所有 gz 文件,方法是指定目录路径,如 from 's3://&lt;bucket&gt;/&lt;key&gt;/'

【讨论】:

这是不正确的。我过去曾成功使用 COPY 命令导入 tar.gz 文件。 我再次在我的环境中进行了测试,但无法将 tar 文件(非 gzip)正确复制到 Redshift。 COPY 似乎只是将指定的文件视为单个文件数据,因此您可能会复制 tar 文件数据,而不是包含文件名列表、权限等存档信息的第一行。【参考方案2】:

这是我正在处理的数据的问题。

有些文件的标题与我在第 2 部分中为变量 $quote_header_mask 设置的标题不同,因此标题行没有被删除。

这些文件进入了COPY 命令,但由于标头仍然存在而发生故障,而我的COPY 根本没有提供任何标头。

【讨论】:

以上是关于Redshift COPY 无法从 S3 读取 tar.gz。错误代码 1216。缺少换行符:在位置 1 发现意外字符 0x2f的主要内容,如果未能解决你的问题,请参考以下文章

S3 使用 COPY 到 Redshift:无法 COPY 到不存在的表中

使用多个清单文件从 S3 加载到 Redshift?

如何从 SQL 脚本执行 AWS S3 到 Redshift Copy 命令?

S3 -> Redshift 无法处理 UTF8

尝试加载 Redshift 样本,从 S3 复制时拒绝访问

如果我使用 COPY 命令将数据从 S3 加载到 Redshift,它会遵循我的 dist 样式和键吗?