AWSのDMS(Data Migration Service)を使ったDB移行のために、新機能の「移行前評価(Premigration assessments)」を試してみた！

# 前提

ハピタスにはデータベースインスタンスが複数存在しています。
データベースインスタンスごとに役割がおおよそ決められており、効果的に活用できていれば
メンテナンスも部分的にできたり、負荷分散も適切に行えたり、有用な構成だったと思います。

しかしながら、長年様々なエンジニアによって改修が行われ、データベースインスタンス同士の依存関係も大きくなり、
一つのデータベースであれば単純に WEB アプリケーション上で一つのSQLで完結できたはずのものが
php を介して、SQL の問い合わせ結果を使いマージして、複雑な処理を行うため
その処理がボトルネックになってきています。メンテナンスもハピタスのインフラの歴史的な背景の理由などで複雑化しています。

そこで DMS を使って、データベースの統合を進めています。

## 元々

![Untitled Diagram-Page-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/474a443e-ba56-f4c8-e1a3-94f9b634378c.png)

## こうする


![Untitled Diagram-Page-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/009080e7-b006-82e0-e1cd-66d372bf7f66.png)

## 課題したい課題

課題は色々ありましたが、
本トピックでは 2020年7月29日の昨日にリリースされた DMS の Premigration assessments 「移行前評価」について使ってみて事前検証したので共有します。

できたての機能なので、本日 7月30日時点では New とマークがついていますね。


![スクリーンショット 2020-07-30 21.33.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/bf630777-0d3f-4599-b468-3c8111e20024.png)

使われる場合は事前に https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Tasks.AssessmentReport.html を一読してみてください。


- ソース： RDS for MySQL 5.6
- ターゲット Aurora MySQL
- フルロードおよび CDC を使う

上記の環境の場合、以下の5項目が評価対象となるようです。

- CDC またはフルロードのプライマリキーがなく、CDC タスクのみのソーステーブル
- サポートされていないデータ型
- ソーステーブルに LOB があるが、プライマリキーまたは一意の制約がない
- ターゲットテーブルに CDC タスクのみのプライマリキーがない
- ラージオブジェクト (LOB) は使用されるが、ターゲット LOB 列は null を許容しない

この評価がエラーとなっても 必ずしも問題になるわけではなく、 DMS タスクの開始はできるようです。
表示されたメッセージから扱っている環境がどういった問題が起き得るかが推測できます。
事前に テーブルの定義を一つ一つ調査していたものが自動でチェックできるので、とても便利ですね。


## 設定方法

※ 事前にレプリケーションインスタンス、エンドポイント（ソース/ターゲット）、セキュリティグループなどは作成、設定済みの前提

1. DMS 用の IAMロールを作成します
    - [ロール作成画面](https://console.aws.amazon.com/iam/home?region=ap-northeast-1#/roles$new?step=type) から DMS を選択します
    - ポリシー名を AmazonDMSRedshiftS3Role で検索してチェックをつけます
    - IAMロールの名前を設定します
2. [データ移行タスク](https://ap-northeast-1.console.aws.amazon.com/dms/v2/home?region=ap-northeast-1#CreateNewTask) からデータ移行タスクを作成します。
    - 設定をそれぞれ入力します
    - `移行前評価の実行の有効化` にチェックをいれます
    - そうすると以下のような表示がされます。不要な評価がある場合はチェックをはずし （環境が該当しないものはチェックが付いていても評価されないようです）
    - `評価レポートのストレージ` はレポートを保存する S3 のバケットとパスを指定します
    - `IAM ロール` では 1. で作成したロールを選びます
    - ちなみに `移行前評価` を有効にすると `移行タスクのスタートアップ設定` で `作成時に自動的に行う` が選べないようになっています。評価を行ってから、問題ないか判断、および問題点を改善して、実行できるようになっていると思われます

※ 移行前評価の画面
![スクリーンショット 2020-07-30 21.59.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/0f1ff374-a7d5-e037-14b4-5119878f8ac8.png)

※ `移行前評価` を有効にすると `移行タスクのスタートアップ設定` で `作成時に自動的に行う` が選べない
![スクリーンショット 2020-07-30 22.04.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/1753dffd-ab65-65f3-d7eb-cf68341d6c08.png)

以上で作成が完了です

## ハピタスのあるDBで検証してみた結果

見事に警告が2つ表示されました。

![スクリーンショット 2020-07-30 22.07.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/426b6b9b-f5ec-13a3-82bd-f554f0187100.png)

評価のリンクをクリックすると json ファイルが配置された S3 バケットのパスに遷移します。

具体的にはこんな感じで問題のあるテーブルがわかります

```bash

$ jq < table-with-no-primary-key-or-unique-constraint.json 
{
  "test-name": "table-with-no-primary-key-or-unique-constraint",
  "test-result": "warning",
  "table-results-summary": {
    "failed": 0,
    "passed": 0,
    "warning": 3
  },
  "table-results": {
    "failed": [],
    "passed": [],
    "warning": [
      {
        "schema-name": "pointback",
        "table-name": "status",
        "table-result": "warning",
        "message": "Table has no primary key or unique constraint",
        "column-data": []
      },
      {
        "schema-name": "pointback",
        "table-name": "result",
        "table-result": "warning",
        "message": "Table has no primary key or unique constraint",
        "column-data": []
      },
      {
        "schema-name": "pointback",
        "table-name": "special",
        "table-result": "warning",
        "message": "Table has no primary key or unique constraint",
        "column-data": []
      }
    ]
  }
}
$ jq < target-table-has-unique-key-or-primary-key-for-cdc.json 
{
  "test-name": "target-table-has-unique-key-or-primary-key-for-cdc",
  "test-result": "warning",
  "table-results-summary": {
    "warning": 3,
    "passed": 0,
    "failed": 0
  },
  "table-results": {
    "warning": [
      {
        "schema-name": "pointback",
        "table-name": "status",
        "table-result": "warning",
        "message": "Table is missing a primary key or unique constraint",
        "column-data": []
      },
      {
        "schema-name": "pointback",
        "table-name": "result",
        "table-result": "warning",
        "message": "Table is missing a primary key or unique constraint",
        "column-data": []
      },
      {
        "schema-name": "pointback",
        "table-name": "special",
        "table-result": "warning",
        "message": "Table is missing a primary key or unique constraint",
        "column-data": []
      }
    ],
    "passed": [],
    "failed": []
  }
}
  
```

上記について対応するべく、target の テーブルに対して、AUTOINCREMENT の プライマリーキーを設定しました
その上で再度、移行前評価を作成すると以下のような結果となりました

![スクリーンショット 2020-07-30 22.22.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/48c585d4-b4d5-46a9-2702-e88254331d3f.png)

`CDC またはフルロードのプライマリキーがなく、CDC タスクのみのソーステーブル` のみがまだ警告がでています。
ここは対応しなくて問題ないと判断しました。
なぜなら移行元のテーブルのデータは約１万レコードしかないからです。その程度のレコード数では負荷にならないと判断し、DMS を実行しました。

結果的には数分で移行は完了し、負荷の上昇はほぼ発生しませんでした。

## 使ってみた感想

オンプレから AWS の移行でも、 AWS 内のサービス移行でもこういった評価が自動でされることは個別に一つ一つチェックすることで発生する見落としを防ぐのに効果的だと思いました。
もちろん自分でチェックした場合でも、評価が自動でされる場合にも、問題点が見つかった場合にどう対処するかは各々の環境で考えなくてはいけませんが、そこだけに集中できるのはとても有用です。