Amazon Web Services ブログ
AWS DMS がフルロードおよび CDC タスクを開始する際にオープントランザクションをどのように扱うか
リレーショナルデータベース管理システム(RDBMS)における、consistency(一貫性 / 整合性)はトランザクションの重要な特性の1つです。一貫性は、トランザクションが終了した後にデータが常に正しい状態に保たれるためのルールを定義します。データの一貫性により、トランザクションはテーブルに対して事前に定義された予測可能な方法でのみ変更を加えることができ、これによりデータの整合性に対する意図しない影響を防ぐことができます。
データベース移行の際にシステム停止時間を最小限に抑えるためには、まずはじめに移行元のデータベースから整合性のとれたスナップショットを取得する必要があります。その後、移行元のデータベースとの整合性を保ちながらレプリケーションを確立するために、整合性のとれたスナップショットを取得した時点のトランザクション位置を記録する必要があります。基本的な考え方として、スナップショット取得時点からレプリケーション開始までの間にトランザクションの欠落や抜けがある場合、移行先のデータベースの整合性は保証されません。
AWS Database Migration Service (AWS DMS) は、リレーショナルデータベース、データウェアハウス、NoSQL データベース、およびその他のタイプのデータストアに対する移行を支援します。
初期データロード、または AWS DMS のフルロードフェーズ、および変更データキャプチャ (CDC) が一貫した状態から開始されるトランザクション位置を管理するために、AWS DMS は TransactionConsistencyTimeout
というタスク設定を実装して、AWS DMS タスクの開始時にオープントランザクションを処理するようにしました。
この記事では、さまざまなエンジンのフルロード + CDC タスクの開始時に AWS DMS がオープントランザクションを処理する方法について説明し、consistency timeout(整合性タイムアウト)の問題を回避するためのベストプラクティスを紹介します。
トランザクション整合性タイムアウトに関するよくある質問
移行元のデータベースの種類によって、TransactionConsistencyTimeout
に関して以下のような質問がよく寄せられます。
- Oracle ソース – タスクを開始した時
Before load
の状態で10分間も停止しているのはなぜですか。タスクログに表示される「open transaction」とは何を意味しますか。オープントランザクションのタイムアウトが発生するとどうなりますか。 - SQL Server ソース – タスクを開始した時に、
Before load
の状態で停止しているのはなぜですか。 - PostgreSQL ソース –
statement_timeout
を設定していないのに、タスクの開始時にステートメントのタイムアウトが発生してタスクが失敗したのはなぜですか。 - MySQL ソース – 長時間トランザクションが存在する場合、フルロードや CDC タスクの開始に支障が出るのでしょうか。
これらの疑問に答えるため、まず AWS DMS でのオープントランザクションとは何かを説明します。
AWS DMS におけるオープントランザクション
AWS DMS におけるオープントランザクションとは、フルロード + CDC タスクの開始時点で、移行元のリレーショナルデータベースでコミットもロールバックもされていないトランザクションを指します。
前述した移行アプローチ同様、AWS DMS はフルロードを開始する際と、CDC のためのトランザクション位置を特定する際に、整合性のとれた状態を必要とします。
RDBMS エンジンごとにトランザクションログの実装方法が異なるため、AWS DMS も移行元の RDBMS によって異なる動作をします。以降のセクションでは、Oracle、SQL Server、PostgreSQL、MySQL を移行元とした場合に、AWS DMS がオープントランザクションをどのように処理するかについて説明します。
Oracle ソースからの移行時における AWS DMS のオープントランザクション処理について
フルロード + CDC タスクの場合、タスク設定 TransactionConsistencyTimeout
は、AWS DMS がフルロードオペレーションを開始する前にトランザクションが終了するのを待つ秒数を定義します。デフォルト値は 600 秒(10 分)です。タスクの開始時にトランザクションが開いている場合、AWS DMS はデフォルトで 10 分間待機します。TransactionConsistencyTimeout
値に達すると、実行中のトランザクションがあってもフルロードが開始され、TransactionConsistencyTimeout
よりも長いトランザクションが将来のレプリケーションで失われます。
次の図では、フルロードタスク + CDC タスクが開始されると、合計 6 つのトランザクションのうち、AWS DMS ソースキャプチャプロセスによって特定されるオープントランザクションが 2 つあります。
- トランザクション 1 – ソースキャプチャが開始された時点ではオープントランザクションですが、
TransactionConsistencyTimeout
の時間枠内かつフルロードが開始される前にコミットされます。したがって、フルロードフェーズに含まれます。 - トランザクション 2 –
TransactionConsistencyTimeout
の時間枠内およびフルロードが開始される前に開始およびコミットされます。したがって、フルロードフェーズに含まれます。 - トランザクション 3 と 4 – フルロードフェーズ中にコミットされるため、キャッシュされた変更として、フルロードが終了した後に適用されます。
- トランザクション 5 – フルロードフェーズで開始し、フルロードが完了した後にコミットされるため、CDC として、キャッシュされた変更が適用された後に適用されます。
- トランザクション 6 –
FailOnTransactionConsistencyBreached
はデフォルトで false に設定されているため、タスクは続行されます。オープントランザクション B はスキップされ、TransactionConsistencyTimeout
後にコミットされたため、データが失われます。TransactionConsistencyTimeout
とFailOnTransactionConsistencyBreached
の設定に関するベストプラクティスについては、後のセクションで説明します。
次のログは、オープントランザクションがある場合の一般的な AWS DMS ログの例を示しています。SOURCE_CAPTURE
コンポーネントはオープンされているトランザクションの数を識別し、SORTER
は TransactionConsistencyTimeout の後にトランザクション整合性タイムアウトに関する警告を出力します。
SQL Server ソースからの移行時における AWS DMS のオープントランザクション処理について
SQL Server を移行元として使用する場合も同様に、フルロード + CDC タスクの開始時にオープントランザクションが存在すると、AWS DMS の SOURCE_CAPTURE
は以下のようなログを出力して検知します。
SQL Server のデフォルトの分離レベルである READ COMMITTED
で、READ_COMMITTED_SNAPSHOT
が OFF
の場合、他のトランザクションによって変更されたがまだコミットされていないデータの読み取りは許可されません。
そのため、フルロード + CDC タスクで移行中のテーブルにオープントランザクションが存在する場合、そのテーブルに対する select *
は、タスクの対象範囲内のアクティブなトランザクションがコミットまたはロールバックされるまでブロックされます。タスクの対象範囲外のテーブルにオープントランザクションが存在する場合、AWS DMS は一定時間待機した後にタスクを開始します。この場合、AWS DMS はフルロード + CDC タスクの開始のためにコミットやロールバックを待つことはなく、タスクの実行にも影響はありません。
この動作の結果、データの損失は発生しません。ただし、タスク対象範囲内のテーブルに関連するオープントランザクションがコミットまたはロールバックされるまで、フルロード + CDCタスクは Before load
状態のままとなります。
PostgreSQL ソースからの移行時における AWS DMS のオープントランザクション処理について
PostgreSQL を移行元とする場合、AWS DMS は PostgreSQL プラグイン pglogical
または test_decoding
を使用して SOURCE_CAPTURE
コンポーネントを介して Write-Ahead Log (WAL)
を読み取ります。
ただし、アクティブなトランザクションが存在する場合、レプリケーションスロットの作成処理 select * from pg_create_logical_replication_slot('slot_test','test_decoding');
は停止してしまいます。その結果、AWS DMS は変更を取得するためのレプリケーションスロットを作成できなくなり、ステートメントがタイムアウトするまで TransactionConsistencyTimeout
の時間だけ待機します。
オープントランザクションが TransactionConsistencyTimeout
の制限時間内にコミットまたはロールバックされれば、フルロード + CDC タスクは正常に開始され、データの損失も発生しません。しかし、オープントランザクションの実行時間が TransactionConsistencyTimeout
を超えた場合、CDC の前提条件チェックが失敗し、以下のようなログが出力されます。
MySQL ソースからの移行時における AWS DMS のオープントランザクション処理について
MySQL を移行元とする場合、AWS DMS は変更の取得に binlog
を使用します。MySQL の binlog
にはコミットされていないトランザクションは含まれません。そのため、フルロード + CDC タスクの開始時に、AWS DMS はコミットされたトランザクションのみを参照できます。オープントランザクションは、コミットされるタイミング(フルロード中かフルロード後か)に応じて、キャッシュされた変更または CDC 変更として扱われます。このため、MySQL を移行元として使用する場合、フルロード + CDC タスクにおいてトランザクションの整合性タイムアウトの問題は発生しません。
ベストプラクティス
オープントランザクションを扱うためのベストプラクティスは以下の通りです。
- データ移行の評価作業として、移行元データベースの長時間実行トランザクションを事前に十分確認し、アプリケーションやサービスの管理者と協力して、少なくとも移行フェーズの間はデータベース内の長時間トランザクションを最小限に抑えるためのプロセスを確立してください。
- Oracleを移行元とする場合、トランザクションの整合性タイムアウトエラーが発生するとデータが失われる可能性があります。そのため、
FailOnTransactionConsistencyBreached
を true に設定し、早期にタスクを停止させる方がよいでしょう。 - フルロード + CDC タスクは、移行元データベースの負荷が低い時間帯に開始してください。また、フルロード + CDCタスクを開始する前に、移行元データベースで予定されているダンプ処理や 抽出・変換・読み込み(ETL)ジョブの完了を待つことを推奨します。これにより、トランザクションの整合性タイムアウト問題の発生可能性を抑制し、また、処理すべき変更データ量を減らすことで、より早く移行元データベースに追いつくことができます
- フルロード + CDC タスクを開始後、Before load 状態が長時間続く場合は、移行元データベースでオープントランザクションが存在していないか確認することを推奨します。
- Oracle の場合は、v$transaction を確認してください。Oracle スタンバイ(Active Data Guard または Amazon RDS リードレプリカ)データベースをソースとして使用する場合、ソースデータベースのプライマリデータベースでオープントランザクションの詳細を確認してください。
- PostgreSQL の場合は、pg_stat_activity(例)と pg_prepared_xacts(例)を確認してください。
- SQL Server の場合は、DBCC OPENTRAN または dm_tran_active_transactions を確認してください。
TransactionConsistencyTimeout
はデフォルトで 10 分です。ソースデータベースに常に 10 分を超えるトランザクションがある場合は、TransactionConsistencyTimeout
の値を増やしてください。TransactionConsistencyTimeout
を増やすと、AWS DMS の待機時間が長くなるため、TransactionConsistencyTimeout
に達する前に、開いているトランザクションがコミットまたはロールバックされる可能性があります。TransactionConsistencyTimeout
を増やしても、この記事で説明されている整合性タイムアウト関連のエラーが原因で、ソースデータベースで長時間実行されているトランザクションや、タスク障害を回避するための解決策にはならないことに注意してください。AWS DMS がソースデータベースでトランザクションのコミットまたはロールバックを待っている間、タスクは進行しません。したがって、上記のベストプラクティスを適用することは依然として重要です。- データの欠落や整合性の問題を特定するために、AWS DMS データ検証を使用してください。
まとめ
データベース移行プロジェクトにおいて、データの損失は決して許容できません。この記事では、オープントランザクションとは何か、そして異なるデータベースエンジンでフルロード + CDC タスクを開始する際に、AWS DMS がどのようにオープントランザクションを処理するのかについて説明しました。また、オープントランザクションに関連する問題を回避するため、AWS DMS タスクの計画から実行に至るまでのベストプラクティスを紹介しました。
著者について
Wanchen Zhao は AWS のパートナーソリューションアーキテクトです。
Rishi Raj Srivastava は、アマゾンウェブサービスの AWS DMS チームに所属するデータベースエンジニアです。
Sudip Acharya は、インドのAWS ProServe チームのコンサルタントとして、社内外の Amazon カスタマーのデータベース最新化プロジェクトに関するガイダンスや技術支援を行い、お客様が AWS を使用する際のソリューションの価値向上を支援しています。特に、データベースや移行関連ツールの設計・実装を得意分野としています。
翻訳はクラウドサポートエンジニアの小池が担当しました。原文はこちらです。