

# DB インスタンス 間での PostgreSQL データベースの移行
<a name="PostgreSQL.TransportableDB"></a>

Amazon RDS の PostgreSQL トランスポータブルデータベースを使用することで、2 つの DB インスタンス間で PostgreSQL データベースを移行できます。この手法により、異なる DB インスタンス間での大規模なデータベースの移行が大幅に高速化されます。このアプローチを使用するには、対象の DB インスタンスの両方で、PostgreSQL の同じ主要バージョンを実行している必要があります。

この機能を使用するには、移行元の DB インスタンスと移行先の DB インスタンスで、ともに `pg_transport` 拡張機能をインストールします。`pg_transport` 拡張は、最小限のプロセスでデータベースファイルを移動するための、物理的な移行メカニズムを提供します。このメカニズムにより、ダンプとロードによる従来のプロセスと比較してデータの移行が大幅に高速化され、ダウンタイムが最小限に抑えられます。

**注記**  
PostgreSQL トランスポータブルデータベースは、RDS for PostgreSQL 11.5 以降、および RDS for PostgreSQL のバージョン 10.10 以降で利用可能です。

ある RDS for PostgreSQL DB インスタンスから別のインスタンスへの、PostgreSQL DB インスタンスの移行を行うには、最初に、「[ 移行に向けた DB インスタンスの設定](PostgreSQL.TransportableDB.Setup.md)」での説明に従いながら、ソースインスタンスとデスティネーションインスタンスの設定を行います。その後、「[ PostgreSQL データベースの移行](PostgreSQL.TransportableDB.Transporting.md)」で説明されている関数を使用してデータベースを移行します。

**Topics**
+ [データベースの移行中に何が起こるか](#PostgreSQL.TransportableDB.DuringTransport)
+ [PostgreSQL トランスポータブルデータベースの使用に関する制約事項](#PostgreSQL.TransportableDB.Limits)
+ [PostgreSQL データベース移行の設定](PostgreSQL.TransportableDB.Setup.md)
+ [移行元から移行先への PostgreSQL データベースの転送](PostgreSQL.TransportableDB.Transporting.md)
+ [トランスポータブルデータベースの関数リファレンス](PostgreSQL.TransportableDB.transport.import_from_server.md)
+ [トランスポータブルデータベースのパラメータリファレンス](PostgreSQL.TransportableDB.Parameters.md)

## データベースの移行中に何が起こるか
<a name="PostgreSQL.TransportableDB.DuringTransport"></a>

PostgreSQL のトランスポータブルデータベース機能は、移行先 DB インスタンスが移行元 DB インスタンスからデータベースをインポートするプルモデルを使用します。`transport.import_from_server` 関数を使うと、移行先 DB インスタンスで移行中のデータベースが作成されます。移行中、移行中のデータベースは、移行先 DB インスタンスではアクセスすることはできません。

移行スタートの際は、移行元データベースのすべての現在のセッションが終了します。移行元 DB インスタンスの移行元データベース以外のすべてのデータベースには移行による影響はありません。

移行元データベースは、特別な読み取り専用モードとなります。このモードの最中は、移行元データベースにアクセス可能で、読み取り専用のクエリを実行できます。ですが、書き込み可能なクエリやその他の種類のコマンドはブロックされます。移行された特定の移行元データベースのみがこれら制限による影響を受けます。

移行中、移行元 DB インスタンスは、ポイントインタイムの復元はできません。これは、移行がトランザクションではなく、変更を記録するための PostgreSQL ログ先行書き込みを使用しないからです。移行先 DB インスタンスの自動バックアップが有効になっていれば、移行後に、バックアップが自動で実行されます。ポイントインタイムの復元は、バックアップが終了した*後*に実行が可能になります。

移行に失敗した場合、`pg_transport` のエクステンションが、移行先/元 DB インスタンスで行ったすべての変更をやり直します。これには、移行先で一部のみ移行されたデータベースの削除も含まれます。失敗の内容によっては、移行元データベースで引き続き、書き込み可能クエリが拒否されます。これが発生した場合、以下のコマンドを使い、書き込み可能クエリを許可します。

```
ALTER DATABASE db-name SET default_transaction_read_only = false;
```

## PostgreSQL トランスポータブルデータベースの使用に関する制約事項
<a name="PostgreSQL.TransportableDB.Limits"></a>

トランスポータブルデータベースには以下の制限があります。
+ **リードレプリカ** - リードレプリカまたはリードレプリカの親インスタンスでは、トランスポータブルデータベースを使用できません。
+ **サポートされていない列タイプ** - このメソッドを使用して移行するすべてのデータベーステーブル内の `reg` データ型を使用することはできません。これらタイプは、システムカタログオブジェクト ID (OID) に依存し、移行中に変わることがあります。
+ **テーブルスペース**　-すべてのソースデータベースオブジェクトは既定の `pg_default` テーブルスペースに既存しなければいけません。
+ **互換性** - 移行先および移行元両方の DB インスタンスは、PostgreSQL の同じ主要バージョンを実行しなければなりません。
+ **拡張機能** – 移行元 DB インスタンスには、`pg_transport` のみがインストールされています。
+ **ロールおよび ACL** - 移行元データベースのアクセス権限および所有権情報は、移行先データベースには移行されません。すべてのデータベースオブジェクトは、移行するローカルの移行先ユーザーが作成および所有します。
+ **同時移行数** – ワーカープロセスが適切に設定されていれば、単一の DB インスタンスで同時に最大 32 個の (インポートとエクスポートの両方を含む) 移行をサポートできます。
+ **RDS for PostgreSQL DB インスタンスのみ** – PostgreSQL のトランスポータブルデータベースは、RDS for PostgreSQL DB インスタンスでのみサポートされます。オンプレミスのデータベースや Amazon EC2 で実行されているデータベースでは使用できません。

# PostgreSQL データベース移行の設定
<a name="PostgreSQL.TransportableDB.Setup"></a>

この作業を開始する前に、対象の RDS for PostgreSQL DB インスタンスが、以下の要件を満たしていることを確認してください。
+ 移行先および移行元両方の RDS for PostgreSQL DB インスタンスは、PostgreSQL の同じバージョンを実行している必要があります。
+ 移行先の DB は、移行する元である DB と同じ名前のデータベースを持つことはできません。
+ 移行を実行するために使用するアカウントでは、移行元と移行先の両方の DB で、`rds_superuser` の権限が付与される必要があります。
+ 移行元 DB インスタンスのセキュリティグループは、移行先 DB インスタンスからのインバウンドアクセスを許可する必要があります。この許可は、移行元と移行先の DB インスタンスが VPC 内に存在する場合には、既に設定されている場合があります。セキュリティグループの詳細については、[セキュリティグループによるアクセス制御](Overview.RDSSecurityGroups.md) を参照してください。

データベースを移行元 DB インスタンスから移行先 DB インスタンスに移行する際には、各インスタンスに関連付けられた DB パラメータグループをいくつか変更する必要があります。つまり、移行元の DB インスタンスと移行先の DB インスタンスのそれぞれのために、カスタムの DB パラメータグループを作成する必要があります。

**注記**  
DB インスタンスで、カスタム DB パラメータグループの使用が設定済みである場合は、以下の手順のステップ 2 から開始できます。

**データベースを移行するためのカスタム DB グループパラメータを構成するには**

以下の手順では、`rds_superuser` の権限を持つアカウントを使用します。

1. 移行元と移行先の DB インスタンスがデフォルトの DB パラメータグループを使用している場合は、そのインスタンス用として適切なバージョンの、カスタム DB パラメータグループを作成する必要があります。これにより、複数のパラメータの値を変更できるようになります。詳細については、「[Amazon RDS のパラメータグループ](USER_WorkingWithParamGroups.md)」を参照してください。

1. カスタム DB パラメータグループ内で、以下のパラメータの値を変更します。
   + `shared_preload_libraries` – ライブラリのリストに `pg_transport` を追加します。
   + `pg_transport.num_workers` – デフォルト値は 3 です。データベースの必要に応じて、この値を増減します。200 GB のデータベースでは、8 以下を推奨します。このパラメータのデフォルト値を増加させた場合は、`max_worker_processes` の値も増やす必要があることに注意してください。
   + `pg_transport.work_mem` – デフォルト値は、PostgreSQL のバージョンによって 128 MB または 256 MB のどちらかになります。デフォルト設定は、通常、特に変更する必要はありません。
   + `max_worker_processes` — このパラメータの値は、次の計算を使用して設定する必要があります。

     ```
     (3 * pg_transport.num_workers) + 9
     ```

     この値は、トランスポートに関連するさまざまなバックグラウンドワーカープロセスを処理するために、接続先で必要です。`max_worker_processes,` の詳細については、PostgreSQL ドキュメントの「[Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html)」(資源の消費) を参照してください。

   `pg_transport` パラメータの詳細については、「[トランスポータブルデータベースのパラメータリファレンス](PostgreSQL.TransportableDB.Parameters.md)」を参照してください。

1. 移行元と移行先の RDS for PostgreSQL DB インスタンスをともに再起動して、パラメータの設定を有効にします。

1. 移行元の RDS for PostgreSQL DB インスタンスに接続します。

   ```
   psql --host=source-instance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. DB インスタンスのパブリックスキーマから無関係な拡張機能を削除します。実際の移行オペレーション中に使用が許可されるのは、`pg_transport` 拡張機能のみです。

1. 次のように `pg_transport` 拡張機能をインストールします。

   ```
   postgres=> CREATE EXTENSION pg_transport;
   CREATE EXTENSION
   ```

1. 移行先の RDS for PostgreSQL DB インスタンスに接続します。無関係な拡張機能をすべて削除した上で、`pg_transport` 拡張機能をインストールします。

   ```
   postgres=> CREATE EXTENSION pg_transport;
   CREATE EXTENSION
   ```

# 移行元から移行先への PostgreSQL データベースの転送
<a name="PostgreSQL.TransportableDB.Transporting"></a>

[PostgreSQL データベース移行の設定](PostgreSQL.TransportableDB.Setup.md) で記載したプロセスを完了すると、移行をスタートすることが可能です。移行をスタートするには、移行先 DB インスタンスで `transport.import_from_server` 関数を実行します。次の構文では、関数に使用するパラメータを確認できます。

```
SELECT transport.import_from_server( 
   'source-db-instance-endpoint', 
    source-db-instance-port, 
   'source-db-instance-user', 
   'source-user-password', 
   'source-database-name', 
   'destination-user-password', 
   false);
```

この例での `false` 値は、この処理がドライランではないことを関数に伝えます。移行の設定をテストするには、以下のように、関数の呼び出し時に `dry_run` オプションで `true` を指定します。

```
postgres=> SELECT transport.import_from_server(
    'docs-lab-source-db.666666666666aws-region.rds.amazonaws.com', 5432,
    'postgres', '********', 'labdb', '******', true);
INFO:  Starting dry-run of import of database "labdb".
INFO:  Created connections to remote database        (took 0.03 seconds).
INFO:  Checked remote cluster compatibility          (took 0.05 seconds).
INFO:  Dry-run complete                         (took 0.08 seconds total).
 import_from_server
--------------------

(1 row)
```

`pg_transport.timing` パラメータがデフォルト値の `true` に設定されているため、INFO 行が出力されます。次に示すように、`dry_run` に `false` を設定してコマンドを実行し、データベースを移行元から移行先にインポートします。

```
INFO:  Starting import of database "labdb".
INFO:  Created connections to remote database        (took 0.02 seconds).
INFO:  Marked remote database as read only           (took 0.13 seconds).
INFO:  Checked remote cluster compatibility          (took 0.03 seconds).
INFO:  Signaled creation of PITR blackout window     (took 2.01 seconds).
INFO:  Applied remote database schema pre-data       (took 0.50 seconds).
INFO:  Created connections to local cluster          (took 0.01 seconds).
INFO:  Locked down destination database              (took 0.00 seconds).
INFO:  Completed transfer of database files          (took 0.24 seconds).
INFO:  Completed clean up                            (took 1.02 seconds).
INFO:  Physical transport complete              (took 3.97 seconds total).
import_from_server
--------------------
(1 row)
```

この関数には、データベースユーザーパスワードを入力する必要があります。よって、移行完了後は、使用したユーザーロールのパスワードを変更することをお勧めします。または、SQL のバインド可変を使用するとユーザーロールを一時的に作成することができます。このようなテンポラリロールを移行に使ったら、破棄することが可能です。

移行が成功しなかった場合、次のようなエラーメッセージが表示されることがあります。

```
pg_transport.num_workers=8 25% of files transported failed to download file data
```

「failed to download file data (ファイルデータのダウンロードに失敗しました)」というエラーメッセージは、データベースのサイズに対してワーカープロセスの数が正しく設定されていないことを示します。`pg_transport.num_workers` に設定した値の増減が必要な場合があります。失敗が発生するたびに、処理の完了率がレポートされるため、変更の影響度合いを確認できます。例えば、あるケースで設定を 8 から 4 に変更した場合、次のような結果になります。

```
pg_transport.num_workers=4 75% of files transported failed to download file data
```

`max_worker_processes` パラメーターは、移行のプロセス中にも考慮されることにご留意ください。つまり、データベースを正常に移行するためには、`pg_transport.num_workers` と `max_worker_processes` の両方で変更が必要な場合があります。`pg_transport.num_workers` に 2 を設定することで、最終的にこの例は正しく機能します。

```
pg_transport.num_workers=2 100% of files transported
```

`transport.import_from_server` 関数とそのパラメータの詳細については、「[トランスポータブルデータベースの関数リファレンス](PostgreSQL.TransportableDB.transport.import_from_server.md)」を参照してください。

# トランスポータブルデータベースの関数リファレンス
<a name="PostgreSQL.TransportableDB.transport.import_from_server"></a>

`transport.import_from_server` 関数は、PostgreSQL データベースを移行元 DB インスタンスから移行先 DB インスタンスにインポートします。これは、物理的なデータベース接続移行メカニズムを使って実行されます。

この関数は、移行元と移行先の DB インスタンスが同じバージョンであり、移行のための互換性があることを、移行の開始前に確認します。また、移行先の DB インスタンスに、移行元のサイズに見合うの十分な領域があることも確認します。

**[Syntax]** (構文)

```
transport.import_from_server(
   host text,
   port int,
   username text,
   password text,
   database text,
   local_password text,
   dry_run bool
)
```

**戻り値**

なし。

パラメータ****

`transport.import_from_server` 関数パラメータの説明に関しては、以下のテーブルをご参照ください。


****  

| Parameter | 説明 | 
| --- | --- | 
| host |  移行元 DB インスタンスのエンドポイント。  | 
| port | 整数は、移行元 DB インスタンスを表しています。PostgreSQL DB インスタンスは、通常ポート 5432 を使います。 | 
| username |  移行元 DB インスタンスのユーザー。このユーザーは、`rds_superuser` ロールのメンバーでなければなりません。  | 
| password |  移行元 DB インスタンスのユーザーパスワード。  | 
| database |  移行する移行元 DB インスタンスのデータベース名。  | 
| local\$1password |  移行先 DB インスタンスの現在のユーザーのローカルパスワード。このユーザーは、`rds_superuser` ロールのメンバーでなければなりません。  | 
| dry\$1run | リハーサルを実施するかどうかを判断する任意のブール値。デフォルトは、`false` で、移行を実行することを意味します。実際に移行せずに、移行元と移行先 DB インスタンスの互換性を確認するには、dry\$1run を true に設定します。 | 

**例**

例については、「[移行元から移行先への PostgreSQL データベースの転送](PostgreSQL.TransportableDB.Transporting.md)」を参照してください。

# トランスポータブルデータベースのパラメータリファレンス
<a name="PostgreSQL.TransportableDB.Parameters"></a>

複数のパラメータにより、`pg_transport` 拡張機能の動作が制御されます。以下で、これらのパラメータの説明を参照してください。

**`pg_transport.num_workers`**  
移行プロセスに使用するワーカー数。デフォルトは 3 です。有効な値は、1-32 です。大規模なデータベースを移行する場合でも、通常必要なワーカー数は 8 未満です。移行中には、移行先 DB インスタンスの設定が、移行先および移行元の両方の DB インスタンスで使用されます。

**`pg_transport.timing` **  
移行中にタイミング情報を報告するかどうかを指定します。デフォルトは `true` で、タイミング情報が報告されることを意味します。進行状況を監視できるようにするため、このパラメータは `true` に設定しておくことをお勧めします。出力例については、「[移行元から移行先への PostgreSQL データベースの転送](PostgreSQL.TransportableDB.Transporting.md)」を参照してください。

**`pg_transport.work_mem`**  
メモリの最大容量を各ワーカーに配分する。PostgreSQL のバージョンに応じて、この設定のデフォルトは、131,072 キロバイト (KB) または 262,144 KB (256 MB) のどちらかになります。最小値は 64 メガバイト (65,536 KB) です。2 進法ベースの 2 ユニット (1 KB = 1,024 バイト) なので、有効値は、キロバイト (KB) で表記されます。  
移行は、このパラメータで指定されたメモリより少ないメモリを使う場合があります。移行するデータベースが大規模な場合でも、通常必要なメモリは、ワーカー当たり 256 MB (262,144 KB) 未満です。