Amazon Web Services ブログ

Bucardo を使用して従来の PostgreSQL データベースを Amazon RDS または Aurora PostgreSQL に移行する



9.4 より前の PostgreSQL を使用している場合、サポートされていない PostgreSQL バージョンを使用していることになります。Amazon RDS または Amazon Aurora PostgreSQL でデータベースを移行または複製するためのオプションが制限されている場合があります。これは主に、9.4 よりも古いバージョンの PostgreSQL では論理複製を実行できないのが原因です。

Bucardo は、データの変更を非同期で複数のセカンダリまたは複数のマスターに複製できるオープンソースユーティリティです。これはトリガーベースのレプリケーションであり、より広範囲の移行や継続的なレプリケーションに対して一貫性と安定性が実証されています。Bucardo は、プライマリキーなしでテーブルの全ロードを実行できます。ただし、デルタデータの変更をプライマリから複製するには、セットアップを開始する前にプライマリキーを作成します。

この記事では、Bucardo をセットアップし、PostgreSQL 8.4 から PostgreSQL 9.6 にデータ変更を複製する方法を示しています。

前提条件

開始する前に、次のものが必要です。

  • Bucardo 用 Ubuntu 16.04 を使用する 1 つの EC2 インスタンス (Bucardo サーバー: 172.31.88.4)
  • PostgreSQL 8.4.2 で RHEL 6 を使用する 1 つの EC2 インスタンス (PostgreSQL 8.4.2: 172.31.16.177)
  • us-east-1 に 1 つの RDS PostgreSQL 9.6 (RDS 9.6)

この記事では、Amazon EC2 で PostgreSQL 8.4.2 を使用しています。ただし、PostgreSQL データベースはオンプレミスで実行されている場合があります。

このソリューションでは、Ubuntu 16.04 に Bucardo 5.4.1 をインストールします。つまり、Bucardo のリポジトリは、PostgreSQL 9.6 インスタンスで実行されている同じホスト上にあります。次の図は、データ複製フローのアーキテクチャを示しています。

図: Bucardo を使用して PostgreSQL 8.4 を RDS PostgreSQL 9.6 に移行するためのレプリケーションアーキテクチャ。

Bucardo バイナリのインストール

Bucardo をインストールする前にインストールする必要のあるパッケージがいくつかあります。次のコードを参照してください。

#apt-get install postgresql-plperl-9.6 libdbd-pg-perl libboolean-perl build-essential libdbd-mock-perl libdbd-pg-perl libanyevent-dbd-pg-perl libpg-hstore-perl libpgobject-perl

CPAN に接続し、DBI,DBD::Pg,DBIx::Safe をインストールします。次のコードを参照してください。

cpan > install DBI
cpan > install DBD::Pg
cpan > install DBIx::Safe

Bucardo バイナリをローカルディレクトリにダウンロードし、展開します。次のコードを参照してください。

$wget http://bucardo.org/downloads/Bucardo-5.4.1.tar.gz
tar xvfz Bucardo-5.4.1.tar.gz

$perl Makefile.PL
$sudo make install 

スーパーユーザーとリポジトリデータベースの作成

環境間のレプリケーションを制御して追跡するには、Bucardo スーパーユーザーとリポジトリデータベースを作成する必要があります。PSQL クライアントまたは pgadmin4 を使用して DB-APP1 に接続し、DR-App1 にスーパーユーザーとリポジトリを作成します。次のコードを参照してください。

postgres=# create user bucardo superuser;
CREATE ROLE

postgres=# create database bucardo;
CREATE DATABASE
postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 bucardo   | Superuser                                                  | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 replica   | Replication                                                | {}

postgres=# alter database bucardo owner to bucardo;
ALTER DATABASE
postgres=# \list
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 bucardo   | bucardo  | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(4 rows)

スーパーユーザーとリポジトリデータベースを作成したら、PSQL を終了し、Bucardo ソフトウェアがステージングされているターミナルから “bucardo install” を実行します。これにより、Bucardo データベースに一連のテーブルが作成されます (データベース所有者は Bucardo スーパーユーザーでなければなりません)。

Bucardo リポジトリのインストール

Bucardo リポジトリをインストールするには、次のコードを入力します。

postgres@ip-172-31-88-4:~/Bucardo-5.4.1$ sudo bucardo install

これにより、Bucardo データベースが既存の PostgreSQL クラスターにインストールされます。Perl サポートを使用して PostgreSQL をコンパイルし、スーパーユーザーとして接続する必要があります。次のコードを参照してください。

Current connection settings:
1.Host:           <none>
2.Port:           5432
3.User:           postgres
4.Database:       bucardo
5.PID directory:  /var/run/bucardo
Enter a number to change it, P to proceed, or Q to quit: p

Postgres version is: 9.6
bucardo データベースとスキーマを作成して入力しようとしています
データベースの作成が完了しました

構成設定 "piddir" を更新しました

これでインストールが完了しました。エラーが表示されたり、サポートが必要な場合は、Bucardo サポート (bucardo-general@bucardo.org) までお問い合わせください。

次に構成変数を確認することをお勧めします。次のコードを参照してください。

bucardo show all
Change any setting by using: bucardo set foo=bar

postgres@ip-172-31-88-4:~/Bucardo-5.4.1$ 

相互接続するために Bucardo と PostgreSQL データベースサーバーをホワイトリストに追加

pgpass を使用してパスワードのない認証を設定し、ソースデータベースとターゲットデータベースを安全に接続します。Bucardo サーバーで、次のコードを入力します。

postgres@ip-172-31-88-4:~$ touch ~/.pgpass
postgres@ip-172-31-88-4:~$ chmod 0600 ~/.pgpass

postgres@ip-172-31-88-4:~$ cat ~/.pgpass
#server:port:database:username:password
127.0.0.1:5432:postgres:postgres:XXXXXX
172.31.88.4:5432:bucardo:postgres:XXXXXX
172.31.16.177:5432:repdb:postgres:XXXXXX
pgrds.cxad2e11vriv.us-east-1.rds.amazonaws.com:5432:repdb:postgres:XXXXXX

次のコードを使用して、パスワードなしで Bucardo サーバーがソースデータベースとターゲットデータベースに接続できることを確認します。

postgres@ip-172-31-88-4:~$ psql -h 172.31.16.177 -d repdb -U postgres -w -c "select count(*) from pgbench_branches"
 count 
-------
     1
(1 row)

postgres@ip-172-31-88-4:~$ psql --host 'pgrds.cxad2e11vriv.us-east-1.rds.amazonaws.com' --port 5432 --username 'postgres' 'repdb' -w -c "select count(*) from pgbench_branches"
 count 
-------
     1
(1 row)

アクセス許可拒否エラーの解決

RDS はマネージドサービスであるため、AWS はセキュリティ上の理由からスーパーユーザーの権限を提供しません。トリガーベースのレプリケーションを実行するには、パラメータ session_replication_role を有効にする必要があります。

セキュリティ定義関数 rds_session_replication_role を使用できます。これは、イベントが発生したときにレプリカにパラメータを設定するのに役立ちます。すべての環境で一貫性を保つために、この記事では EC2 PostgreSQL (8.4.2) および RDS でセキュリティ定義関数を作成します。

次のコードで言語 plpgsql; を作成します。

CREATE OR REPLACE FUNCTION public.rds_session_replication_role(role text)
 RETURNS text
 LANGUAGE plpgsql
 SECURITY DEFINER
AS $function$
        DECLARE
                curr_val text := 'unset';
        BEGIN
                EXECUTE 'SET session_replication_role = ' || quote_literal(role);
                EXECUTE 'SHOW session_replication_role' INTO curr_val;
                RETURN curr_val;
        END
$function$;

postgres=> revoke all on function rds_session_replication_role(text) from public;
REVOKE

postgres=> grant execute on function rds_session_replication_role(text) to rds_superuser;
GRANT

postgres=> grant rds_superuser to postgres; 
GRANT

また、5397 行と 5330 行で bucardo.pm ファイルを次のコードに変更します。

$dbh->do(q{select rds_session_replication_role('replica');}); ## Assumes a sane default !

From.

$dbh->do(q{SET session_replication_role = default}); ## Assumes a sane default !

あるいは、更新された bucardo.pm ファイルをダウンロードして、/usr/local/share/perl/5.22.1/Bucardo.pm で Bucardo が実行されているサーバーにファイルを移動することもできます。本番環境で実行している場合は、使用する前にテストを行ってください。

サンプルソースデータベースの生成とターゲットの全ロードの開始

ソースデータベースで、pgbench を使用していくつかのテストデータを生成します。この記事では、4 つのテーブルが生成されます。3 つはプライマリキーが有効で、もう 1 つはプライマリキーが無効です。次のコードを参照してください。

postgres=# create database repdb;
CREATE DATABASE

次のコードは、repdb で生成されたサンプルデータです。

[postgres@ip-172-31-16-177 ~]$ pgbench -i repdb
NOTICE:  table "pgbench_branches" does not exist, skipping
NOTICE:  table "pgbench_tellers" does not exist, skipping
NOTICE:  table "pgbench_accounts" does not exist, skipping
NOTICE:  table "pgbench_history" does not exist, skipping
creating tables...
10000 tuples done.
20000 tuples done.
30000 tuples done.
40000 tuples done.
50000 tuples done.
60000 tuples done.
70000 tuples done.
80000 tuples done.
90000 tuples done.
100000 tuples done.
set primary key...
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "pgbench_branches_pkey" for table "pgbench_branches"
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "pgbench_tellers_pkey" for table "pgbench_tellers"
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "pgbench_accounts_pkey" for table "pgbench_accounts"
vacuum...done.

データ数とテーブル構造を確認します。次のコードを参照してください。

repdb=# select count(*) from pgbench_accounts;
 100000

repdb=# select count(*) from pgbench_branches;
     1

repdb=# select count(*) from pgbench_history;
     0

repdb=# select count(*) from pgbench_tellers;
    10

pg_dump および pg_restore を使用したソースデータベースからの repdb 移行

pg_dump を使用してソースデータベースをバックアップします。次のコードを参照してください。

postgres@ip-172-31-88-4:~$ pg_dump -Fc -v -h ec2-34-229-97-46.compute-1.amazonaws.com -U postgres repdb -w > repdb_bkp1.dump
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
……

RDS PostgreSQL にログインして、データベース repdb を作成します。次のコードを参照してください。

postgres@ip-172-31-88-4:~$ psql --host 'pgrds.cxad2e11vriv.us-east-1.rds.amazonaws.com' --port 5432 --username 'postgres' 'postgres'
ユーザー postgres のパスワード: 
psql (9.6.15)
SSL 接続 (プロトコル: TLSv1.2、暗号: ECDHE-RSA-AES256-GCM-SHA384、ビット: 256、圧縮: オフ)
ヘルプを表示するには "help" と入力します。
postgres=> create database repdb;
CREATE DATABASE

pg_restore を使用して、RDS PostgreSQL で新しく作成された repdb で生成されたダンプファイルを復元します。次のコードを参照してください。

postgres@ip-172-31-88-4:~$ pg_restore -v -h pgrds.cxad2e11vriv.us-east-1.rds.amazonaws.com -U postgres -d repdb repdb_bkp1.dump 
pg_restore: connecting to database for restore
パスワード: 
pg_restore: creating SCHEMA "public"
pg_restore: creating COMMENT "SCHEMA public"
pg_restore: creating PROCEDURAL LANGUAGE "plpgsql"

詳細については、Amazon RDS で PostgreSQL にデータをインポートするを参照してください。

プライマリキーでテーブルを複製するための Bucardo 構成

従来の Bucardo セットアップは、ソースデータベースとターゲットデータベースを追加し、プライマリキーを持つテーブルをグループに追加し、同期を作成して有効化し、ソースからの変更を複製する手順で構成されています。

ソースデータベースを追加するには、次のコードを入力します。

postgres@ip-172-31-88-4:~$ bucardo add db pgdb84 dbhost=ec2-34-229-97-46.compute-1.amazonaws.com dbport=5432 dbname=repdb dbuser=postgres
"pgdb84" データベースを追加しました

ターゲット RDS データベースを追加するには、次のコードを入力します。

postgres@ip-172-31-88-4:~$ bucardo add db rds96 dbhost=pgrds.cxad2e11vriv.us-east-1.rds.amazonaws.com dbport=5432 dbname=repdb dbuser=postgres dbpass=postgres123
"rds96" データベースを追加しました

群れにテーブルを追加するには、次のコードを入力します。

postgres@ip-172-31-88-4:~$ bucardo add table pgbench_accounts pgbench_branches pgbench_tellers herd=herd_pg84 db=pgdb84
"herd_pg84" という名前のリレーショナルグループを作成しました
次のテーブルまたはシーケンスは、リレーショナルグループ "herd_pg84" の一部になりました。
  public.pgbench_accounts
  public.pgbench_branches
  public.pgbench_tellers

データベースグループを追加するには、次のコードを入力します。

postgres@ip-172-31-88-4:~$ bucardo add dbgroup pgdb84_to_rds96 pgdb84:source rds96:target
DB グループ "pgdb84_to_rds96" を作成しました
データベース "pgdb84" を DB グループ "pgdb84_to_rds96" にソースとして追加しました
データベース "rds96" をターゲットとして DB グループ "pgdb84_to_rds96" に追加しました

postgres@ip-172-31-88-4:~$ bucardo add sync sync_pg84_rds96 relgroup=herd_pg84 db=pgdb84,rds96 
同期 "sync_pg84_rds96" を追加しました
既存の DB グループ "dbgrp84_96" を使用する

特定のデータベースグループに複数のデータベースを含めることができます。

開始する前に Bucardo の同期ステータスをチェックして、作成されたパラメータが表示されることを確認します。次のコードを参照してください。

postgres@ip-172-31-88-4:~$ sudo bucardo status sync_pg84_rds96
[sudo] postgres のパスワード: 
======================================================================
同期名                : sync_pg84_rds96
現在の状態            : レコードが見つかりません
ソースリレーショナルグループ/データベース : herd_pg84 / pgdb84
同期しているテーブル           : 3
ステータス                   : アクティブ
確認時刻               : なし
期限超過時刻             : 00:00:00
満了時刻             : 00:00:00
Stayalive/Kidsalive      : はい/はい
インデックスを再構築            : いいえ
オートキック                 : はい
ワンタイムコピー              : いいえ
コピー後の分析        : はい
最新のエラー:              : 
======================================================================

Bucardo を起動して、ステータスを確認します。次のコードを参照してください。

postgres@ip-172-31-88-4:~$ sudo bucardo start
既存プロセスを確認しています
ファイル "/var/run/bucardo/fullstopbucardo" を削除しています
Bucardo を開始しています

postgres@ip-172-31-88-4:~$ sudo bucardo status sync_pg84_rds96
======================================================================
最終正常                : Dec 05, 2019 08:30:03 (実行時間: 1 秒)
削除/挿入された行数    : 0 / 0 
同期名                : sync_pg84_rds96
現在の状態            : 良好 
ソースリレーショナルグループ/データベース : herd_pg84 / pgdb84
同期しているテーブル           : 3
ステータス                   : アクティブ
確認時刻               : なし
期限超過時刻             : 00:00:00
満了時刻             : 00:00:00
Stayalive/Kidsalive      : はい/はい
インデックスを再構築            : いいえ
オートキック                 : はい
ワンタイムコピー              : いいえ
コピー後の分析        : はい
最新のエラー:              : 
======================================================================

現在の状態良好であり、現在、ソースデータベースでは、挿入、更新、削除は行われていません。

レプリケーションをテストするには、pgbench を使用してソースデータベースにテストロードを生成し、ターゲットの変更をモニタリングします。次のコードを参照してください。

[postgres@ip-172-31-16-177 ~]$ pgbench -t 10000 repdb
starting vacuum...end.
トランザクションタイプ: TPC-B (分類)
スケーリング要因: 1
クエリモード: 簡単
クライアント数: 1
トランザクション数/クライアント: 10000
実際に処理されたトランザクション数: 10000/10000
tps = 503.183795 (接続確立を含む)
tps = 503.244214 (接続確立を除外)

pgbench を実行すると、いくつかのトランザクションが生成されますが、アクセス許可の問題により Bucardo をターゲットに移動できません。したがって、現在の状態のステータスは不良です。次のコードを参照してください。

postgres@ip-172-31-88-4:~$ sudo bucardo status sync_pg84_rds96
======================================================================
最終不良                 : Dec 05, 2019 08:32:54 (失敗までの時間: 1 秒)
同期名                : sync_pg84_rds96
現在の状態            : 不良
ソースリレーショナルグループ/データベース : herd_pg84 / pgdb84
同期しているテーブル           : 3
ステータス                   : アクティブ
確認時刻               : なし
期限超過時刻             : 00:00:00
満了時刻             : 00:00:00
Stayalive/Kidsalive      : はい/はい
インデックスを再構築            : いいえ
オートキック                 : はい
ワンタイムコピー              : いいえ
コピー後の分析        : はい
最終エラー:              : 失敗 : DBD::Pg::db が失敗しました: エラー:  関数 rds_session_replication_role(不明) が存在しません ライン 1: rds_session_replication_role('レプリカ') を選択してください;                ^ ヒント:  指定された名前と引数タイプに一致する関数がありません。場合に応じて、/usr/local/share/perl/5.22.1/Bucardo.pm line 5328 で明示的なタイプのキャストを追加する必要があります。ライン: 5041 メイン DB 状態: ? エラー: なし DB pgdb84 状態: ? エラー: なし DB rds96 状態: 42883 エラー: 7  (KID 14864)
======================================================================

このエラーが発生した場合は、手順通りに実行してアクセス許可拒否エラーを解決してください。この例では、ソースデータベースとターゲットデータベースでセキュリティ定義関数が作成されず、前述のエラーが発生しました。セキュリティ定義者を実装した後、Bucardo を再起動します。次のコードを参照してください。

postgres@ip-172-31-88-4:~$ sudo bucardo restart
Creating /var/run/bucardo/fullstopbucardo ...完了
既存プロセスを確認しています
ファイル "/var/run/bucardo/fullstopbucardo" を削除しています
Bucardo を開始しています

現在の状態良好で、データベースで 294 回の削除と挿入が発生しました。これで、Bucardo が正常であることを確認できます。最終エラーのエントリは無視できます。次のコードを参照してください。

postgres@ip-172-31-88-4:~$ sudo bucardo status sync_pg84_rds96
======================================================================
最終正常                : Dec 05, 2019 08:51:21 (実行時間: 1 秒)
削除/挿入された行数    : 294 / 294 
最終不良                 : Dec 05, 2019 08:35:06 (失敗までの時間: 1 秒)
同期名                : sync_pg84_rds96
現在の状態            : 良好 
ソースリレーショナルグループ/データベース : herd_pg84 / pgdb84
同期しているテーブル           : 3
ステータス                   : アクティブ
確認時刻               : なし
期限超過時刻             : 00:00:00
満了時刻             : 00:00:00
Stayalive/Kidsalive      : はい/はい
インデックスを再構築            : いいえ
オートキック                 : はい
ワンタイムコピー              : いいえ
コピー後の分析        : はい
最終エラー:              : 失敗 : DBD::Pg::db が失敗しました: エラー:  関数 rds_session_replication_role(不明) が存在しません ライン 1: rds_session_replication_role('レプリカ') を選択してください;                ^ ヒント:  指定された名前と引数タイプに一致する関数がありません。場合に応じて、/usr/local/share/perl/5.22.1/Bucardo.pm line 5328 で明示的なタイプのキャストを追加する必要があります。ライン: 5041 メイン DB 状態: ? エラー: なし DB pgdb84 状態: ? エラー: なし DB rds96 状態: 42883 エラー: 7  (KID 15006)
======================================================================

複製をデバッグするために、Bucardo ログは /var/log ディレクトリに存在しています。次のコードを参照してください。

postgres@ip-172-31-88-4:~$ tail -f /var/log/bucardo/log.bucardo
(15337) [Thu Dec  5 08:51:25 2019] KID (sync_pg84_rds96) Delta count for pgdb84.public.pgbench_tellers  :  10
(15337) [Thu Dec  5 08:51:25 2019] KID (sync_pg84_rds96) Totals: deletes=297 inserts=297 conflicts=0
(15337) [Thu Dec  5 08:51:25 2019] KID (sync_pg84_rds96) Delta count for pgdb84.public.pgbench_accounts : 109
(15337) [Thu Dec  5 08:51:25 2019] KID (sync_pg84_rds96) Delta count for pgdb84.public.pgbench_branches :   1
(15337) [Thu Dec  5 08:51:25 2019] KID (sync_pg84_rds96) Delta count for pgdb84.public.pgbench_tellers  :  10
(15337) [Thu Dec  5 08:51:25 2019] KID (sync_pg84_rds96) Totals: deletes=120 inserts=120 conflicts=0
(15337) [Thu Dec  5 08:51:26 2019] KID (sync_pg84_rds96) Delta count for pgdb84.public.pgbench_accounts : 239
(15337) [Thu Dec  5 08:51:26 2019] KID (sync_pg84_rds96) Delta count for pgdb84.public.pgbench_branches :   1
(15337) [Thu Dec  5 08:51:26 2019] KID (sync_pg84_rds96) Delta count for pgdb84.public.pgbench_tellers  :  10
(15337) [Thu Dec  5 08:51:26 2019] KID (sync_pg84_rds96) Totals: deletes=250 inserts=250 conflicts=0

まとめ

この記事では、非同期トリガーベースのレプリケーションユーティリティ Bucardo を使用して、9.4 より古い従来の PostgreSQL データベースを Amazon RDS PostgreSQL または Aurora PostgreSQL に移行するという課題を克服する完全なソリューションを示しました。

このソリューションに関するコメントやご質問は、以下のコメントセクションからお送りください。

 


著者について

 

Rajeshkumar Sabankar は、アマゾン ウェブ サービスのデータベース専門アーキテクトです。 Amazon の内部顧客と連携して、AWS クラウドで安全でスケーラブルで復元力のあるアーキテクチャを構築し、顧客がオンプレミスデータベースから Amazon RDS および Aurora データベースに移行するように支援しています。

 

 

 

Samujjwal Roy はデータベース専門アーキテクトで、アマゾン ウェブ サービスのプロフェッショナルサービスチームの一員です。Amazon に 15 年以上勤続し、Amazon 内外のお客様の移行プロジェクトを主導して、オンプレミスデータベース環境から AWS クラウドデータベースソリューションへの移行を手がけてきました。