オンプレミスの PostgreSQL クラスタを Google Cloud に移行する

この記事では、オンプレミスの PostgreSQL クラスタを Google Cloud に移行する方法について説明します。このアプローチは、PgBouncer を接続プーラーとして使用してアプリケーションのダウンタイムを最小限に抑え、結果をモニタリングできるようにツールを設定する際に役立ちます。この記事は、Linux 環境で作業する PostgreSQL 管理者およびシステム管理者を対象としています。

次の図は、オンプレミス マスターの前に配置された PgBouncer インスタンスを示しています。

オンプレミス マスターの前に配置された PgBouncer インスタンスのアーキテクチャ。

接続プールにより、Google Cloud へのフェイルオーバーが発生したときに、クライアントは代替ノードにルーティングされます。アプリケーション構成の再デプロイや、アプリケーション レベルでの変更を行う必要はありません。

次の図は移行を示しています。

Google Cloud への移行アーキテクチャ。

移行を行うには、現在のマスターをシャットダウンし、下位の Google Cloud レプリカをマスターに昇格します。PgBouncer により、トラフィックが Google Cloud 上の新しいマスターノードに再ルーティングされます。

費用

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使用すると、予想使用量に基づいて費用の見積もりを作成できます。

目標

  • Google Cloud に PostgreSQL を設定する。
  • Compute Engine でレプリケーションを設定する。
  • データを新しいインスタンスにシードする。
  • Google Cloud に PostgreSQL クラスタを設定する。
  • 新しいサーバーに切り替える。
  • モニタリングを実装する。

始める前に

このチュートリアルでは、gcloud コマンドと gsutil コマンドを使用します。これらのコマンドは、Cloud Console から起動した Cloud Shell インスタンスから実行できます。ローカルのワークステーションで gcloudgsutil を使用する場合、Cloud SDK をインストールします。このチュートリアルでは、Cloud Shell でコマンドを実行する方法を説明しています。ワークステーション上の Cloud SDK を使用する場合、ここでの説明は環境に合わせて読み替えてください。

  1. Google Cloud アカウントにログインします。Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  3. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. Compute Engine API を有効にします。

    API を有効にする

環境設定

はじめに、次のタスクを行います。

  • Google Cloud に PostgreSQL を設定する。
  • Compute Engine でレプリケーションを設定する。

次に、マスターのレプリケーションを開始する前に、データを新しいインスタンスにシードします。

Google Cloud に PostgreSQL を設定する

ホット スタンバイで高可用性とレプリケーションを行えるように PostgreSQL を設定する方法の説明に従って、Google Cloud に PostgreSQL を設定します。この作業は数分で終わります。Compute Engine 上の Ubuntu 仮想マシン インスタンスで PostgreSQL を構成します。

Compute Engine でレプリケーションを設定する

Google Compute Engine で PostgreSQL を設定する方法の手順で、Compute Engine 上でホット スタンバイ モードで実行されるように PostgreSQL を構成します。2 つの Compute Engine インスタンスを使用します。1 つはプライマリ PostgreSQL サーバーを実行するインスタンスで、もう 1 つはスタンバイ サーバーを実行するインスタンスです。

PostgreSQL を構成するためのプロパティはマスター インスタンスと下位インスタンスで異なりますが、シームレスなフェイルオーバーを可能にするために、プロパティ ファイルは同一である必要があります。

PostgreSQL クラスタ内の下位インスタンスは、recovery.conf ファイルの存在によって示されます。

ほとんどの場合、データベースのデータ ディレクトリをブートディスクから分離することが重要です。この例では、データベース ファイルを /database のマウントに格納します。

次のコマンドを使用して、マスター インスタンスの postgresql.conf ファイルを変更し、レプリケーションを設定します。

wal_level = 'hot_standby'
archive_mode = on
archive_command = 'test ! -f /postgresql/archivedir/%f && cp %p /postgresql/archivedir/%f'
max_wal_senders = 3
listen_addresses = '*'
wal_keep_segments = 8

次のコマンドを使用して、レプリカの postgresql.conf ファイルを変更します。

hot_standby = on
standby_mode = on
primary_conninfo = 'host=${PRIMARY_IP} port=5432 user=repuser'

Read リクエストをレプリカに送信する場合は、マスターの負荷の一部をオフセットできます。

データをシードする

マスター データベースには上限付きのトランザクション ログが含まれているため、PostgreSQL のほとんどの移行では、マスターのレプリケーションを開始する前にデータを新しいインスタンスにシードする必要があります。次のいずれかの方法でデータをシードできます。

  • Pg_dump を使用して、単一のデータベースをスクリプトまたはアーカイブ ファイルにダンプします。
  • Pg_basebackup を使用して、実行中のデータベース クラスタのバイナリコピーを取得します。
  • rsync を使用して、データフォルダをレプリカにコピーします。
  • 以前のバックアップをレプリカに復元します。

これらのオプションのうち、以前のバックアップをレプリカに復元する方法をおすすめします。このソリューションでは、大量のデータが転送されている間もパフォーマンスへの影響はなく、現在のクラスタは通常どおり動作を続けることができます。

データベースの初期シード後は、rsync コマンドを使用して、バックアップ以降に発生した変更をレプリカにフィードできます。このコマンドでは、2 つのインスタンス間でデータ ディレクトリが同期されます。この手順は、バックアップがマスターより大幅に古くなり、通常のレプリケーションでは同期できない場合に重要です。

Google Cloud での PostgreSQL クラスタの設定

カスケード レプリケーションを使用して PostgreSQL クラスタを作成できます。最初に、次の図に示すようにデータベースを移行します。

現在の環境のアーキテクチャを Google Cloud に移行。

データベースを移行する

  1. 実行中のマスター サーバーから完全バックアップを取得します(label は任意のラベルです)。

    echo "select pg_start_backup('label',true);" |sudo su - postgres -c psql
    sudo tar cvfz postgresql_AAAAMMDD.tar.gz $PGDATA
    

    $PGDATA は、PostgreSQL のメインデータ ディレクトリです。

  2. gs://pg-repo/ という Google Cloud プロジェクトにバケットを作成します。

  3. 作成したバケットにバックアップを転送します。

    master$ gsutil cp postgresql_AAAAMMDD.tar.gz gs://pg-repo/
    
  4. バックアップ ファイルを Google Cloud マスターに転送します。

    new_master$ gsutil cp gs://pg-repo/postgresql_AAAAMMDD.tar.gz
    
  5. バックアップ ファイルを Google Cloud マスターに復元します。

    new_master$ (cd / ; tar xvf postgresql_AAAAMMDD.tar.gz)
    
  6. $PG_DATA ディレクトリに、次の内容を含む recovery.conf ファイルを作成します。

    standby_mode     = 'on'
    primary_conninfo = 'port=5432 host=${running_master_ip} user=${replication_user} application_name=cloud_master'
    trigger_file     = '/tmp/failover.postgresql.5432'
    
  7. PostgreSQL サービスを起動します。

    sudo service postgresql start
    
  8. Google Cloud マスター サーバーが実行中のマスターと同期するまで待ちます。ログに、次のように表示されます。

    tail -f /var/log/postgresql/postgresql*log
    ...
    2018-09-22 17:59:54 UTC LOG:  consistent recovery state reached at 0/230000F0
    2018-09-22 17:59:54 UTC LOG:  database system is ready to accept read only connections
    ...
    

    さらに、master pg_stat_replication を検索すると、cloud_master という名前の新しい下位が接続されているかどうかを判断できます。

    postgres=# \x
    Expanded display is on.
    postgres=# select * from pg_stat_replication where application_name='cloud_master';
    -[ RECORD 1 ]----+------------------------------
    pid              | 16940
    usesysid         | 16402
    usename          | repmgr
    application_name | cloud_master
    ...
    

下位データベースを作成する

  1. データベースとサーバーをシャットダウンします。

    sudo service postgresql stop
    sudo shutdown -h now
    
  2. サービスが停止したことを確認するには、次のコマンドを実行します。

    gcloud compute instances describe master-instance-name | grep status
    

    出力に、インスタンスのステータスが TERMINATED として表示されます。

    status: TERMINATED
    

    次に、新しい下位を作成できるように、データディスクのスナップショットを作成します。

  3. Cloud Console で [スナップショット] ページに移動します。

    [スナップショット] ページに移動

  4. PostgreSQL ディスクから、新しいスナップショットを作成します。

  5. Google Cloud マスター サーバーを起動します。

  6. [VM インスタンス] ページに移動し、master-instance-name をクリックして、[開始] をクリックします。

    PostgreSQL サービスが自動的に起動します。

  7. 確認するには、次のコマンドを実行します。

    ps ax | grep postgres
    

    結果は次のようになります。

     1398 ?     S   0:00 /usr/lib/postgresql/9.3/bin/postgres -D /var/lib/postgresql/9.3/main -c config_file=/etc/postgresql/9.3/main/postgresql.conf
     1454 ?     Ss  0:00 postgres: checkpointer process
     1455 ?     Ss  0:00 postgres: writer process
     1456 ?     Ss  0:00 postgres: wal writer process
     1457 ?     Ss  0:00 postgres: stats collector process
    
  8. Cloud Console で、[VM インスタンス] ページに移動し、[インスタンスを作成] をクリックします。

  9. ブートディスクには、Ubuntu 14.04 を選択します。

  10. [管理、ディスク、ネットワーク、SSH 認証鍵] をクリックし、前に作成したスナップショットに基づいて新しいディスクを追加します。

  11. 新しいサーバーを起動し、ディスクをマウントします。

    sudo mkdir /database && sudo mount /dev/sdb1 /database
    
  12. PostgreSQL をインストールします。

    sudo apt-get install postgresql && sudo service postgresql stop
    
  13. データ ディレクトリとレプリケーション値を構成します。Google Cloud マスターから postgresql.conf ファイルと pg_hba.conf ファイルをコピーし、recovery.conf ファイルを編集して以下の内容を追加します。

    standby_mode = 'on'
    primary_conninfo = 'port=5432 host=${cloud_master_ip} user=${replication_user} application_name=cloud_slave_${identifier}'
    recovery_target_timeline = 'latest'
    
  14. Google Cloud マスターを参照する新しい構成ファイルで PostgreSQL サービスを起動します。

    sudo service postgresql restart
    
  15. サービスが実行されていることを確認します。

    ps ax | grep postgres
    
  16. 次のクエリで Google Cloud マスター サーバーを確認します。

    postgres=# \x
    Expanded display is on.
    postgres=# select * from pg_stat_replication where application_name like 'cloud_slave%';
    -[ RECORD 1 ]----+-----------------------------
    pid              | 2466
    usesysid         | 16402
    usename          | repmgr
    application_name | cloud_slave_1
    ...
    
  17. さらに下位を追加するには、この手順を繰り返します。

新しいサーバーに切り替える

  1. 新しい Google Cloud マスター サーバーを参照するように PgBouncer で構成ファイルを変更します。
  2. PgBouncer インスタンスで、PgBouncer をシャットダウンし、failover.postgresql.5432 トリガー ファイルを使用して新しいマスターをプロモートして、PgBouncer を再起動します。

    service pgbouncer stop ; ssh ${cloud_master_ip} 'touch /tmp/failover.postgresql.5432' ; service pgbouncer start
    

モニタリングを設定する

Google は Blue Medora と連携し、PostgreSQL 指標を提供します。既存の PostgreSQL インスタンスと新しい Google Cloud インスタンスからメトリックやログを収集できます。

Blue Medora の PostgreSQL モニタリング サポートの詳細については、スタートガイドをご覧ください。

サンプルクエリ

サーバー上のすべての同時接続を確認します。

 select * from pg_stat_activity;

(マスター)レプリケーションのステータスを確認します。

select * from pg_stat_replication;

(マスター)レプリカでのデータ適用のラグを確認します。

select pg_xlog_location_diff(write_location, replay_location) from pg_stat_replication;

(マスター)レプリケーションのバイトラグを確認します。

select client_hostname, client_addr, pg_xlog_location_diff(pg_stat_replication.sent_location,
  pg_stat_replication.replay_location)AS byte_lag from pg_stat_replication;

(下位)データベースがレプリカかどうかを確認します。

select pg_is_in_recovery();

(下位)マスターから受信した最後のデータを確認します。

select pg_last_xlog_receive_location();

(下位)マスターから最後に適用されたデータを確認します。

select pg_last_xlog_replay_location();

(下位)レプリケーションの遅延を秒単位で確認します。

select now() - pg_last_xact_replay_timestamp();

クリーンアップ

プロジェクトを削除する

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ

  • Google Cloud に関するリファレンス アーキテクチャ、図、チュートリアル、ベスト プラクティスを確認する。Cloud Architecture Center をご覧ください。
  • Google Cloud プロダクトを使用して、エンドツーエンドのソリューションを作成する方法を学習する。