Amazon Web Services ブログ

AWS DMS を使用して Amazon Aurora for PostgreSQL のメジャーバージョンへのアップグレードを最小ダウンタイムで実現する

AWS は 2 つのマネージド型 PostgreSQL オプションを提供しています。Amazon RDS for PostgreSQLAmazon Aurora PostgreSQL です。Amazon RDS または Aurora がデータベースエンジンの新しいメジャーバージョン (PostgreSQL 10 から 11 など) をサポートしている場合、DB インスタンスを新しいバージョンにアップグレードできます。メジャーバージョンのアップグレードには、既存のアプリケーションとの下位互換性がない可能性があるデータベースの変更が含まれる可能性があります。詳細については、「Aurora PostgreSQL 向けの PostgreSQL DB エンジンをアップグレードする」と「Amazon RDS を PostgreSQLのメジャーバージョンとマイナーバージョンにアップグレードするためのベストプラクティス」を参照してください。

Amazon RDS と Aurora のどちらにも、DB インスタンスを変更することにより、メジャーバージョンのアップグレードを手動で開始するオプションがあります。これは、インプレースアップグレードとも呼ばれ、アップグレードプロセス中にアプリケーションのダウンタイムを必要とします。また、アップグレードで問題が発生した場合は、最新のバックアップを復元する必要があります。したがって、このオプションはすべてのワークロードタイプに望ましいとは限りません。別のアプローチは、メジャーバージョンのアップグレードに AWS Database Migration Service (DMS) を使用することです。AWS DMS は、PostgreSQL 論理レプリケーションを使用して、2 つのメジャーバージョン間のデータをほぼリアルタイムで同期します。AWS DMS は、次の要件を満たしている場合にのみ使用してください。

  • 特定のメジャーバージョンで利用できるインプレースアップグレードオプションがない
  • Aurora クラスター内の少数または一部のデータベースをアップグレードする必要がある
  • アップグレードプロセスに必要なダウンタイムを最小限に抑え、カットオーバーで問題が発生した場合に古いインスタンスへ素早くロールバックできるオプションを確保したい

AWS DMS ソリューションでは、インプレースアップグレードオプションとは対照的に、AWS リソースと計画がより多く必要です。DMS はアウトバウンド論理レプリケーションソリューションに基づいているため、CPU 使用率、ソースでの読み取りおよび書き込み IOPS の面で負荷が増大します。どの程度増大するかは、変更アクティビティ、移行中のアクティブなタスクの数などの要因によって異なります。ベストプラクティスとして、非本番環境で DMS 手順をテストし、この負荷増に対応できるようにソース環境のサイズを設定したことを確認してください。また、同時タスクの数、DMS レプリケーションインスタンス、および必要なモニタリングについて最適な設定が必要です。

この記事では、最小限のダウンタイムで AWS DMS を使用して Aurora PostgreSQL 10 データベースを Aurora PostgreSQL 11 にアップグレードする方法について説明します。チュートリアルには、すぐに使い始めるのに役立つ再利用可能なアーティファクトが多数用意されています。この記事では Aurora を使用していますが、手順は Amazon RDS for PostgreSQL インスタンスにも有効です。

ソリューションの概要

大まかに、この記事には次の手順が含まれます。

  • AWS CloudFormation を使用して必要な AWS リソースをセットアップする
  • Aurora PostgreSQL 10.x バージョンに基づいてソース環境をセットアップし、サンプルデータをロードする
  • Aurora PostgreSQL 11.x に基づきターゲット環境をセットアップする
  • ネイティブ PostgreSQL ユーティリティを使用してスキーマ移行を実行する
  • AWS DMS を使用してデータ移行 (フルロードおよび変更データキャプチャ (CDC)) をセットアップする
  • ターゲット環境へのモニタリング、テスト、カットオーバー

次の図は、大まかなアーキテクチャを示しています。

前提条件

開始する前に、次の前提条件を満たしている必要があります。

環境のセットアップ

環境をセットアップするには、以下の手順を実行します。

  1. CloudFormation テンプレート Aurora_PostgreSQL_DBLaunch.yamlGitHub リポジトリからダウンロードします。
  2. AWS マネジメントコンソールで起動します。
  3. スタックに apgupgrade という名前を付けます。
  4. ソースおよびターゲットのデータベース設定を指定します。
  5. 他の値はデフォルトのままにします。
    この記事では米国東部 (バージニア北部) リージョンを使用していますが、お客様のご希望のリージョンを使用できます。AWS CLI コマンドを使用するときに、AWS_DEFAULT_REGION を適切なリージョンに設定していることを確認してください。
    CloudFormation スタックは次のリソースをデプロイします。
    • VPC (10.0.0.0/25)
    • インターネットゲートウェイ
    • 2 つのプライベートサブネット
    • 2 つのパブリックサブネット
    • AWS Cloud9 環境
    • VPC 内の PostgreSQL 互換の 10.x (aurora-source) および 11.x (aurora-target) を持った Aurora クラスター。これを単一の db.r5.large インスタンス (ライターインスタンス) のみで起動
    • demo という名前のサンプルデータベース
      スタック作成プロセスの詳細については、AWS CloudFormation のドキュメントを参照してください。CloudFormation スタックの作成には約 15 分かかります。イベントのセクションで進行状況を確認できます。
  1. Aurora マスターユーザー名 pgadmin を記録します。マスターユーザーのデフォルトパスワードは auradmin です。
    この記事では、AWS Cloud9 IDE を使用して SQL スクリプトを実行し、データを読み込みます。同じ VPC 内で Amazon EC2 インスタンスを起動することもできます。
  2. 正常に起動したら、AWS Cloud9 環境にログインします。
  3. PostgreSQL クライアントツールをインストールします。
  4. GitHub から AWS DMS サンプルリポジトリのクローンを作成し、データをソースデータベースにロードします。次のコードを参照してください。
    cd ~/environment
    git clone https://github.com/aws-samples/aws-database-migration-samples.git
  5. /PostgreSQL/sampledb/v1 ディレクトリに移動します。
  6. ソースおよびターゲットの Aurora エンドポイントの環境変数を設定します。次のコードを参照してください。
    export AURORA_SOURCE_EP=<aurora-source cluster DNS endpoint>
    export AURORA_TARGET_EP=<aurora-target cluster DNS endpoint>

    AWS CloudFormation の出力セクションからクラスターのエンドポイント名を取得できます。

  7. psql ユーティリティを使用してマスターユーザーとして aurora-source にログインし、サンプルデータをセットアップします。次のコードは、スキーマ dms_sample を作成し、スキーマオブジェクトとデータをロードします。
    cd ~/environment/aws-database-migration-samples/PostgreSQL/sampledb/v1
    psql -h $AURORA_SOURCE_EP  -U pgadmin -d demo -f install-postgresql.sql 

    デフォルトのインストールには最大 30〜45 分かかり、約 7 GB のデータがロードされます。「role does not exist」や「psql: install-postgresql.sql:30: INFO: pg_hint_plan: hint syntax error at or near APPEND」などの psql エラーが発生する場合があります。それは無視しても構いません。

  8. テーブルが正しくセットアップされ、データのロードが完了していることを確認してください。
  9. テーブルとそのサイズのリストを確認するには、次の psql コマンドを実行します。
    psql -h $AURORA_SOURCE_EP -U pgadmin -d demo 
    alter database demo set search_path="$user","dms_sample","public";
     \dt+ dms_sample.*
  10. この記事で使用しているスクリプトと SQL を含む GitHub リポジトリのクローンを作成します。次のコードを参照してください。
    cd ~/environment
    git clone https://github.com/aws-samples/amazon-aurora-postgresql-upgrade

ソース環境の設定

ソース環境を設定するときは、前提条件、制限事項、ベストプラクティスを徹底的に確認することが重要です。この記事では、重要な考慮事項をいくつか取り上げます。詳細については、「AWS DMS のソースとしての PostgreSQL データベースの使用」を参照してください。

論理レプリケーションを有効にする

aurora-source クラスターパラメータグループの rds.logical_replication=1 を更新して論理レプリケーションを有効にし、インスタンスを再起動します。詳細については、「Aurora で PostgreSQL 論理レプリケーションを使用する」を参照してください。次のコードを参照してください。

# Get the parameter group name and Instance details for Aurora cluster
aws rds describe-db-clusters --db-cluster-identifier "aurora-source" --query "DBClusters[*].[DBClusterIdentifier,DBClusterMembers[0].DBInstanceIdentifier,DBClusterParameterGroup]" --output table

# Set the rds.logical_replication to 1 for enabling replication
aws rds modify-db-cluster-parameter-group \
--db-cluster-parameter-group-name <clusterparamgroup> \
--parameters "ParameterName=rds.logical_replication,ParameterValue=1,ApplyMethod=pending-reboot"

# Reboot the instance 
aws rds reboot-db-instance --db-instance-identifier <instance identifier> 

データ型に関する考慮事項

AWS DMS は、PostgreSQL から PostgreSQL にデータを移行するときに、すべての PostgreSQL データ型をサポートしていません。このブログ記事が公開された日付の時点では、複合データ型と、タイムゾーンを含むタイムスタンプを移行することはできません。さらに、AWS DMS は、データ型が不明な場合、一部のデータ型を文字列としてストリーミングします。XML や JSON などの一部のデータ型は小さなファイルとして正常に移行できますが、大きなドキュメントの場合は失敗する可能性があります。このようなデータ型のテーブルがある場合は、pg_dumpPublisher/Subscriber logical replication などのネイティブの PostgreSQL レプリケーションツールを使用して、このようなテーブルを移行する必要があります。詳細については、「AWS DMS を使用して PostgreSQL から PostgreSQL へ移行する」を参照してください。次のコードを参照してください。

cd ~/environment/amazon-aurora-postgresql-upgrade/DMS
psql -h $AURORA_SOURCE_EP -U pgadmin -d demo -f SourceDB/dms_unsupported_datatype.sql

サポートされていないデータ型がセットアップにないため、前のクエリの行は表示されません。

もう 1 つの重要な考慮事項は、精度とスケールのない NUMERIC データ型のテーブルを識別することです。NUMERIC データ型であるが精度とスケールがないデータを転送する場合、AWS DMS はデフォルトで NUMERIC (28,6) (精度 28、スケール 6) を使用します。たとえば、ソースの値 0.611111104488373 は、PostgreSQL ターゲットでは 0.611111 に変換されます。次のコードを参照してください。

select table_schema,table_name,column_name,data_type from information_schema.columns where data_type ='numeric' and numeric_scale is null;

ワークロードに対するこの精度の問題の影響を評価し、テーブルの精度を調整する必要があります。

アプリケーションでターゲットデータベースの精度とスケールを維持する必要がある場合は、ALTER TABLE を使用してソースデータベースを変更する必要があります。ALTER TABLE コマンドは、テーブルの排他ロックを取得するデータ定義言語 (DDL) コマンドであり、トランザクションの終了まで保持されます。これにより、特に大きなテーブルの場合、データベース接続が増加し、アプリケーションが停止します。したがって、このような変更は、慎重に分析した後、メンテナンスウィンドウ中に展開します。

これがワークロードの問題ではない場合は、現状のセットアップでレプリケートできますが、関係するテーブルに対して AWS DMS 検証を有効にできないことに注意してください。詳細については、「AWS DMS タスクの検証」を参照してください。

プライマリキーがない

キャプチャされたテーブルにはプライマリキーが必要です。テーブルにプライマリキーがない場合、AWS DMS はそのテーブルの DELETE および UPDATE レコードの操作を無視します。また、CDC およびデータ検証の目的でプライマリキーも必要です。

プライマリキーがないテーブルを識別するには、次のコードを入力します。

cd ~/environment/amazon-aurora-postgresql-upgrade/DMS
psql -h $AURORA_SOURCE_EP -U pgadmin -d demo -f SourceDB/missing_pk.sql

table_schema  |    table_name
--------------+------------------
 dms_sample   | mlb_data
 dms_sample   | nfl_data
 dms_sample   | nfl_stadium_data
 dms_sample   | seat

このようなテーブルを管理する際は、次の提案を考慮してください。

  • プライマリキーとして機能できる列を特定します。これは、一意のインデックスを持ち、null 制約のない列となるかもしれません。
  • そのようなキーが存在しない場合は、GUID などの列を追加して、代理キーを追加してみてください。別のオプションは、テーブルに存在するすべての列を追加することです。
  • テーブルが挿入のみを受け取り、更新または削除を受け入れない場合 (たとえば、テーブルを履歴テーブルとして使用している場合)、そのままにすることができ、DMS が挿入をコピーします。

このチュートリアルでは、すべてのテーブル (シートを除く) にプライマリキーを作成して、CDC および AWS DMS 検証が確実に行われるようにします。シートテーブルのプライマリキー作成ステップをスキップするため、AWS DMS が検証状態をプライマリキーなしとして報告し、このテーブルでデータ検証を実行していないことにお気づきかもしれません。次のコードを参照してください。

set search_path='dms_sample';
alter table mlb_data add primary key (mlb_id);
alter table nfl_data add primary key (position ,name,team);
alter table nfl_stadium_data add primary key(stadium,team);

データ定義言語の伝播

AWS DMS で DDL ステートメントをレプリケートできますが、例外があります。たとえば、CDC を使用する場合、AWS DMS は TRUNCATE オペレーションをサポートしません。詳細については、「AWS DMS のソースとしての PostgreSQL データベースの使用に対する制限」を参照してください。

ベストプラクティスとして、メンテナンスウィンドウの間に、ソースデータベースとターゲットデータベース上で DDL ステートメントを手動で適用する必要があります。DDL 戦略に基づいて、エンドポイントの作成時に追加の接続属性 captureDDLs と、AWS DMS タスクポリシーを設定することで、DDL ステートメントをオンまたはオフにしてください。詳細については、「変更処理の DDL 処理のタスク設定」を参照してください。

アップグレード前のその他の考慮事項

PostgreSQL バージョン 11 には、以前のリリースとの互換性に影響を与える可能性のある変更点がいくつか含まれています。たとえば、列 relhaspkeypg_class カタログで非推奨になり、代わりに pg_index カタログを使用してプライマリキーを確認する必要があります。このような列に依存するカスタムモニタリングクエリがある場合は、それに応じて修正する必要があります。以前のリリースとの互換性に影響を与える可能性のある変更の詳細については、特定のメジャーバージョンのリリースノート (PostgreSQL ウェブサイト上の PostgreSQL 11.0 リリースノートなど) を参照してください。

pg_stat_statementspg_hint_plan などの拡張機能を使用している場合は、ターゲットデータベース内に手動で作成する必要があります。それらを作成するときは、ソースデータベースとターゲットデータベースのバージョンの不一致がないかを確認し、リリースノートを参照してください。たとえば、pg_repack は 1.4.4 で PostgreSQL 11 のサポートを追加しました。つまり、pg_repack クライアントを 1.4.4 にアップグレードする必要があります。次のコードを使用して、インストールされている拡張機能を検証できます。

psql> \dx

ソース環境をセットアップし、準備が整っていることを確認したら、ターゲット環境をセットアップできます。

ターゲット環境のセットアップ

ターゲット環境を設定するときは、前提条件、制限事項、ベストプラクティスを注意深く確認することが重要です。詳細については、「AWS Database Migration Service のターゲットとしての PostgreSQL データベースの使用」を参照してください。このセクションでは、スキーマの移行と環境で必須のパラメータの設定を実行します。

この記事では、PostgreSQL バージョン 11 に基づくカスタムパラメータグループを提供します。これは、既存の設定に基づいてさらにカスタマイズできます。

session_replication_role=replica を設定して、移行が完了するまでインスタンスからのすべてのトリガーを一時的に無効にします。次のコードを参照してください。

# Identify instance id for aurora-target cluster

aws rds describe-db-clusters --db-cluster-identifier "aurora-target" \
--query "DBClusters[*].[DBClusterIdentifier,DBClusterMembers[0].DBInstanceIdentifier,\
DBClusterParameterGroup]" --output table

# Check DB parameter group

aws rds describe-db-instances --db-instance-identifier <instance_identifier> \
 --query "DBInstances[*].[DBClusterIdentifier,DBInstanceIdentifier,\
 DBParameterGroups[0].DBParameterGroupName,DBParameterGroups[0].ParameterApplyStatus]"\
 --output table

# Modify session_replication_role setting to replica

aws rds modify-db-parameter-group --db-parameter-group-name <dbparamgroup> \
--parameters "ParameterName=session_replication_role,ParameterValue=replica,\
ApplyMethod=immediate"

# Make sure the ParameterApplyStatusvalue changes from applying to in-sync
aws rds describe-db-instances --db-instance-identifier <instance_identifier> \
 --query "DBInstances[*].[DBClusterIdentifier,DBInstanceIdentifier,\
 DBParameterGroups[0].DBParameterGroupName,DBParameterGroups[0].ParameterApplyStatus]"\
 --output table

# Verify that database parameter is set in target database

demo=> show session_replication_role ;
 session_replication_role 
--------------------------
 replica
(1 row)

この移行を続行するには、最初にスキーマと関連オブジェクトをターゲットデータベースに作成する必要があります。スキーマの移行には 2 つのステップが含まれます。ユーザー、ロール、付与を移行することと、スキーマ定義を移行することです。これは同種の移行であるため、pg_dumpallpg_dump などのネイティブ PostgreSQL ツールを使用します。

ユーザー、ロール、システム権限の移行

すべてのデータベースに共通のグローバルオブジェクトをダンプするには、pg_dumpall を使用します。これには、データベースのロールと、データベース全体に適用されるアクセス許可などのプロパティに関する情報が含まれます (pg_dump はこれらのオブジェクトをエクスポートしません)。次のコードを参照してください。

cd ~/environment
cd amazon-aurora-postgresql-upgrade/DMS/SourceDB
pg_dumpall -h $AURORA_SOURCE_EP -g -U pgadmin -f db_roles.sql --no-role-password

Amazon RDS for PostgreSQL と Aurora PostgreSQL は、カタログテーブル pg_authid へのアクセスをブロックします。したがって、pg_dumpall—no—role-password オプションを使用して、ユーザーとロールの定義をダンプする必要があります。さらに、これには PostgreSQL 10 クライアントを使用する必要があります。

db_roles.sql ファイルには、rdsadmin や他の rds _ * ロールなど、すべてのユーザーおよびロール情報が含まれています。環境に関連するユーザーを特定し、不要なユーザーとテーブルスペース定義を SQL スクリプトから除外し、そのスクリプトをターゲットデータベースで実行します。これにより、ソース環境とターゲット環境の両方で一貫したユーザーとロールのセットアップがあることが保証されます。パスワードはエクスポートされないため、alter user コマンドを使用して手動でパスワードを同期する必要があります。

認証情報を AWS Secrets Manager に保存するか、IAM 認証を使用する場合は、ターゲット環境に必要な認証情報とアクセス許可を設定します。

psql -h $AURORA_TARGET_EP -U pgadmin -d demo -c "CREATE USER dms_user WITH PASSWORD 'dms_user'"

スキーマオブジェクトの移行

スキーマ DDL をコピーするには、pg_dump コマンドを使用します。次のコードを参照してください。

cd ~/environment/amazon-aurora-postgresql-upgrade/DMS/SourceDB
pg_dump –h  $AURORA_SOURCE_EP -d demo --schema-only -U pgadmin -f pg_schema.sql

pg_schema.sql ファイルには、すべての DDL ステートメントが含まれています。

ベストプラクティスとして、効率的なデータロードのために、次の順序でオブジェクトを作成する必要があります。

  1. フルロードを開始するためのシーケンス、テーブル、およびプライマリキー制約を作成します。
  2. フルロードが完了したら、CDC の変更を適用する前にタスクを停止できます。これは、AWS DMS タスク設定で管理できます。
  3. 追加のセカンダリインデックスとその他の残りのオブジェクトを作成します。

このアプローチにより、セカンダリインデックスがフルロードプロセスを遅くしないことを確認します。

この記事はすでに pg_schema.sql スクリプトから dms_sample スキーマ関連 DDL を抽出し、オブジェクトタイプに基づいて複数の DDL ファイルを作成しています。このような SQL ファイルは、TargetDB ディレクトリにあります。ターゲット環境で dms_sample スキーマを作成するには、次のコードを入力します。

cd ~/environment/amazon-aurora-postgresql-upgrade/DMS/
psql -h $AURORA_TARGET_EP -U pgadmin -d demo -f ./TargetDB/create_table.sql
psql -h $AURORA_TARGET_EP -U pgadmin -d demo -f ./TargetDB/create_pk_constraint.sql

データベースの移行に進む前に、スキーマオブジェクトがターゲットにあることを確認します。

データベースの移行

このステップでは、スタック名 DMSRepforBlog を使用して、AWS CloudFormation を介して AWS DMS レプリケーションインスタンス (AWS DMS バージョン 3.3.1)、ソース、およびターゲットエンドポイントを作成します。AWS CLI コマンドを使用してレプリケーションタスクを作成するため、dms-vpc-roledms-cloudwatch-logs-role の 2 つのロールを作成する必要があります。手順については、「AWS CLI と AWS DMS API で使用して IAM ロールを作成する」を参照してください。

次のコードで CloudFormation テンプレートを起動します。

cd ~/environment/amazon-aurora-postgresql-upgrade/DMS/src 
# Install jq utility
sudo yum install jq -y
# Set AURORA_DB_CFSTACK_NAME to Aurora PostgreSQL launch CloudFormation stack name.
export AURORA_DB_CFSTACK_NAME="<Enter the stack name of Aurora>"
echo $AURORA_DB_CFSTACK_NAME
# Verify above stack name matches the Aurora stack created in earlier step

export AWS_DEFAULT_REGION="us-east-1"

#Source Endpoint Information
SrcRDSEndPoint=$(aws cloudformation describe-stacks --stack-name $AURORA_DB_CFSTACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="SrcRDSEndPoint") | .OutputValue')

#Target Endpoint Information
TgtRDSEndPoint=$(aws cloudformation describe-stacks --stack-name $AURORA_DB_CFSTACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="TgtRDSEndPoint") | .OutputValue')

#Subnet Information
SubnetID1=$(aws cloudformation describe-stacks --stack-name $AURORA_DB_CFSTACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="SubnetID1") | .OutputValue')

SubnetID2=$(aws cloudformation describe-stacks --stack-name $AURORA_DB_CFSTACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="SubnetID2") | .OutputValue')

#Security Group Information
RepSecurityGroup=$(aws cloudformation describe-stacks --stack-name $AURORA_DB_CFSTACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="RDSSecurityGrp") | .OutputValue')

export SrcDBUsername="pgadmin"
export SrcDBPassword="auradmin"
export TgtDBUsername="pgadmin"
export TgtDBPassword="auradmin"

# Launch the Cloudformation Stack to create DMS replication instance
aws cloudformation create-stack --stack-name DMSRepforBlog --template-body file://DMSRepInstance.yaml --parameters ParameterKey=RepAllocatedStorage,ParameterValue=100 ParameterKey=RepMultiAZ,ParameterValue=false ParameterKey=RepSecurityGroup,ParameterValue=$RepSecurityGroup ParameterKey=ReplInstanceType,ParameterValue=dms.r4.2xlarge ParameterKey=SrcDBUsername,ParameterValue=$SrcDBUsername ParameterKey=SrcDBPassword,ParameterValue=$SrcDBPassword ParameterKey=SrcDatabaseConnection,ParameterValue=$SrcRDSEndPoint ParameterKey=SrcEngineType,ParameterValue=aurora-postgresql ParameterKey=Subnets,ParameterValue="$SubnetID1 \, $SubnetID2" ParameterKey=TgtDBUsername,ParameterValue=$TgtDBUsername ParameterKey=TgtDBPassword,ParameterValue=$TgtDBPassword ParameterKey=TgtDatabaseConnection,ParameterValue=$TgtRDSEndPoint ParameterKey=TgtEngineType,ParameterValue=aurora-postgresql

スタックの作成には最大 5 分かかります。完了したら、次のコードでソースとターゲットの接続をテストします。

 Set AWSDMS_CFSTACK_NAME to DMS replication Cloudformation stack name
AWSDMS_CFSTACK_NAME="DMSRepforBlog"
export AWS_DEFAULT_REGION="us-east-1"
#Set variable to replication instance arn
DMSREP_INSTANCE_ARN=$(aws cloudformation describe-stacks --stack-name $AWSDMS_CFSTACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="ReplicationInstanceArn") | .OutputValue')

# Set source database end point arn
DB_SRC_ENDPOINT=$(aws cloudformation describe-stacks --stack-name $AWSDMS_CFSTACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="SrcEndpointArn") | .OutputValue')
# Set target database end point arn
DB_TGT_ENDPOINT=$(aws cloudformation describe-stacks --stack-name $AWSDMS_CFSTACK_NAME | jq -r '.Stacks[].Outputs[] | select(.OutputKey=="TgtEndpointArn") | .OutputValue')

レプリケーションインスタンスとエンドポイントの ARN を取得したら、接続のテストに進むことができます。次のコードを参照してください。

#Test source DB connection

aws dms test-connection --replication-instance-arn ${DMSREP_INSTANCE_ARN} --endpoint-arn ${DB_SRC_ENDPOINT}
# Ensure status changes from testing to successful (takes about ~1 min)
aws dms describe-connections --filter Name=endpoint-arn,Values=${DB_SRC_ENDPOINT} Name=replication-instance-arn,Values=${DMSREP_INSTANCE_ARN} --output table

#Repeat same steps for target DB

aws dms test-connection --replication-instance-arn ${DMSREP_INSTANCE_ARN} --endpoint-arn ${DB_TGT_ENDPOINT}
# Ensure status changes from testing to successful (takes about ~1 min)
aws dms describe-connections --filter Name=endpoint-arn,Values=${DB_TGT_ENDPOINT} Name=replication-instance-arn,Values=${DMSREP_INSTANCE_ARN} --output table

スキーマのソースエンドポイントを更新するには、次のコードを入力します。

# Below command is an asynchronous operation and can take several minutes

aws dms refresh-schemas --endpoint-arn $DB_SRC_ENDPOINT --replication-instance-arn $DMSREP_INSTANCE_ARN --output table

# Check status
aws dms describe-refresh-schemas-status --endpoint-arn $DB_SRC_ENDPOINT --output table

AWS DMS のセットアップ

AWS DMS は、この移行でフルロードと CDC をサポートしています。または、フルロードには pg_dump のようなネイティブツールを使用し、CDC には AWS DMS のみを使用できます。この記事では、AWS DMS を使用してフルロードと CDC の両方を実行します。

このチュートリアルでは、2 つのタスクを作成します。1 つは大きなテーブル用で、もう 1 つは残りのテーブル用で、さまざまなタスク設定を使用して並列処理を改善します。トランザクションの一貫性はタスク内で維持されるため、個別のタスクのテーブルは一般的なトランザクションに含まれません。

移行中、大きなテーブル (テーブルの行または物理サイズ) のフルロードにはかなり時間がかかることがあります。AWS DMS のフルロードのベストプラクティスは次のとおりです。

  • 大きなテーブルを特定し、数値のプライマリキーに基づいてそれを複数のチャンクに分割します。できたチャンクを DMS インスタンスの数全体で複数のタスクに分割します。
  • 大きなパーティション分割テーブルをコピーするには、手動でタスクを分割するか、バージョン 1.2 以降の AWS DMS で利用できる自動パーティション分割を使用します。
  • 非本番環境で数回繰り返した後、適切なレプリケーションインスタンスクラスとレプリケーションインスタンスの数を選択します。詳細については、「レプリケーションインスタンスの最適サイズの選択」を参照してください。
  • オフピーク時にソースでフルロードを行うことを計画することで、データベースの変更を書き込み先行ログ (WAL) で維持するための負担を減らし、ストレージ要件を最小限に抑えられます。
  • ターゲットデータベースで自動バキュームをオフにし、フルロードが完了した後にオンにします。

詳細については、「AWS DMS 移行のパフォーマンスの向上」を参照してください。

AWS CLI コマンドを使用して、以下の 2 つの DMS タスクを作成します。

  • タスク 1 には、外部キー関係があるため、personsporting_event_ticket、および ticket_purchase_hist が含まれています
  • タスク 2 には残りのテーブルが含まれます

DMS レプリケーションインスタンスの CloudFormation テンプレートの Outputs タブには、レプリケーションとエンドポイント ARN の値があります。jq ユーティリティを使用して、必要な ARN を抽出することもできます。次のコードを参照してください。

# Switch to directory hosting table mapping and task setting files
cd ~/environment/amazon-aurora-postgresql-upgrade/DMS/Migration
# Task 1
export task_identifier=dms-sample-task1-full-load-cdc
aws dms create-replication-task --replication-task-identifier ${task_identifier} --source-endpoint-arn ${DB_SRC_ENDPOINT} \
--target-endpoint-arn ${DB_TGT_ENDPOINT} --replication-instance-arn ${DMSREP_INSTANCE_ARN} --migration-type full-load-and-cdc \
--table-mappings 'file://table-mapping-task1.json' --replication-task-settings 'file://tasksetting.json'

DMS_TASK_ARN1=$(aws dms describe-replication-tasks | jq -r  '.ReplicationTasks[]|select(.ReplicationTaskIdentifier=="dms-sample-task1-full-load-cdc")|.ReplicationTaskArn')

# Task 2
export task_identifier=dms-sample-task2-full-load-cdc

aws dms create-replication-task --replication-task-identifier ${task_identifier} --source-endpoint-arn ${DB_SRC_ENDPOINT} \
--target-endpoint-arn ${DB_TGT_ENDPOINT} --replication-instance-arn ${DMSREP_INSTANCE_ARN} --migration-type full-load-and-cdc \
--table-mappings 'file://table-mapping-task2.json' --replication-task-settings 'file://tasksetting.json'

DMS_TASK_ARN2=$(aws dms describe-replication-tasks | jq -r  '.ReplicationTasks[]|select(.ReplicationTaskIdentifier=="dms-sample-task2-full-load-cdc")|.ReplicationTaskArn')

AWS DMS エンジンのバージョンに基づいてタスクとエンドポイントを設定するための特定の手順に従っていることを確認してください。たとえば、3.1.0 より前の AWS DMS バージョンを使用する場合は、ソースでさらに設定を行う必要があります。

準備ができたらタスクを開始できます。ステータスを確認するには、次のコードを使用して、ReplicationTaskStatus が「creating」から「ready」に変化したことを確認します。

aws dms describe-replication-tasks --filters Name=replication-instance-arn,Values=${DMSREP_INSTANCE_ARN} --query "ReplicationTasks[:].{ReplicationTaskIdentifier:ReplicationTaskIdentifier,ReplicationTaskArn:ReplicationTaskArn,ReplicationTaskStatus:Status,ReplicationTFullLoadPercent:ReplicationTaskStats.FullLoadProgressPercent}" --output table

# Start tasks
aws dms start-replication-task --replication-task-arn ${DMS_TASK_ARN1} --start-replication-task-type start-replication
aws dms start-replication-task --replication-task-arn ${DMS_TASK_ARN2} --start-replication-task-type start-replication

# Track progress
aws dms describe-replication-tasks --filters Name=replication-instance-arn,Values=${DMSREP_INSTANCE_ARN} --query "ReplicationTasks[:].{ReplicationTaskIdentifier:ReplicationTaskIdentifier,ReplicationTaskArn:ReplicationTaskArn,ReplicationTaskStatus:Status,ReplicationTFullLoadPercent:ReplicationTaskStats.FullLoadProgressPercent}" --output table

注: タスクの開始後、コマンド (select * from pg_replication_slots) を実行して、AWS DMS が aurora-source クラスターにレプリケーションスロットを作成したかどうかを確認できます。タスクごとに 1 つのスロットが作成されます。これは、フルロードおよび CDC タスクにのみ当てはまります。CDC のみのタスクを使用している場合は、スロットを手動で作成し、ソースエンドポイント設定で指定する必要があります。タスクが完了した後、または不要になったときに、タスクと手動スロットを必ずクリーンアップしてください。

# Track progress describing statistics at table level
aws dms describe-table-statistics --replication-task-arn ${DMS_TASK_ARN1} --output table
aws dms describe-table-statistics --replication-task-arn ${DMS_TASK_ARN2} --output table

フルロードが完了すると、タスクは停止するように設定されています。これで、追加のインデックスと残りのオブジェクトを作成できます。次のコードを参照してください。

cd ~/environment/amazon-aurora-postgresql-upgrade/DMS
psql -h $AURORA_TARGET_EP  -U pgadmin -d demo -f ./TargetDB/create_secondary_index.sql
psql -h $AURORA_TARGET_EP  -U pgadmin -d demo -f ./TargetDB/create_fk_constraints.sql
psql -h $AURORA_TARGET_EP -U pgadmin -d demo -f ./TargetDB/create_view.sql
psql -h $AURORA_TARGET_EP  -U pgadmin -d demo  -f ./TargetDB/create_function.sql
psql -h $AURORA_TARGET_EP  -U pgadmin -d demo -f ./TargetDB/object_grants.sql

レプリケーションを連続して行うには、インデックス作成後にタスクを再開する必要があります。次のコードを参照してください。

aws dms start-replication-task --replication-task-arn ${DMS_TASK_ARN1} --start-replication-task-type resume-processing
aws dms start-replication-task --replication-task-arn ${DMS_TASK_ARN2} --start-replication-task-type resume-processing

これで、ソースで DML アクティビティを実行し、AWS DMS がそれをターゲットに複製することを確認できます。次のコードを参照してください。

psql -h $AURORA_SOURCE_EP -U pgadmin -d demo -c "select dms_sample.generateticketactivity(1000)"
psql -h $AURORA_SOURCE_EP -U pgadmin -d demo -c "select dms_sample.generatetransferactivity(100)"

コンソールからタスクの進行状況をモニタリングできます。次のスクリーンショットは、データベース移行タスクページを示しています。

すべてのテーブルの検証状態は「Validated」ですが、シートテーブルには「No primary key」という状態があります。次のスクリーンショットを参照してください。

移行のモニタリング

Amazon CloudWatch メトリクスを使用して、移行の進行状況をモニタリングできます。詳細については、「AWS DMS タスクのモニタリング」を参照してください。ベストプラクティスとして、CDCLatencySourceCDCLatencyTarget の CloudWatch アラームを設定してください。これは、レプリケーションラグに関するタイムリーなアラートを取得し、適切なアクションを実行するのに役立ちます。サンプルの AWS CLI コマンドと、CDCLatencySource および CDCLatencyTarget のモニタリングの設定の詳細については、GitHub の DMS タスクモニタリングファイルを参照してください。 また、aurora-source クラスターの TransactionLogsDiskUsage および CPUUtilization メトリクスをモニタリングすることもできます。詳細については、「Amazon Aurora DB クラスターのモニタリング」を参照してください。

トラブルシューティング

複雑なマルチテラバイトデータベースの移行中に、エラーやデータのコピー処理の遅延といった問題に直面することがあります。このようなシナリオでは、AWS DMS を使用する際のさまざまなトラブルシューティング手法とベストプラクティスを扱った次の記事を参照できます。

アプリケーションをテストする

レプリケーションが AWS DMS を介して追いついた後、aurora-target クラスターに接続することで、アプリケーションのテストを開始できます。テストに進む前に、vacuumdbanalyze などのユーティリティを使用してデータベースの統計を収集します。たとえば、次のコードを参照してください。

vaccumDB -d demo -vZ -h <AURORA_TARGET_EP> -U pgadmin -p 5432

次のテスト戦略を使用できます。

  • 読み取り専用テストについては、レプリケーションがオンになっている間、アプリケーションを直接 aurora-target クラスターにポイントします。
  • ターゲットでの書き込みテストまたはあらゆる種類のストレステストについては、DB クラスタースナップショットを作成するか、aurora-target クラスターのデータベースのクローンを作成します。これにより、レプリケーションプロセスを中断する必要がなくなります。また、テストする前に、トリガー、インデックス、およびカスタムパラメータを必ず有効にしてください。新しいバージョンに対してワークロードを徹底的にテストして、非互換性やパフォーマンスの問題がないかどうかを確認することが重要です。
  • ソースの既存のカスタムパラメータを確認し、テストして、ターゲット環境で適切に設定します。

カットオーバー

機能面と非機能面の両方のテストが完了したら、アプリケーションを新しいメジャーバージョン環境に向けることができます。ロールバック計画とともにカットオーバーの成功基準を定義したことを確認してください。この記事は、参考として次のチェックリストを提供します。チェックリストは環境に合わせて調整してください。次の順序でチェックリストに記入します。

  1. すべてのユーザーとロールが aurora-target で適切な権限で設定されていることを確認します。
  2. ソース環境とターゲット環境でデータベースオブジェクト (インデックスや関数など) 数が一致していることを確認します。オブジェクトの比較を行う際は、repo のサンプルクエリを参照してください。
  3. CloudWatch メトリクスなどのターゲットデータベースのモニタリングをソースと同じになるように設定します。
  4. ソースで長時間実行されているトランザクションを確認し、pg_stat_activity で停止または終了します。次のコードを参照してください。
    cd ~/environment/amazon-aurora-postgresql-upgrade/DMS
    psql -h $AURORA_SOURCE_EP -d demo -U pgadmin -f ./SourceDB/longrunningsess.sql
  5. aurora-source に書き込むすべてのアプリケーションを停止します。これがダウンタイムが始まるポイントです。
  6. CloudWatch メトリクス CDCLatencySource および CDCLatencyTarget をモニタリングして、AWS DMS レプリケーションの遅延がないことを確認します。
  7. AWS DMS にデータ検証エラーがないことを確認します。SQL コマンドを使用して、キーテーブルの行数を確認することもできます。
  8. AWS DMS タスクを停止します。
  9. aurora-target クラスターパラメータグループを更新し、session_replication_role=origin を設定して、すぐに適用します。
  10. 最後の値を手動で調整して、シーケンス (存在する場合) がソースの現在の値と同期していることを確認します。次のコードを参照してください。
    select 'select setval('||quote_literal(schemaname||'.'||sequencename)||','||last_value||',true);' from pg_sequences;
  11. aurora-target エンドポイントを指すようにアプリケーションを変更して、アプリケーションを起動します。
  12. 必要なテストを実行して、アプリケーションが正しく動作していることを確認します。
  13. ターゲットを本番環境で使用できるようにします。これは、ダウンタイムが停止するポイントです。
  14. ターゲット環境をモニタリングし、問題がないかどうかをログに記録します。
  15. テストが成功したら、AWS DMS タスクを削除し、AWS リソースをクリーンアップします。

まとめ

この記事では、Aurora と Amazon RDS for PostgreSQL のメジャーバージョン間でデータを移行するための詳細な手順と、計画と実行に関する重要な考慮事項について説明しました。ベストプラクティスとして、メジャーバージョンアップグレードの最新情報については、AWS DMS、Aurora と PostgreSQL のドキュメントを確認してください。この記事には、データベースをすばやく移行するために使用できるコードテンプレート、SQL スクリプト、タスク設定、およびベストプラクティスも含まれています。この記事についてご質問やご意見があれば、コメントセクションでお聞かせください。

 


著者について

 

Gowri Balasubramanian は、アマゾン ウェブ サービスのプリンシパルデータベースソリューションアーキテクトです。 彼は、AWS を使用している場合にソリューションの価値を向上させる手助けとなるために、AWS のお客様と協力してリレーショナルデータベースと NoSQL データベースサービスの両方の指導や技術支援を行っています。

 

 

 

Amit Bansal は、アマゾン ウェブ サービスでプロフェッショナルサービスチームのシニアコンサルタントです。彼は、AWS へのデータベース移行に焦点を当て、AWS RDS、Aurora、Redshift のアーキテクチャを設計および実装するためにお客様と協力しています。

 

 

 

HariKrishna Boorgadda は、アマゾン ウェブ サービスでプロフェッショナルサービスチームのシニアコンサルタントです。彼は、AWS へのデータベース移行に焦点を当て、Amazon RDS とAurora のアーキテクチャを設計および実装するためにお客様と協力しています。