Azure Database for PostgreSQL へのシームレスな移行に関するベスト プラクティス

適用対象: Azure Database for PostgreSQL - フレキシブル サーバー

この記事では、Azure Database for PostgreSQL への移行で発生することがよくある落とし穴と、それを円滑に成功させるためのベスト プラクティスについて説明します。

移行前の検証

移行の最初のステップとして、移行を実行する前に移行前の検証を行います。 移行の [セットアップ] ページの [検証] および [検証と移行] オプションを使用できます。 移行前の検証では、定義済みのルール セットに対して徹底的な検査が行われます。 目的は、潜在的な問題を明らかにし、是正措置のための役に立つ分析情報を提供することです。 結果が成功状態になるまで、移行前の検証を実行し続けます。 詳細については、移行前の検証に関するページを参照してください。

ターゲット フレキシブル サーバーの構成

データの最初の基本コピーのときに、複数の INSERT ステートメントが移行先に対して実行され、これによって先行書き込みログ (WAL) が生成されます。 これらの WAL がアーカイブされるまで、ログによって、移行先のストレージと、データベースに必要なストレージが消費されます。

その数値を計算するには、移行元インスタンスにサインインして、次のコマンドを移行対象のすべてのデータベースに対して実行します。

SELECT pg_size_pretty( pg_database_size('dbname') );

十分なストレージをフレキシブル サーバー上で割り当てることをお勧めします。具体的には、上記のコマンドの出力で得られた現在の使用量の 1.25 倍つまり 25% を追加した容量です。 ストレージの自動拡張も使用できます。

重要

ストレージ サイズは、手動構成またはストレージの自動拡張で減らすことはできません。 一連のストレージ構成の中で、1 つ上を選ぶとサイズが 2 倍になるため、必要な容量を事前に見積もることをお勧めします。

ポータルを使用して Azure Database for PostgreSQL - フレキシブル サーバーのインスタンスを作成するクイックスタートから始めることをお勧めします。 各サーバー構成に関する詳細情報については、Azure Database for PostgreSQL - フレキシブル サーバーのコンピューティングとストレージのオプションに関するページを参照してください。

移行のタイムライン

各移行の有効期間は開始から最大 7 日間 (168 時間) であり、7 日後にタイムアウトとなります。 データの検証とすべてのチェックが完了した後に移行とアプリケーションの一括移行を完了することによって、移行のタイムアウトを回避できます。オンライン移行では、最初の基本コピーが完了した後の一括移行の時間枠は 3 日間 (72 時間) で、これを過ぎるとタイムアウトとなります。オフライン移行では、データ損失を防ぐために、アプリケーションによるデータベースへの書き込みを停止する必要があります。 同様に、オンライン移行の場合は、移行が完了するまでの間、トラフィック量を低く抑えてください。

ほとんどの非運用サーバー (開発、UAT、テスト、ステージング) は、オフライン移行を使って移行されます。 これらのサーバーのデータは運用サーバーよりも少ないため、移行は短時間で完了します。 運用サーバーの移行では、事前に計画するため、移行が完了するまでにかかる時間を把握しておく必要があります。

移行が完了するまでにかかる時間は、いくつかの要因によって異なります。 これには、データベースの数、サイズ、各データベース内のテーブルの数、インデックスの数、テーブル間のデータの分散などが含まれます。 また、移行先サーバーの SKU と、移行元インスタンスと移行先サーバーで使用できる IOPS にも左右されます。 移行時間に影響を与える可能性のある要因はきわめて多いため、移行の完了に要する時間の合計を見積もることは困難です。 最善の方法は、実際のワークロードを使ってテスト移行を実行することです。

運用サーバーの移行を実行するための合計ダウンタイムを計算するには、次のフェーズを考慮します。

  • PITR の移行: 運用データベース サーバーの移行に要する時間を適切に見積もる最善の方法は、運用サーバーのポイントインタイム リストア (PITR) を利用して、この新しく復元されたサーバーでオフライン移行を実行することです。

  • バッファーの移行: 前述のステップが完了した後に、実際の運用環境の移行をアプリケーションのトラフィックが少ない時間帯に行うための計画を立てます。 この移行は、同日に計画することも、場合によっては 1 週間後に計画することもできます。 この時点で、ソース サーバーのサイズが増えている可能性があります。 この増加の量に基づいて、運用サーバーの推定移行時間を更新してください。 増加が著しい場合は、PITR サーバーを使用して再度テストすることを検討してください。 しかし、ほとんどのサーバーでは、サイズが著しく増えることはないはずです。

  • データの検証: 運用サーバーの移行が完了した後に、フレキシブル サーバー内のデータが移行元インスタンスの正確なコピーであるかどうかを検証する必要があります。 オープンソースまたはサードパーティ製のツールを使うことも、手動で検証を行うこともできます。 行う必要がある検証のステップを、実際の移行の前に準備してください。 検証には、次のものが含まれます。

    • 移行に関連するすべてのテーブルの行数が一致していること。

    • すべてのデータベース オブジェクト (テーブル、シーケンス、拡張機能、プロシージャ、インデックス) の数を照合する。

    • 主要なアプリケーション関連の列の最大または最小の ID を比較する。

      Note

      データベースのサイズ比較は、検証に適したメトリックではありません。 移行元インスタンスにブロートやデッド タプルが存在することがあり、これが原因で移行元インスタンスのサイズが増大する可能性があります。 移行元インスタンスと移行先サーバーの間でサイズが異なるのは、正常なことです。 前述の検証の 3 つのステップで問題がある場合は、移行に問題があることを示しています。

  • サーバー設定の移行: カスタムのサーバー パラメーター、ファイアウォール規則 (該当する場合)、タグ、アラートがある場合は、これらを移行元インスタンスから移行先に手動でコピーする必要があります。

  • 接続文字列の変更: 検証が成功した後に、アプリケーションの接続文字列をフレキシブル サーバーに変更する必要があります。 この作業では、アプリケーション チームと連携して、移行元インスタンスをポイントしている接続文字列のすべての参照を変更します。 フレキシブル サーバーの接続文字列では、user=username という形式でユーザー パラメーターを使用できます。

例: psql -h myflexserver.postgres.database.azure.com -u user1 -d db1

ほとんどの場合、移行は問題なく実行されますが、不測の事態が発生してデバッグに多くの時間がかかる場合や移行のやり直しが必要になる場合に備えた計画を立てておくことをお勧めします。

移行速度のベンチマーク

次の表は、移行サービスを使ってデータベースの移行を実行するのに要する時間をサイズ別にまとめたものです。 この移行は SKU Standard_D4ds_v4 (4 コア、16 GB メモリ、128 GB ディスク、500 IOPS) のフレキシブル サーバーを使用して実行されました。

データベース サイズ おおよその所要時間 (HH:MM)
1 GB 00:01
5 GB 00:03
10 GB 00:08
50 GB 00:35
100 GB 01:00
500 GB 04:00
1,000 GB 07:00

上記の数値は、移行の完了に要する時間の概算値です。 実際のワークロードでテスト移行を実行し、サーバーの移行に関する正確な値を取得することを強くお勧めします。

重要

移行をより短時間で実行するには、これよりも上位の SKU をフレキシブル サーバー用に選択してください。 Azure Database for PostgreSQL - フレキシブル サーバーでは、ダウンタイムがほぼゼロのコンピューティングと IOPS のスケーリングがサポートされているため、ダウンタイムを最小限に抑えて SKU を更新できます。 SKU は、移行後にアプリケーションのニーズに合わせていつでも変更できます。

移行速度の向上: テーブルの並列移行

PostgreSQL 移行サービスはフレキシブル サーバー上の 1 つのコンテナーから実行されるため、移行先には強力な SKU を使うことをお勧めします。 SKU が強力であるほど、より多くのテーブルを並列に移行できます。 移行後に、SKU を任意の構成にスケールバックできます。 このセクションでは、テーブル間のデータ分散のバランスをさらに均等にする必要がある場合や SKU を強力にしても移行速度がそれほど変わらない場合に、移行速度を向上させるためのステップを紹介します。

移行元でのデータの分散に大きな偏りがあり、データのほとんどが 1 つのテーブルに存在する場合は、移行用に割り当てられたコンピューティングをフルに利用する必要があり、その結果としてボトルネックが発生します。 そのため、大きなテーブルは小さなチャンクに分割され、これらが並列で移行されます。 この機能は、タプル数が 1,000,000 (100 万) を超えるテーブルに適用されます。 テーブルを小さなチャンクに分割できるのは、次のいずれかの条件を満たしている場合です。

  • テーブルに int 型または significant int 型の単純 (複合型ではない) 主キーまたは一意のインデックスの列がある。

    Note

    最初または 2 番目のアプローチでは、移行元スキーマに一意のインデックスの列を追加することによる影響を慎重に評価する必要があります。 一意のインデックスの列を追加してもアプリケーションに影響を与えないことが確認された場合に限り、その変更を行うようにしてください。

  • テーブルに int 型または significant int 型の単純主キーも一意のインデックスもないが、このデータ型の条件を満たす列がある場合は、次のコマンドを使用してその列を一意のインデックスに変換できます。 このコマンドでは、テーブルに対するロックは必要ありません。

        create unique index concurrently partkey_idx on <table name> (column name);
    
  • テーブルに simple int/big int の主キーも一意のインデックスもなく、データ型の条件を満たす列もない場合は、条件を満たす列を ALTER を使用して追加して移行後に削除することができます。 ALTER コマンドを実行するには、テーブルに対するロックが必要です。

        alter table <table name> add column <column name> big serial unique;
    

前述の条件のいずれかが満たされていれば、テーブルが複数のパーティションに分割されて並列で移行されるため、移行速度が大幅に向上します。

しくみ

  • 移行サービスは、分割して並列で移行する必要があるテーブルの主キーまたは一意のインデックスの、最大と最小の整数値を見つけます。
  • 最小値と最大値の差が 1,000,000 (100 万) を超える場合は、そのテーブルは複数の部分に分割されて、各部分が並列で移行されます。

まとめると、PostgreSQL 移行サービスは、次の場合にテーブルを並列スレッドで移行して、移行時間を短縮します。

  • テーブルに、int 型または significant int 型の単純な主キーまたは一意なインデックスを含む列があります。
  • テーブルに少なくとも 1,000,000 (100 万) 行があり、したがって主キーの最小値と最大値の差が 1,000,000 (100 万) を超えている。
  • 使用される SKU には、テーブルの並列移行に利用できるアイドル状態のコアがある。

PostgreSQL データベース内の肥大化のバキューム処理

時間の経過とともに、データが追加、更新、削除されて、PostgreSQL にデッド行や無駄なストレージ領域が蓄積する可能性があります。 この肥大化により、ストレージ要件が増加し、クエリのパフォーマンスが低下する可能性があります。 バキューム処理は、この無駄な領域を再利用し、データベースが効率的に動作することを保証する重要なメンテナンス タスクです。 バキューム処理によって、デッド行やテーブル ブロートなどの問題に対処できるので、ストレージを効率的に使用できるようになります。 また、移行時間の短縮にも役立ちます。移行に要する時間は、データベース サイズによって決まるためです。

PostgreSQL には、デッド行によって占有されているストレージを再利用するための VACUUM コマンドがあります。 ANALYZE オプションを指定すると、クエリのプランニングをさらに最適化するための統計情報も収集されます。 書き込みアクティビティが多いテーブルの場合は、VACUUM FULL を使用すると VACUUM プロセスがよりアグレッシブになりますが、実行に要する時間が長くなります。

  • 標準バキューム

    VACUUM your_table;
    
  • バキュームと分析

    VACUUM ANALYZE your_table;
    
  • 書き込みが多いテーブル用のアグレッシブ バキューム

    VACUUM FULL your_table;
    

この例では、your_table を実際のテーブル名に置き換えます。 VACUUM コマンドに FULL を付けない場合は領域を効率的に再利用できますが、VACUUM ANALYZE を指定した場合はクエリ プランニングが最適化されます。 VACUUM FULL オプションは、パフォーマンスへの影響が大きいため、慎重に使用する必要があります。

データベースの中には、画像やドキュメントなどのラージ オブジェクトを格納するものがありますが、これらは時間の経過とともにデータベース ブロートの原因となる可能性があります。 VACUUMLO コマンドは、PostgreSQL 内のラージ オブジェクト用に設計されています。

  • ラージ オブジェクトのバキューム処理

    VACUUMLO;
    

これらのバキューム戦略を定期的に組み込むことで、適切に管理された PostgreSQL データベースが確保されます。

特別な考慮事項

チュートリアルまたはモジュールに進む前に認識しておく必要のある、特別な条件があります (一般的には固有の状況、構成、または前提条件を指します)。 この条件に含まれるものとしては、学習コンテンツの修了に必要な特定のソフトウェア バージョン、ハードウェア要件、またはその他のツールがあります。

オンライン移行

オンライン移行では pgcopydb follow が使用され、いくつかの論理デコード制限が適用されます。 また、オンライン移行対象のデータベースのすべてのテーブルに主キーを持たせることをお勧めします。 主キーがない場合は、その結果として insert 操作のみが移行時に反映されることになり、更新や削除は除外されます。 オンライン移行に進む前に、関係するテーブルに一時的な主キーを追加してください。

Note

オンライン移行するテーブルに主キーがない場合は、insert 操作のみが移行先で再生されます。 この結果として、移行元で更新または削除されたレコードが移行先に反映されない場合にデータベースの不整合が生じる可能性があります。

別の方法として、ALTER TABLE コマンドを使用することができます。アクションは REPLICA IDENTIY で、FULL オプションを指定します。 FULL オプションを指定すると、行内のすべての列の古い値が記録されるので、主キーが存在しない場合でも、オンライン移行時に CRUD すべての操作が移行先に反映されます。 これらのオプションが機能しない場合は、代わりにオフライン移行を実行してください。

postgres_fdw 拡張機能を持つデータベース

postgres_fdw モジュールで提供される外部データ ラッパー postgres_fdw を使用すると、外部 PostgreSQL サーバーに格納されているデータにアクセスできます。 データベースでこの拡張機能が使われている場合は、移行を成功させるために次の手順を実行する必要があります。

  1. 移行元インスタンス上で、外部データ ラッパーを一時的に削除 (リンク解除) します。
  2. 残りのデータ移行を、移行サービスを使って実行します。
  3. 移行後に、移行先で外部データ ラッパーのロール、ユーザー、リンクを復元します。

postGIS 拡張機能を持つデータベース

PostGIS 拡張機能のバージョン間には、破壊的変更や圧縮の問題があります。 フレキシブル サーバーに移行する場合は、より新しいバージョンの PostGIS に対してアプリケーションを調べて、アプリケーションへの影響がないことを確認してください。影響がある場合は変更が必要になります。 postGIS ニュースリリース ノートが、バージョン間の破壊的変更を理解するための出発点として適しています。

データベース接続のクリーンアップ

移行を開始するときに、このエラーが発生することがあります。

CL003:Target database cleanup failed in the pre-migration step. Reason: Unable to kill active connections on the target database created by other users. Please add the pg_signal_backend role to the migration user using the command 'GRANT pg_signal_backend to <migrationuser>' and try a new migration.

このシナリオでは、データベースへのアクティブな接続をすべて閉じるためのアクセス許可を migration user に付与するか、接続を手動で閉じてから移行を再試行してください。