AWS Database Migration Service データ移行時におけるエラーレコードの特定方法

こんにちは。
Fusic Advent Calendar 2017 2日目は 若干ニッチなお話をさせていただきます。


# AWS Database Migration Service とは

AWS Database Migration Service (AWS DMS) は、Oracle、PostgreSQL、Microsoft SQL Server、Amazon Redshift、Amazon Aurora、MariaDB、MySQL など、幅広く使用されている商用およびオープンソースデータベースとの間でデータを移行できます。このサービスでは、Oracle から Oracle など、同機種間の移行をサポートしているほか、Oracle から MySQL、MySQL から Amazon Aurora など、異なるデータベースプラットフォーム間の異機種の移行もサポートしています。
※ [AWSユーザーガイド](http://docs.aws.amazon.com/ja_jp/dms/latest/userguide/Welcome.html)より抜粋


今回は DMS を使用した初期データ移行時に、
エラーが発生した際の、原因の特定方法を紹介します。


# エラーが発生したテーブルのみを指定してタスクを実行

当たり前のことなのですが、
エラーが発生した際は、対象のテーブルのみを指定してタスクを作成・実行してみましょう。
その際、ロギングの有効化は忘れずに。
※ CloudWatch にログが出力されます。

実行後、CloudWatchログを確認してみてください。

### エラー部分のログの例

```
2017-12-01T10:44:43 [TARGET_LOAD     ]E: Failed to wait for previous run (csv_target.c:937)
2017-12-01T10:44:43 [TARGET_LOAD     ]E: Failed to start load process for file '2' [1020403] (csv_target.c:1300)
2017-12-01T10:44:43 [TARGET_LOAD     ]E: Failed to load file '2' [1020403] (csv_target.c:1407)
2017-12-01T10:44:43 [TASK_MANAGER    ]W: Table 'db_name'.'table_name' (subtask 1 thread 1) is suspended (replicationtask.c:2094)
2017-12-01T10:44:43 [TARGET_LOAD     ]E: Failed to load data from csv file. [1020403] (odbc_endpoint_imp.c:5233)

```


- エラーが特定出来た → おしまい
- エラーが特定出来ない → 次へ進む


# タスクのログレベルを上げる

エラーの原因となっている コンポーネントアクティビティ （↑の例だと TARGET_LOAD ） のログレベルを

- LOGGER_SEVERITY_DEBUG

もしくは

- LOGGER_SEVERITY_DETAILED_DEBUG

に設定します。

参照） [AWS Database Migration Service ユーザーガイド](http://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_Tasks.CustomizingTasks.TaskSettings.Logging.html)

なお、ログレベルの変更は 2017/12/2 現在 Management Console からは行うことが出来ません。
AWS CLI より、

1. aws dms describe-replication-tasks で タスク の情報を抽出
1. ↑の情報から ReplicationTaskSettings.Logging.LogComponents の対象となる コンポーネントアクティビティ のログレベルを変更したタスクを複製

といった流れで別タスクを作成します。
別タスクを実行後、CloudWatchログを確認してみてください。

### エラー部分のログの例

```
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Going to load file '/rdsdbdata/data/tasks/HU2DPNPG5RNCUJDBZPZZYTI5J4/data_files/1/LOAD00000002.csv'  (csv_target.c:1285)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Load data command. Path: , Exe name: psql, Exe params: -h rds_name.ccsis9ijpw43.ap-northeast-1.rds.amazonaws.com -p 5432 -U ***** -w -d db_name -c """\\copy \""db_name\"".\""table_name\"" from '/rdsdbdata/data/tasks/HU2DPNPG5RNCUJDBZPZZYTI5J4/data_files/1/LOAD00000002.csv' WITH DELIMITER ',' CSV NULL 'attNULL' ESCAPE '\\'"""  (provider_syntax_manager.c:2595)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Before wait for command  (csv_target.c:827)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  wait for load command process returned status '10'  (csv_target.c:839)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Load command output: psql: /usr/lib64/libcom_err.so.2: no version information available (required by /rdsdbbin/attunity-2.3.0.R1/lib/libgssapi_krb5.so.2), psql: /usr/lib64/libcom_err.so.2: no version information available (required by /rdsdbbin/attunity-2.3.0.R1/lib/libkrb5.so.3), ERROR:  date/time field value out of range: "0000-00-00 00:00:00", CONTEXT:  COPY table_name, line 83299, column deleted: "0000-00-00 00:00:00"  (csv_target.c:895)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Failed to wait for previous run  (csv_target.c:937)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Failed to start load process for file '2' [1020403]  (csv_target.c:1300)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Failed to load file '2' [1020403]  (csv_target.c:1407)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Failed to load data from csv file. [1020403]  (odbc_endpoint_imp.c:5233)
2017-12-01T11:03:24 [TARGET_LOAD     ]D:  Handling End of table 'db_name'.'table_name' loading failed by subtask 1 thread 1 [1020403]  (endpointshell.c:2147)
2017-12-01T11:03:24 [TARGET_LOAD     ]E:  Failed to wait for previous run  (csv_target.c:937)
2017-12-01T11:03:24 [TARGET_LOAD     ]E:  Failed to start load process for file '2' [1020403]  (csv_target.c:1300)
2017-12-01T11:03:24 [TARGET_LOAD     ]E:  Failed to load file '2' [1020403]  (csv_target.c:1407)
2017-12-01T11:03:24 [TASK_MANAGER    ]W:  Table 'db_name'.'table_name' (subtask 1 thread 1) is suspended  (replicationtask.c:2094)
2017-12-01T11:03:24 [TARGET_LOAD     ]E:  Failed to load data from csv file. [1020403]  (odbc_endpoint_imp.c:5233)
```

※↑の例だと5行目にエラーの原因が出力されていますね


- エラーが特定出来た → おしまい
- エラーが特定出来ない → 次へ進む


# S3 に出力したファイルを見て実際のレコードを特定する

ターゲットエンドポイントをS3に指定したタスクを作成し、実行します。
前述のエラーの例の場合、83299行目にエラーが発生しています。（line 83299）
S3に出力されたファイルを確認することで、
エラーが発生したレコードを特定することが可能です。

- エラーが特定出来た → おしまい
- エラーが特定出来ない → 次へ進む


# サポートに問い合わせる

ターゲットエンドポイントの "追加の接続属性" に「keepCSVFiles=true;keepErrorFiles=true」を設定し、
タスク実行時にレプリケーションインスタンス上に、一時的に保存される移行対象テーブルのデータを、
永続的に保存するようにします。
ただ、2017/12/2 現在では、レプリケーションインスタンスには、
AWSの中の人しかログイン出来ません。
設定後、タスクを再実行し、移行対象テーブルのデータを保存したら、
AWSサポートに問合せてみましょう。


ここまでやったらエラーは特定できてる！…はず

明日のAdvent Calendarは Fusicの核弾頭 @Junkins です。
皆様、お楽しみに！