【问题标题】:Redshift COPY failing to read tar.gz from S3. Error code 1216. Missing newline: Unexpected character 0x2f found at location 1Redshift COPY 无法从 S3 读取 tar.gz。错误代码 1216。缺少换行符:在位置 1 发现意外字符 0x2f
【发布时间】: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

进一步分解:

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

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


但等等,还有更多……

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

  1. zip 文件被unziped 到一个临时目录中
  2. 临时目录中的文本文件被转换
    2.1。 sed 从文件中删除标题行并通过管道传输到 ...
    2.2. awk 在输出前添加一列并保存到临时文本文件
    2.3. mv 只是将临时文件重命名为临时工作目录中的原始文件名
  3. 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
;   

问题

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

【问题讨论】:

    标签: bash awk sed amazon-redshift


    【解决方案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 根本没有提供任何标头。

    【讨论】:

      猜你喜欢
      • 2014-09-08
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 1970-01-01
      • 2017-06-26
      • 2017-10-31
      • 2020-01-15
      • 1970-01-01
      相关资源
      最近更新 更多