Amazon Web Services ブログ

RDS PostgreSQL トランスポータブルデータベースを使用したデータベースの移行

Amazon RDS for PostgreSQL が、バージョン 11.5 以降および 10.10 以降で、高速データのインポートおよびエクスポート方法であるトランスポータブルデータベース機能をサポートするようになりました。RDS PostgreSQL インスタンスから別の PostgreSQL インスタンスに PostgreSQL データベースをインポートする必要がある場合は、pg_dumppg_restore などのネイティブツールを使用するか、\copy コマンドを使用してデータをターゲットテーブルにロードできます。トランスポータブルデータベースを使用すると、こうした従来のツールよりもはるかに高速にデータを移動することができます。この機能は、データベースごとの物理的な転送メカニズムを提供する pg_transport と呼ばれる新しい拡張機能を使用します。物理的な転送では、最小限の処理でデータベースファイルをストリーミングすることにより、最小限のダウンタイムでデータをより高速に移動できます。

この記事では、pg_transport の一般的なユースケースと、AWS CLIpsql ユーティリティを使用して RDS PostgreSQL 環境でこれを設定および使用する方法について説明します。

pg_transport のユースケース

多くのお客様は、RDS PostgreSQL で独自の SaaS またはマルチテナントおよびエンタープライズアプリケーションを実行しています。これは、Amazon RDS により、AWS での PostgreSQL デプロイの設定、操作、スケーリングが簡単になるためです。単一の RDS PostgreSQL インスタンスに複数のデータベースを配置して、さまざまな顧客やアプリケーションにサービスを提供するのは一般的なことです。このような環境では、トランスポータブルデータベースが役立ちます。 以下のようなユースケースに最小限のダウンタイムで対処できます。

  • リソースの管理や分離を改善するために、RDS インスタンス間でデータベースを移動する。たとえば、SaaS プロバイダーであれば、特定の容量に達した場合、顧客データを異なる構成 (より大きなインスタンスタイプ、プロビジョンド IOPS、または異なるインスタンスファミリー) に移動する必要があります。
  • セキュリティおよびコンプライアンスの理由でデータを再編成する。たとえば、ある AWS アカウントの RDS インスタンスから、追加のセキュリティコントロールを持つアカウントの RDS インスタンスにデータベースを移動するなどです。
  • 必要に応じて、ダウンストリームアプリケーションや新機能のテストのために、データベースの完全なコピーを提供する。

前提条件

この記事では、RDS PostgreSQL および Amazon EC2 インスタンスに精通していることを前提としています。また、以下の前提条件を満たしている必要もあります。

  • 同じ AWS リージョン内の同じまたは異なる AWS アカウントで、バージョン 11.5 とインスタンスタイプ r5.large の 2 つの RDS インスタンスを起動していること。ソース RDS クラスターには pgsource.<identifier>. <AWS region>.rds.amazonaws.com という名前を付け、ターゲットには pgtarget.<identifier>. <AWS region>.rds.amazonaws.com という名前を付けます。ソースとターゲットの両方の RDS インスタンスが、PostgreSQL の同じメジャーバージョンである必要があります。詳細については、PostgreSQL データベースを作成して接続するを参照してください。
  • ソースデータベースインスタンスの VPC セキュリティグループが、転送先インスタンスからのインバウンドトラフィックを許可していることを確認してください。
  • PostgreSQL インスタンスで動作するように、psql クライアントで Amazon EC2 インスタンスを設定していること。この EC2 インスタンスからのトラフィックを許可するようにデータベースセキュリティグループを設定します。詳細については、PostgreSQL データベースエンジンを実行している DB インスタンスへの接続を参照してください。
  • 認証情報を使用してAWS CLIを設定していること。RDS 管理者の IAM 権限が必要です。詳細については、Amazon RDS での Identity and Access Management を参照してください。また、AWS 管理ポリシー DatabaseAdministrator を使用して RDS インスタンスを管理することも検討できます。

この機能に関連する既知の制限と設定パラメータの詳細については、transport.import_from_server 関数を使用した PostgreSQL データベースの転送を参照してください。

ソース環境の設定

この機能を使用する前に、ソースおよびターゲットの RDS 環境で必要な設定パラメータと pg_transport 拡張を有効にします。次の手順を実行します。

  1. EC2 インスタンスにログインします。新しいパラメータグループを作成し、pgsource (ソース RDS) にアタッチします。次のコマンドを参照してください。
    aws rds create-db-parameter-group --db-parameter-group-name pg11-source-transport-group --db-parameter-group-family postgres11  --description "Parameter group with transport parameters enabled"
  2. pg_transport 関連パラメータである pg_transport.num_workerspg_transport.timingpg_transport.work_mem を設定します。shared_preload_libraries を通じて拡張機能を読み込み、max_worker_processes を更新します。次のコマンドを参照してください。
    aws rds modify-db-parameter-group \
        --db-parameter-group-name pg11-source-transport-group \
        --parameters "ParameterName=pg_transport.num_workers,ParameterValue=4,ApplyMethod=immediate" \
                     "ParameterName=pg_transport.timing,ParameterValue=1,ApplyMethod=immediate" \
                     "ParameterName=pg_transport.work_mem,ParameterValue=131072,ApplyMethod=immediate" \
                     "ParameterName=shared_preload_libraries,ParameterValue=\"pg_stat_statements,pg_transport\",ApplyMethod=pending-reboot" \
                     "ParameterName=max_worker_processes,ParameterValue=24,ApplyMethod=pending-reboot"

    pg_transport 関連パラメータの詳細については、PostgreSQL.TransportableDB.Parameters を参照してください。

  1. 新しく作成したパラメータグループを使用して、ソース RDS インスタンスを変更します。shared_preload_librariesmax_worker_processes などの静的パラメータの一部を変更したため、インスタンスを再起動する必要があります。次のコマンドを参照してください。
    aws rds modify-db-instance --db-instance-identifier pgsource --db-parameter-group-name pg11-source-transport-group —apply-immediately
    aws rds reboot-db-instance —db-instance-identifier pgsource
  1. RDS インスタンスが起動したら、psql を介してインスタンスへの接続を確認します。サンプルデータベースを設定して pg_transport をテストします。この記事では、サイズが異なる 2 つのデータベースを使用していますが、使用している環境の任意のデータベースを使用できます。次のコマンドを参照してください。
    psql -h pgsource.<identifier>.<AWS Region>.rds.amazonaws.com -d postgres -U <RDS Master User>
    create database imdb;
    create database benchdb;
    

    a.) IMDB データセットのデータ (約 14 GB) を imdb データベースに読み込みます。PostgreSQL データベースのオープンソースコミュニティには、多くのサンプルデータセットが用意されています。詳細については、PostgreSQL wiki のサンプルデータセットを参照してください。
    b.) pgbench を使用して benchdb データベースを読み込みます。この記事では、スケールファクタ 10,000 を使用して pgbench データベース (約 130 GB) を初期化します。次のコマンドを入力してデータを benchdb に読み込みます。

    pgbench -i -h pgsource.<identifier>.<AWS Region>.rds.amazonaws.com -d benchdb --foreign-keys -s 10000
  1. ソースデータベース環境の設定を確認し、各データベースの pg_transport 拡張を作成します。ソースインスタンスに接続したら、次のコマンドを入力します。次のコマンドは、出力も表示します。
    psql -h pgsource.<identifier>.<AWS Region>.rds.amazonaws.com -d postgres -U <RDS Master User>
    
    postgres=>\c imdb
     
    imdb-> CREATE EXTENSION pg_transport;
    
    imdb->\dt+
                              関係のリスト
     スキーマ |       名前       | 種類  |  所有者  |  サイズ   | 説明
    --------+------------------+-------+---------+---------+-------------
     public | name_basics      | テーブル | dbadmin | 926 MB  |
     public | title_akas       | テーブル | dbadmin | 1520 MB |
     public | title_basics     | テーブル | dbadmin | 705 MB  |
     public | title_crew       | テーブル | dbadmin | 307 MB  |
     public | title_episode    | テーブル | dbadmin | 176 MB  |
     public | title_principals | テーブル | dbadmin | 1870 MB |
     public | title_ratings    | テーブル | dbadmin | 49 MB   |
    
    imdb=> SELECT pg_size_pretty( pg_database_size('imdb') );
     pg_size_pretty
    ----------------
     14 GB
    (1 行)
    
    imdb->\c benchdb 
    
    benchdb-> CREATE EXTENSION pg_transport;
    benchdb-> \dt+
                              関係のリスト
     スキーマ |       名前       | 種類  |  所有者  |  サイズ   | 説明
    --------+------------------+-------+---------+---------+-------------
     public | pgbench_accounts | テーブル | dbadmin | 125 GB  |
     public | pgbench_branches | テーブル | dbadmin | 392 kB  |
     public | pgbench_history  | テーブル | dbadmin | 0 bytes |
     public | pgbench_tellers  | テーブル | dbadmin | 4360 kB |
  1. 次のクエリを入力して、ソースデータベース設定パラメータが新しいパラメーターグループを介して更新されたことを確認します。
    select name, setting,unit from pg_settings where name in ('shared_preload_libraries','max_worker_processes',
    'pg_transport.num_workers','pg_transport.timing','pg_transport.work_mem'); 

これで、ソース環境が完全に設定されました。

ターゲット環境の設定

ターゲット環境を設定するには、次の手順を実行します。

  1. 新しいパラメータグループを作成し、pgtarget (ターゲット RDS) インスタンスにアタッチします。次のコマンドを参照してください。
    aws rds create-db-parameter-group --db-parameter-group-name pg11-target-transport-group --db-parameter-group-family postgres11  --description "Parameter group with transport parameters enabled"
  2. pg_transport 関連パラメータを設定します。shared_preload_libraries を通じて拡張機能を読み込み、max_worker_processes を更新します。ソース DB インスタンスと転送先 DB インスタンスの両方で max_worker_processes を、pg_transport.num_workers パラメータに対する転送先 DB インスタンスでの設定の少なくとも 3 倍に設定する必要があります。さらにいくつかを追加して、非トランスポートバックグラウンドワーカープロセスを提供します。この記事では、max_worker_processes の値を 24 に設定します。次のコマンドを参照してください。
    aws rds modify-db-parameter-group \
        --db-parameter-group-name pg11-target-transport-group \
        --parameters "ParameterName=pg_transport.num_workers,ParameterValue=4,ApplyMethod=immediate" \
                     "ParameterName=pg_transport.timing,ParameterValue=1,ApplyMethod=immediate" \
                     "ParameterName=pg_transport.work_mem,ParameterValue=131072,ApplyMethod=immediate" \
                     "ParameterName=shared_preload_libraries,ParameterValue=\"pg_stat_statements,pg_transport\",ApplyMethod=pending-reboot"\
                     "ParameterName=max_worker_processes,ParameterValue=24,ApplyMethod=pending-reboot"
  3. 新しく作成したパラメータグループを使用して、ターゲット RDS インスタンスを更新します。shared_preload_librariesmax_worker_processes などの静的パラメータの変更により、インスタンスを再起動する必要があります。次のコマンドを参照してください。
    aws rds modify-db-instance --db-instance-identifier pgtarget --db-parameter-group-name pg11-target-transport-group —apply-immediately
    aws rds reboot-db-instance —db-instance-identifier pgtarget
  4. 次のクエリを入力して、ターゲットデータベース設定パラメータが新しいパラメーターグループを介して更新されたことを確認します。
    select name, setting,unit from pg_settings where name in ('shared_preload_libraries','max_worker_processes',
    'pg_transport.num_workers','pg_transport.timing','pg_transport.work_mem');
  5. RDS インスタンスが起動したら、psql を介してインスタンスへの接続を確認します。ターゲット環境に、ソースと同じ名前のデータベースが含まれていないことを確認してください。次のコマンドを参照してください。
    psql -h pgtarget.<identifier>.<AWS Region>.rds.amazonaws.com -d postgres -U <RDS Master User>
    postgres-> \l  
    注意: \l オプションはデータベースを一覧します。
  6. 次のコマンドを使用して、転送先インスタンスで pg_transport 拡張を設定します。
    postgres-> CREATE EXTENSION pg_transport;

pg_transport のテスト

これで、ソースおよびターゲット環境を完全に設定したので、この機能をテストする準備が整いました。pg_transport は、実際のデータ転送の前に両方の環境を検証する簡単なオプションを提供します (移行の予行演習)。

  1. transport.import_from_server 関数を使用して、移行を実行します。パラメータ dry_run=true を設定します。次のコマンドを参照してください。
    psql -h pgtarget.<identifier>.<AWS Region>.rds.amazonaws.com -d postgres -U <RDS Master User>
    
    SELECT transport.import_from_server('pgsource.<identifier>.<AWS Region>.rds.amazonaws.com',5432,<Source DB User>,<Source DB User password>,'imdb',<Target DB user password>,true);    --dry run
    INFO:  Starting dry-run of import of database "imdb".
    INFO:  Created connections to remote database        (took 0.02 seconds).
    INFO:  Checked remote cluster compatibility          (took 0.05 seconds).
    INFO:  Dry-run complete                         (took 0.08 seconds total).
     import_from_server
    --------------------
    
    (1 行)
  2. 予行演習が成功したら、データベースの移行を開始します。パラメータ値を false に変更します (dry_run=false)。次のコマンドを参照してください。
    postgres=>SELECT transport.import_from_server('pgsource.<identifier>.<AWS Region>.rds.amazonaws.com',5432,<Source DB User>,<Source DB User password>,'imdb',<Target DB user password>,false);
    
    INFO:  Starting import of database "imdb".
    INFO:  Created connections to remote database        (took 0.04 seconds).
    INFO:  Marked remote database as read only           (took 2.13 seconds).
    INFO:  Checked remote cluster compatibility          (took 0.02 seconds).
    INFO:  Signaled creation of PITR blackout window     (took 2.01 seconds).
    INFO:  Applied remote database schema pre-data       (took 0.65 seconds).
    INFO:  Created connections to local cluster          (took 0.01 seconds).
    INFO:  Locked down destination database              (took 0.00 seconds).
    INFO:  16.36% of files transported
    INFO:  23.64% of files transported (current rate is ~300 MB/sec)
    INFO:  34.55% of files transported (current rate is ~285 MB/sec)
    INFO:  38.18% of files transported (current rate is ~306 MB/sec)
    INFO:  41.82% of files transported (current rate is ~256 MB/sec)
    INFO:  49.09% of files transported (current rate is ~274 MB/sec)
    INFO:  58.18% of files transported (current rate is ~298 MB/sec)
    INFO:  63.64% of files transported (current rate is ~281 MB/sec)
    INFO:  81.82% of files transported (current rate is ~287 MB/sec)
    INFO:  90.91% of files transported (current rate is ~268 MB/sec)
    INFO:  Completed transfer of database files          (took 52.87 seconds).
    INFO:  Completed clean up                            (took 1.02 seconds).
    INFO:  Physical transport complete              (took 58.76 seconds total).
     import_from_server
    --------------------
    
    (1 行)
    
    postgres=> \c imdb
    imdb=> SELECT pg_size_pretty( pg_database_size('imdb') ); ## データベースのサイズを確認
     pg_size_pretty
    ----------------
     14 GB
    (1 行)

    この記事では、14 GB の imdb データベースの転送に 60 秒もかかりませんでした。
    pg_transport のパフォーマンスを理解するために、この記事では、pg_dump および pg_restore メソッドを使用して同じ imdb データベースのインポートをテストしました。次のコマンドを参照してください。

    pg_dump -Fc -v -h pgsource.<identifier>.<AWS Region>.rds.amazonaws.com -U [RDS Master User] imdb > imdb.dump
    pg_restore -v -h pgtarget.<identifier>.<AWS Region>.rds.amazonaws.com -U [RDS Master User] -d imdb  imdb.dump

    1 分もかからなかった pg_transport とは対照的に、約 8 分かかりました。
    データベースの転送が進行中の間は、読み取り専用クエリのみを実行できます。たとえば、imdb データベース title_rating のテーブルを更新しようとすると、次のエラーが表示されます。

    psql -h pgsource.<identifier>.<AWS Region>.rds.amazonaws.com -d imdb -U <RDS Master User>
    imdb=> update title_ratings set "averageRating"=7, "numVotes"=3000 where tconst=1;
    ERROR: cannot execute UPDATE in a read-only transaction
  1. pgbench データベース benchdb の移行についても同じ手順を繰り返します。次のコマンドを参照してください。
    postgres=>SELECT transport.import_from_server('pgsource.<identifier>.<AWS Region>.rds.amazonaws.com',5432,<Source DB User>,<Source DB User password>,'benchdb',<Target DB user password>,false);
    
    .........
    INFO:  Completed transfer of database files          (took 565.60 seconds).
    INFO:  Completed clean up                            (took 1.04 seconds).
    INFO:  Physical transport complete              (took 569.51 seconds total).

    pg_transport.num_workers=8 および max_worker_processes=40 では約 569 秒かかりました。これらのテストが行われたとき、ソースおよびターゲットの RDS インスタンスで実行されていた他のワークロードまたはクエリはありませんでした。 転送速度は、ソースおよびターゲットのシステムでの負荷、インスタンスタイプ、RDS パラメータの設定などの要因により異なる場合があります。

ベストプラクティス

大規模データベース (約 200 GB) の場合、pg_transport に関連するパラメータを変更できます。たとえば、pg_transport.num_workers を 8 に、max_worker_processesnum_workers. pg_transport プロセスがインスタンスレベルで消費するメモリリソースの数の3倍に増やすことができます。ただし、これはソースとターゲットの両方で実行中の他のデータベースに影響を与える可能性があります。したがって、実稼働環境で変更を適用する前に、開発環境で設定を計画およびテストしてください。

pg_transport.work_mem は、各ワーカープロセスに割り当てられます (たとえば、pg_transport.num_workers)。インスタンスに使用可能な十分な空きメモリがあることを確認してください。詳細については、Amazon RDS のベストプラクティスを参照してください。

pg_transport を設定すると、max_worker_processesshared_preload_libraries などの静的パラメーターを変更するため、インスタンスを再起動する必要があります。したがって、頻繁な変更を避けるために、データベース環境に基づいてこれらのパラメータをテストおよび標準化することをお勧めします。

データベースを転送した後、データベースアクセス要件に従って、ターゲットで適切なロールとアクセス許可を設定します。さらに、アプリケーションの必要に応じて拡張機能を有効にできます。

まとめ

この記事では、RDS PostgreSQL トランスポータブルデータベース機能のユースケースを提供し、pg_transport 拡張機能を設定する際の重要な考慮事項と、従来のダンプおよびロード方式よりもパフォーマンスが優れていることを強調しました。 ご使用の環境でこの機能を試してみることをお勧めします。いつものように、AWS はフィードバックを歓迎します。コメントや質問を以下に残してください。

 


著者について

 

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