■ はじめに
https://dk521123.hatenablog.com/entry/2021/09/01/200818
において、Hiveテーブルデータ を Redshift に移行する際に COPYコマンドにおいていくつかトラブルが発生したので まとめておく。
目次
【1】COPYコマンド時にエラー「Forbidden: HTTP response error code 403」が発生 【2】COPYコマンド時にエラー「Check 'stl_load_errors' system table for details.」が発生
【1】COPYコマンド時にエラー「Forbidden: HTTP response error code 403」が発生
https://dk521123.hatenablog.com/entry/2021/09/01/200818
で行ったHiveテーブルデータ を Redshift に移行において、 Hive/Redshiftを以下のように行ったら、以下の「1)エラー内容」が発生した。
[現象発生時] Hive Part
CRATE EXTERNAL TABLE sample_table( id STRING, name STRING, col1 STRING, col2 STRING, created_at TIMESTAMP ) STORED AS PARQUET TBLPROPERTIES("parquet.compression"="SNAPPY") LOCATION 's3://your-s3-bucket/xxxx/sample_db/sample_table/' ;
[現象発生時] Redshift part : COPYコマンド
COPY redshift_db_name.redshift_sample_table FROM 's3://your-s3-bucket/xxxx/sample_db/sample_table/' iam_role 'arn:aws:iam::XXXXXXXXXXX:role/for-redshift-role' parquet REGION 'us-west-2';
1)エラー内容
ERROR: Spectrum Scan Error DETAIL: ----------------------------------------------- error: Spectrum Scan Error code: 15007 context: Forbidden: HTTP response error code 403 Message: AccessDenied Access Denied x-amz-request-id: xxxx x-amz-id-2: xxxx query: xxxxxx location: dory_util.cpp:1136 process: worker_thread [pid=xxxx] ----------------------------------------------
2)原因
S3の権限エラーっぽいけど、 Hive の Parquet と Redshift の Parquet で相性が悪いから??
補足1:権限問題の調査について
まずは、以下の2点を確認した方がいい。 ~~~~~~~ 1)COPYコマンドに付与している IAM role の権限の確認 2)COPY元のS3のバケットのアクセス権限の確認 ~~~~~~~ そして、公式サイトの「S3ServiceException エラー」を頼りに、 ロール問題かどうかを詳細に調査した方がいいと思う。
https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/s3serviceexception-error.html
補足2:調査メモ
以下のようにディレクトリ構成でファイルができていた。 ~~~~~~ s3://your-s3-bucket/xxxx/sample_db/sample_table/ 1/xxxx 2/xxxx ~~~~~~ そこでものは試しに、手動で、以下のように構成変更して 色々試したけど、同じエラーになってしまった。。。 ~~~~~~ [変更後] s3://your-s3-bucket/xxxx/sample_db/sample_table/ xxxx1 xxxx2 [試したこと] [Errror] COPY ... FROM 's3://your-s3-bucket/xxxx/sample_db/sample_table/' [Errror] COPY ... FROM 's3://your-s3-bucket/xxxx/sample_db/sample_table/xxxx1' ~~~~~~
3)解決案
Hiveの保存をparquetから変更したら、エラーが解消された。 フルソースは、以下の関連記事を参照のこと。
https://dk521123.hatenablog.com/entry/2021/09/01/200818
[修正後] Hive part
-- GZIP形式で圧縮する set hive.exec.compress.output=true; set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec; CRATE EXTERNAL TABLE sample_table( id STRING, name STRING, col1 STRING, col2 STRING, created_at TIMESTAMP ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\001' STORED AS TEXTFILE LOCATION 's3://your-s3-bucket/xxxx/sample_db/sample_table/' ;
[修正後] Redshift part (COPYコマンド)
COPY redshift_db_name.redshift_sample_table FROM 's3://your-s3-bucket/xxxx/sample_db/sample_table/' iam_role 'arn:aws:iam::XXXXXXXXXXX:role/for-redshift-role' DELIMITER '\001' gzip NULL 'NULL' REGION 'us-west-2';
【2】COPYコマンド時にエラー「Check 'stl_load_errors' system table for details.」が発生
『【1】COPYコマンド時にエラー「Forbidden: HTTP response error code 403」が発生』を 実行後、別のテーブルのCOPYコマンド時に、以下「1)エラー内容」のエラーが発生した。
1)エラー内容
ERROR: Load into table 'xxxx' failed. Check 'stl_load_errors' system table for details.
2)原因
https://otiai10.hatenablog.com/entry/2015/12/22/183910
が非常に参考になった。本当にこういう記事はありがたいです、、、
原因・Case1
最終的には、データがテーブルに定義した範囲を超えていたため。 (例として、VERCHAR(100) で定義していたデータ項目に、 100文字を超えた文字列を格納しようとしていた)
原因・Case2
Integerで定義している項目に対して、 文字列「${xxxx}」を格納しようとしていたため。
3)補足:調査内容
https://otiai10.hatenablog.com/entry/2015/12/22/183910
を参照。 以下は、自分の確認した調査手順。 「String length exceeds DDL length」とあったので、 上記「2)原因」であることが突き止められた
[1] psqlでログイン
psql -U ${USER} -h ${HOST} -p ${PORT} ${DB_NAME}
[2] システムテーブル「stl_load_errors」テーブルの確認
\d stl_load_errors;
[3] エラー内容確認 / Case1
SELECT starttime, TRIM(colname), err_code, TRIM(err_reason) FROM stl_load_errors ORDER BY starttime DESC LIMIT 2; [出力結果](「String length exceeds DDL length」を確認) starttime | btrim | err_code | btrim ----------------------------+--------+----------+------------------------------------------------ 20XX-XX-XX XX:47:17.143206 | column_name | 1204 | String length exceeds DDL length 20XX-XX-XX XX:15:05.32209 | column_name | 1204 | String length exceeds DDL length (2 rows)
[3] エラー内容確認 / Case2
[出力結果](「String length exceeds DDL length」を確認) starttime | btrim | err_code | btrim ----------------------------+--------+----------+------------------------------------------------ 20XX-XX-XX XX:47:17.143206 | column_name | 1207 | Invalid digit, Value '$', Pos 0, Type: Integer 20XX-XX-XX XX:15:05.32209 | column_name | 1207 | Invalid digit, Value '$', Pos 0, Type: Integer (2 rows)
4)解決案
Case1の解決案
テーブルの定義域を拡張した。 ~~~~~~~ VERCHAR(100) => VERCHAR(200) ~~~~~~~
Case2の解決案
数字になるように元データ側を修正
関連記事
Hiveテーブルデータ を Redshift に移行するには
https://dk521123.hatenablog.com/entry/2021/09/01/200818
Amazon Redshift ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/02/22/002139
Amazon Redshift ~ COPY コマンド ~
https://dk521123.hatenablog.com/entry/2021/07/21/214248
よく使う pdqlコマンド
https://dk521123.hatenablog.com/entry/2020/01/10/224818