AWS移行 - AWSへのDB移行方式検討とDMSによるOracleからAuroraへの移行検証

# 1. はじめに

データベースをオンプレミスからクラウドへ移行する場合、移行先DBのDBMSや構成を確定させたあとに、移行方式の検討を行います。本番移行でトラブルが起きると、計画外のサービス停止が発生して利用者に大きな影響を及ぼすリスクがありますので、安全な移行方式を選定したうえで、十分な検証を行う必要があります。

この記事では、はじめにDBの移行方式を決めるための検討ポイントを、Oracle DatabaseをAWSへ移行するケースを例にしてまとめます。次に、異種DBMS間のDB移行について、Oracle DatabaseからAuroraへの移行を例に、AWS Database Migration Service（DMS）とSchema Conversion Tool（SCT）を使った移行方式を検証したので、作業の流れや移行時の注意事項をまとめます。

なお、データベース移行の計画フェーズで検討すべきポイントについては[別記事](https://qiita.com/kenichi_matsunaga/items/fd5247f6c839ce19c097)にまとめていますので、こちらも参考にしていただければと思います。


# 2. DB移行方式の検討

## 2-1. DB移行方式の検討ポイント

DBの移行方式を検討する際、以下の2点が重要なポイントとなります。

- 移行元・移行先DBMSの差異
- サービス停止可能時間

移行元・移行先DBMSの差異については、同一DBMSであればDBMSが提供する標準移行ツールを利用する移行方式が第一候補になります。標準移行ツールは利用実績が多いので、移行リスクを低減できるでしょう。一方、移行元・移行先でDBMSが異なる場合、両方のDBMSをサポートしている有償の移行ツールを使用することになると思います。

サービス停止可能時間については、DBデータの全量コピーを含む一連の移行作業を実施している期間中、DBの更新を伴うサービスを停止していても問題ないかが判断基準になります。十分なサービス停止可能時間を確保できる場合、DBの更新がない状態にして、export/importツールなどを利用したDBデータの全量コピーによってDB移行を実施することが可能です。短時間のサービス停止時間しか許容されない場合、サービス中にDBデータの全量コピー＋差分同期（CDC, Change Data Capture）を実施して移行元・先のDBでデータを同期し、サービス停止可能になったら移行先システムへの切り替えを行います。

## 2-2. 同一DBMS間のDB移行方式

移行元・移行先のDBMSが同一の場合のDB移行について、Oracle Databaseを例に利用可能なOracle提供のツールを挙げてみます。Oralce Databaseの移行では、Data PumpのようなバックアップツールやData GuardのようなDRツールを使うケースも多いので、これらについて比較し、AWSへの移行での利用可否も記載します。

| 移行ツール | 概要・制約 | Oracle Database on EC2 <br> への移行 | RDS for Oracle <br> への移行 |
|:-|:-|:-:|:-:|
| Data Pump  | DBデータを中間ファイルへ出力（export）し、移行先DBへimportできる機能<br>OS・文字コード・Oracle Databaseバージョンが異なってもよい<br>データ移行中はDBの更新停止が必要  | 利用可能  | 利用可能  |
| DBLink  | DB間をネットワーク接続し、接続相手のデータを内部データのように扱える機能  | 利用可能  | 利用可能  |
| RMAN | Oracle Databaseのバックアップ機能で、移行先DBへリストアすることでデータ移行を実施<br>OS・文字コード・Oracle Databaseバージョンは同一であること | 利用可能  | 利用不可  |
| トランスポータブル表領域 | 表領域を構成するデータファイルをコピーすることでデータ移行を行う機能<br>文字コードは同一であること、Enterprise Editionが必要<br>データ移行中はDBの更新停止が必要 | 利用可能  | 利用不可  |
| Data Guard  | Oracle Database間でDBデータをレプリケートする、主にDR用途で使用する機能<br>OS・文字コード・Oracle Databaseバージョンが同一であること、Enterprise Editionが必要  | 利用可能  | 利用不可  |
| GoldenGate  | 異種DB間でDBデータをレプリケートする製品（Oracle Database以外のDBへの移行でも利用可能）<br>GoldenGate用の有償ライセンスが必要  | 利用可能  | 利用可能  |

## 2-3. 異種DBMS間のDB移行方式

移行元・移行先でDBMSが異なる場合、以下の2段階でDB移行を実施する必要があります。

- 移行元DBのスキーマを移行先DBMS向けに変換し、移行先DBへ適用
- 移行ツールを使用してDBデータを移行

スキーマの変換については、AWSが無償提供するSchema Conversion Tool（SCT）のような変換ツールを使用して自動変換を行います。ツールでは自動変換できないDBオブジェクトもあるので、この場合は手動変換する必要があります。手動変換が必要なDBオブジェクトの種類や量によってスキーマ変換に必要な作業量・コストは変動するので、計画フェーズでDBMS変更の可能性がある場合には変換ツールを実行して確認しておくのがよいでしょう。

変換したスキーマ定義の移行先DBへの適用については、外部キー制約のようにデータ移行前に適用しないほうがいいDBオブジェクトもあります。DBMSや移行ツールによって異なる動作をするものもあると思いますが、「3-3. SCT, DMSによるDB移行での注意事項」に例をいくつか記載するので、移行時に注意しましょう。

異種DBMS間のDB移行で利用可能なデータ移行ツールについて、AWSへDB移行を行う場合を想定して、[GoldenGate](https://www.oracle.com/jp/middleware/technologies/middleware/goldengate/overview.html)と[Database Migration Service（DMS）](https://aws.amazon.com/jp/dms/?nc2=h_ql_prod_mt_dbms)を比較してみました。どちらのツールもサービス中の全量コピー＋差分同期（CDC）をサポートするので、サービス停止可能時間が短い場合にも利用できます。

| 移行ツール | ベンダ | 概要 | コスト |
|:-|:-|:-|:-|
| GoldenGate  | Oracle  | 多機能で、柔軟な構成が可能なDB移行ツールです。<br>GoldenGate Hubを導入したEC2を用意し、これを経由して移行元からのデータ読込み・移行先への書き込みを実施します。構成はOracle Databaseの移行に関するAWSの[Whitepaper](https://d1.awsstatic.com/whitepapers/strategies-for-migrating-oracle-database-to-aws.pdf)が参考になります。  | GoldenGateライセンスとEC2の費用が必要  |
| Database Migration Service (DMS)  | AWS  | AWSにDMSレプリケーションインスタンスを用意し、これを経由して移行元からのデータ読込み・移行先への書き込みを実施します。<br>マネージド型サービスのため、インスタンス作成やマルチAZ化などを容易に構成可能です。  | DMSインスタンスの費用が必要。Auroraへ移行する場合、6カ月間は無償で利用可能。  |


# 3. DMSを使ったOracle DatabaseからAuroraへの移行検証

ここでは、[AWS DMS データベース移行手順ガイド](https://docs.aws.amazon.com/ja_jp/dms/latest/sbs/dms-sbs-welcome.html)を参考に、SCTやDMSを使った異種DB間での移行作業を一通り実行してみます。移行元はOracle Database、移行先はAurora（PostgreSQL互換）とします。

## 3-1. 検証環境の構成概要

検証環境の構成概要を以下に示します。構成の単純化のため、オンプレミス・AWS間のネットワーク接続は行わず、AWSの同一VPC内に移行元・移行先DBを配置します。移行元DBへ適用するスキーマとして、AWSがDMSの動作確認用に提供している[サンプルスキーマ](https://github.com/aws-samples/aws-database-migration-samples/tree/master/mysql/sampledb/v1)を使用します。

![dms-sct-config.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736452/c251c079-be15-37ae-790d-983eea386a0d.jpeg)

| サーバ | リソース | 導入ソフトウェア |
|:-|:-|:-|
| SCTサーバ（EC2） | インスタンスタイプ: t3.small<br>ディスク: gp2 30GiB | Windows Server 2019 <br> [Schema Conversion Tool 1.0.652](https://docs.aws.amazon.com/ja_jp/SchemaConversionTool/latest/userguide/CHAP_Installing.html) <br> [Oracle JDBC Driver 10](https://www.oracle.com/database/technologies/appdev/jdbc-ucp-19-11-c-downloads.html) <br> [PostgreSQL 4.2 JDBC Driver 42.2.23](https://jdbc.postgresql.org/download.html) <br> [pgAdmin 4 v5.5](https://www.pgadmin.org/download/pgadmin-4-windows/) |
| 移行元DBサーバ（EC2）  | インスタンスタイプ: t3.large<br>ディスク: gp2 50GiB  | Windows Server 2019 <br> [Oracle Database 19c (19.3)](https://www.oracle.com/jp/database/technologies/oracle-database-software-downloads.html)  |
| 移行先DBサーバ（Aurora） | インスタンスクラス: db.t3.medium | Aurora PostgreSQL (Compatible with PostgreSQL 12.6)  |
| DMS  | インスタンスクラス: dms.t3.medium <br> ストレージ: 50GiB | DMS 3.4.4  |


## 3-2. DB移行作業の流れ

### (1) 事前準備

事前準備として、以下のリソースを作成しておきます。

- VPC、サブネット、NAT Gateway、Endpointなどのネットワークリソースを作成
- 移行元DBサーバとなるEC2を作成し、Oracle Database 19cのインストール・DB作成の実施後、サンプルスキーマをインポート
- 移行先DBサーバとしてAurora（PostgreSQL互換）を作成

### (2) SCTによる変換レポート作成・スキーマ変換

SCTサーバとなるEC2を作成し、SCTを導入します。SCTにJDBCドライバを設定した後、以下の作業を実施します。

- 変換レポート作成 <br>
DB移行の計画フェーズで移行先DBMSの比較検討を行う際に、移行対象スキーマでの手動変換の要否や難易度を、DBMSごとにまとめたレポートを作成できます。SCTのメニューから [File] - [New Project Wizard] を選択し、移行元DBへの接続情報などを設定して、PostgreSQLやMySQL、MariaDBへの変換レポートを作成します。

![sct-report.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736452/be4acb59-f870-96df-e2c8-1c87e5920805.jpeg)

- スキーマ変換<br>
SCTで自動スキーマ変換により移行先DBへ適用できるDDLを作成します。SCTのメニューから [File] - [New Project] を選択して、移行元・移行先DBへの接続情報などを設定し、移行元DBから移行対象スキーマを選択して [Actions] - [Convert schema] を実行します。自動変換できなかったオブジェクトは手動で変換を行います。今回の検証では手動変換は対象外としました。

![sct-conversion.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736452/d6ce9892-107f-605e-cdf9-a7f567b56414.jpeg)


### (3) 移行先DBへの変換後スキーマ適用

SCTサーバにPostgreSQLクライアント（pgAdmin）を導入し、自動変換・手動変換したスキーマ定義を移行先DBへ適用して、DBデータを移行できる状態にします。

- 拡張パックの適用
SCTでは、移行元DBMSの独自関数と互換性のある関数を移行先DBで使用できる[拡張パック](https://docs.aws.amazon.com/ja_jp/SchemaConversionTool/latest/userguide/CHAP_ExtensionPack.html)を提供しています。SCTで移行先DBのスキーマを選択して [Actions] - [Apply Extension Pack] を実行し、画面に従って操作を行います。これにより、移行先DBに拡張パックが適用され、aws_oracle_dataやaws_oracle_extなどのスキーマが作成されます。

- 移行先DBへの変換後スキーマの適用
変換後スキーマの移行先DBへの適用方法について、変換後の初回はエラー発生時の原因特定を考慮して、DBクライアントからオブジェクトごとにDDLを実行することをお勧めします。DDLがエラーなく適用でき、オブジェクトが作成できたことを確認した後に、各種テストを実施して正しく変換されていたかを確認してください。
データ移行を行う場合は、「2-3. 異種DBMS間のDB移行方式」に記載したように、データ移行でのエラーの原因となりうるオブジェクトもありますので、必要最小限（テーブルのみなど）のオブジェクトを作成します。データ移行完了後に、残りのオブジェクトを作成します。
今回の検証ではデータ移行で必要なオブジェクトの作成のみとしました。

### (4) データ移行準備

DMSによるデータ移行を実施するため、準備として以下の作業を行います。

- 移行元DBの設定変更
DMSでデータ移行を行う前提条件として、移行元DB（Oracle Database）でアーカイブログ設定・サプリメンタルログ設定を行います。

- DMSの各種リソース作成
DMSでDB移行に必要な下記リソースを作成します。<br>・レプリケーションサブネットグループ<br>・レプリケーションインスタンス<br>・ソースエンドポイント、ターゲットエンドポイント<br>・移行タスク<br>移行タスクではテーブルをマッピングするための変換ルールを設定しますが、SCTではPostgreSQL向けのスキーマ名・テーブル名・列名が移行元で大文字であっても小文字に変換されますので、これをルールとして設定します。
DMSでは、移行方式として全量コピーのみ、全量コピー＋差分同期、差分同期のみの3種類から選択できますが、今回の検証では全量コピーのみとしました。

### (5) データ移行実施

前項で作成した移行タスクを開始し、データ移行を実施します。DMS画面で移行対象の表ごとに移行済みの行数が表示されます。最も移行時間を要する表に対して、事前に移行元DBで行数を確認しておくことで、移行の進捗を確認することができます。全量コピーが完了すると移行タスクも完了します。データ移行完了後に、移行先DBで残りのスキーマオブジェクトを作成します。これでDB移行は完了です。

![dms-replication.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736452/66720b77-87e3-ee3b-ea30-e83ea8383e65.jpeg)


## 3-3. SCT, DMSによるDB移行での注意事項

今回、SCT, DMSを使ってDB移行検証を実施した結果、注意した方がいいと感じた点を以下に挙げてみます。

- SCTは数か月ごとにバージョンアップされています。以前のバージョンで自動変換できなかったオブジェクトが自動変換できるようになることもありますので、常に最新バージョンを使用しましょう。特に、変換レポートを作成する移行計画フェーズと実際にスキーマ変換を行うフェーズは時期が異なるので、スキーマ変換実行時は注意しましょう。

- 「2-3. 異種DBMS間のDB移行方式」に記載しましたが、移行先DBでデータ移行前に作成しないほうがいいオブジェクトがあります。サービス停止可能時間にもよりますが、データ移行前は必要最小限のオブジェクトのみを作成しておき、データ移行完了後に残りのオブジェクトを作成してからサービスを再開する方法もあるかと思います。以下にデータ移行前に作成しないほうがいいオブジェクトの例をいくつかあげます。

  - 外部キーなどの制約<br>
DMSでの移行するデータの順序は任意のため、参照先の外部キーより前に参照元データが移行される場合があります。この場合、移行先DBでのデータ挿入時に外部キー制約に引っかかってエラーになります。移行先DBへの制約の作成は、少なくとも全量コピーが完了した後にする必要があります。

  - インデックス<br>
データ移行後にインデックスが断片化しているとリビルドが必要になります。データ移行中は移行先DBでの処理のオーバーヘッドにもなりますので、特に要件がなければ、移行完了後の作成でもいいでしょう。

  - シーケンス<br>
移行元DBから収集したスキーマ情報では、シーケンスの開始番号は次に採番される番号となっています。一方、SCTで変換したシーケンスのDDLでは開始番号は1になります。また、実際のデータ移行時にはシーケンス番号はスキーマ情報収集時点から変わっていると考えられます。そのため、データ移行が完了し、移行元DBの更新を停止した時点でのシーケンス番号を確認し、その値を反映させたDDLを移行先DBへ適用する必要があります。

  - トリガー<br>
移行先DBでのデータ挿入をきっかけに自動実行されて、データの挿入・更新を実行するトリガーがあると、移行元・移行先のDBデータの不整合が発生してしまいます。データ移行中に必要でなければ、データ移行完了後にトリガーを作成しましょう。

- 今回の検証では、移行性能は検証の対象外としています。実際のDB移行では移行時間がシビアなケースが多く、想定した転送速度が出ない場合には大きな問題になります。DMSインスタンスはサイジングが難しい（無理？）ので、実際のDB移行では、実データを使用した検証が必要です。

# 4. 最後に

この記事ではクラウドへのDB移行について、移行方式を決める際の検討ポイントと、実際にSCT, DMSを使ったAWSへのDB移行検証の結果をまとめてみました。

データベース移行の計画フェーズで検討すべきポイントをまとめた[別記事](https://qiita.com/kenichi_matsunaga/items/fd5247f6c839ce19c097)とあわせて、クラウドへのDB移行を行う際の参考にしていただければと思います。