この記事では、オンプレミスの PostgreSQL クラスタを Google Cloud に移行する方法について説明します。このアプローチは、PgBouncer を接続プーラーとして使用してアプリケーションのダウンタイムを最小限に抑え、結果をモニタリングできるようにツールを設定する際に役立ちます。この記事は、Linux 環境で作業する PostgreSQL 管理者およびシステム管理者を対象としています。
次の図は、オンプレミス マスターの前に配置された PgBouncer インスタンスを示しています。
接続プールにより、Google Cloud へのフェイルオーバーが発生したときに、クライアントは代替ノードにルーティングされます。アプリケーション構成の再デプロイや、アプリケーション レベルでの変更を行う必要はありません。
次の図は移行を示しています。
移行を行うには、現在のマスターをシャットダウンし、下位の Google Cloud レプリカをマスターに昇格します。PgBouncer により、トラフィックが Google Cloud 上の新しいマスターノードに再ルーティングされます。
費用
このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。
目標
- Google Cloud に PostgreSQL を設定する。
- Compute Engine でレプリケーションを設定する。
- データを新しいインスタンスにシードする。
- Google Cloud に PostgreSQL クラスタを設定する。
- 新しいサーバーに切り替える。
- モニタリングを実装する。
始める前に
このチュートリアルでは、gcloud
コマンドと gsutil
コマンドを使用します。これらのコマンドは、Cloud Console から起動した Cloud Shell インスタンスから実行できます。ローカルのワークステーションで gcloud
と gsutil
を使用する場合、Cloud SDK をインストールします。このチュートリアルでは、Cloud Shell でコマンドを実行する方法を説明しています。ワークステーション上の Cloud SDK を使用する場合、ここでの説明は環境に合わせて読み替えてください。
- Google アカウントにログインします。
Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する。
- Compute Engine 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 クラスタを作成できます。最初に、次の図に示すようにデータベースを移行します。
データベースを移行する
実行中のマスター サーバーから完全バックアップを取得します(
label
は任意のラベルです)。echo "select pg_start_backup('label',true);" |sudo su - postgres -c psql sudo tar cvfz postgresql_AAAAMMDD.tar.gz $PGDATA
$PGDATA
は、PostgreSQL のメインデータ ディレクトリです。gs://pg-repo/
という Google Cloud プロジェクトにバケットを作成します。作成したバケットにバックアップを転送します。
master$ gsutil cp postgresql_AAAAMMDD.tar.gz gs://pg-repo/
バックアップ ファイルを Google Cloud マスターに転送します。
new_master$ gsutil cp gs://pg-repo/postgresql_AAAAMMDD.tar.gz
バックアップ ファイルを Google Cloud マスターに復元します。
new_master$ (cd / ; tar xvf postgresql_AAAAMMDD.tar.gz)
$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'
PostgreSQL サービスを起動します。
sudo service postgresql start
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 ...
下位データベースを作成する
データベースとサーバーをシャットダウンします。
sudo service postgresql stop sudo shutdown -h now
サービスが停止したことを確認するには、次のコマンドを実行します。
gcloud compute instances describe master-instance-name | grep status
出力に、インスタンスのステータスが
TERMINATED
として表示されます。status: TERMINATED
次に、新しい下位を作成できるように、データディスクのスナップショットを作成します。
Cloud Console で [スナップショット] ページに移動します。
PostgreSQL ディスクから、新しいスナップショットを作成します。
Google Cloud マスター サーバーを起動します。
[VM インスタンス] ページに移動し、master-instance-name をクリックして、[開始] をクリックします。
PostgreSQL サービスが自動的に起動します。
確認するには、次のコマンドを実行します。
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
Cloud Console で、[VM インスタンス] ページに移動し、[インスタンスを作成] をクリックします。
ブートディスクには、Ubuntu 14.04 を選択します。
[管理、ディスク、ネットワーク、SSH 認証鍵] をクリックし、前に作成したスナップショットに基づいて新しいディスクを追加します。
新しいサーバーを起動し、ディスクをマウントします。
sudo mkdir /database && sudo mount /dev/sdb1 /database
PostgreSQL をインストールします。
sudo apt-get install postgresql && sudo service postgresql stop
データ ディレクトリとレプリケーション値を構成します。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'
Google Cloud マスターを参照する新しい構成ファイルで PostgreSQL サービスを起動します。
sudo service postgresql restart
サービスが実行されていることを確認します。
ps ax | grep postgres
次のクエリで 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 ...
さらに下位を追加するには、この手順を繰り返します。
新しいサーバーに切り替える
- 新しい Google Cloud マスター サーバーを参照するように PgBouncer で構成ファイルを変更します。
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();
クリーンアップ
プロジェクトを削除する
- Cloud Console で [リソースの管理] ページに移動します。
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。