pglogical レプリケーションによるスイッチオーバーとフェイルオーバー

このページでは、pglogical レプリケーションを使用してスイッチオーバーとフェイルオーバーを行う方法について説明します。

始める前に

pglogical レプリケーションが設定され、実用的な高可用性(HA)と障害復旧(DR)ソリューションが存在し、論理レプリケーションが true を提供しず、すべてのデータベース オブジェクトの包括的なレプリケーションを提供しないことを認識したら、この構成をテストしてから使用を開始する必要があります。

pglogical 拡張機能の詳細については、pglogical についてをご覧ください。

pglogical を使用したデータ レプリケーションについては、 Google Cloud AlloyDB と AlloyDB Omni の間でデータを複製するAlloyDB Omni と他のデータベース間でデータを複製するをご覧ください。

pglogical レプリケーションによるスイッチオーバー

スイッチオーバーは、プロバイダ データベースとサブスクライバー データベースの間でロールを切り替えるために使用される制御されたプロセスです。スイッチオーバーを実行すると、2 つのデータベース(プロバイダとサブスクライバー)のロールが逆になります。プロバイダがサブスクライバーになり、サブスクライバーがプロバイダになります。

このスイッチオーバー機能は、オペレーティング システムのアップグレード、PostgreSQL のアップグレード、またはフェイルオーバー テストに重要です。

単方向レプリケーション構成でこれを実現するには、新しいプロバイダ/サブスクライバーの関係を設定し、古いプロバイダ/サブスクライバーの関係を削除する必要があります。

新しいプロバイダ/サブスクライバー構成をビルドする

  1. データベースの変更を防ぐために、アプリケーションがプロバイダ システムに書き込むのを停止し、レプリケーション ラグをチェックして、すべてのトランザクションがサブスクライバー ノードで再生されていることを確認します。

    SELECT application_name,
        state,
        sync_state,
        client_addr,
        client_hostname,
        pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag,
        pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag,
        pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag,
        pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag,
        now()-reply_time AS reply_delay
    FROM pg_stat_replication
    ORDER BY client_hostname;
    

    すべての遅延フィールドにゼロが表示されている場合、レプリケーションは最新の状態であり、データベースはスイッチオーバーの準備ができています。

    出力は次のようになります。

    -[ RECORD 1 ]----+------------------------------
    application_name | test_sub_1
    state            | streaming
    sync_state       | async
    client_addr      | 10.45.0.80
    client_hostname  | 
    sent_lag         | 0
    receiving_lag    | 0
    replay_lag       | 0
    total_lag        | 0
    reply_delay      | 00:00:26.203433
    
  2. サブスクライバー データベースをプロバイダ データベースに変換します。

    1. 既存の定期購入を停止します。
    2. 必要に応じてレプリケーション セットを追加します。
    3. 必要なテーブルをレプリケーション セットに追加します。
    4. 新しいサブスクライバー データベースに新しいサブスクライバー サブスクリプションを作成します。
    5. アプリケーションを新しいプロバイダにリダイレクトします。
  3. 既存のサブスクライバー データベースで定期購入を停止します。このデータベースが新しいプロバイダになります。

    SELECT pglogical.alter_subscription_disable(SUBSCRIPTION_NAME);
    
  4. (省略可)元のプロバイダ データベースの定義と一致するレプリケーション セットを作成します。デフォルトのレプリケーション セットを使用している場合は、これは必要ありません。

    SELECT pglogical.create_replication_set(REPLICATION_SET_NAME);
    
  5. そのレプリケーション セットにテーブルを追加します。

    SELECT pglogical.replication_set_add_table(REPLICATION_SET_NAME, TABLE_NAME);
    

    次のように置き換えます。

    • REPLICATION_SET_NAME: レプリカセットの名前。
    • TABLE_NAME: スキーマ所有者のテーブル名。例: ARRAY['public']
  6. 以前はプロバイダ データベースだった新しいサブスクライバー データベースで、synchronize_data オプションを false に設定して新しいサブスクリプションを作成し、テーブルの初回読み込みを防ぎます。

    SELECT pglogical.create_subscription (
               subscription_name := '<subscription name>',
               replication_sets := array['default'],
               synchronize_data := false,
               provider_dsn := 'host=<hostname or IP> port=5432 
               dbname=<db name> user=pglogical_replication password=<password>');
    
  7. プロバイダノードでサブスクリプションが機能しているかどうかを確認します。

    SELECT application_name,
        state,
        sync_state,
        client_addr,
        client_hostname,
        pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag,
        pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag,
        pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag,
        pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag,
        now()-reply_time AS reply_delay
    FROM pg_stat_replication
    ORDER BY client_hostname;
    
  8. レプリケーションが機能している場合は、新しいプロバイダ データベースを使用するようにアプリケーション接続文字列を変更し、アプリケーション ティアを再起動します。

サブスクライバーの停止後に古いプロバイダ ノードでデータを変更すると、これらの変更は複製されず、データが失われます。元のプロバイダ データベースに複製されていないデータ変更がある場合、または元のプロバイダ(新しい定期購入者)が、新しいプロバイダ データベース(古い定期購入者)と整合性のある状態になっていない場合は、新しい定期購入者データベースを完全に構築する必要があります。

古いプロバイダとサブスクリプションを削除する

単方向レプリケーションが必要な場合は、古いプロバイダ/サブスクライバー構成を削除する必要があります。

  1. 新しいプロバイダで古い定期購入を削除します。

    SELECT pglogical.drop_subscription('<subscription name>')
    
  2. 新しいサブスクライバーでレプリケーション セットを削除するか、レプリケーション セットからすべてのテーブルを削除します。

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    

双方向レプリケーション

ダウンタイムなしで切り替えを行うか、計画外の変更によってデータが失われないようにするには、双方向レプリケーションを使用する必要があります。双方向レプリケーションを実装する場合は、両方のノードへの書き込みアクセスを同時に防止する厳格な制御が設定されていない限り、競合解決を検討してください。

競合解決構成は、次の pglogical.conflict_resolution 設定を使用して設定できます。

  • error: 競合が検出されると、サブスクライバーは停止します。
  • apply_remote: 定期購読者データベースのデータに関係なく、受信した変更を常に適用します。これはデフォルトの設定です。
  • keep_local: 競合する受信データを常に無視し、競合する変更を破棄します。
  • last_update_wins: 最新の commit タイムスタンプを持つデータのバージョンが commit されるデータです。
  • first_update_wins: 最も古いタイムスタンプを持つデータのバージョンが commit されるデータです。

双方向レプリケーションを設定するには、レプリケーションが双方向に行われるようにプロバイダとサブスクライバーを設定します。元のサブスクライバーは、元のプロバイダと同じレプリケーション セットを持つプロバイダにもなります。テーブルを作成し、 Google Cloud AlloyDB プロバイダ データベースのデフォルトのレプリケーション セットに追加するで、最初のプロバイダ データベースの元のレプリケーション セットを複製するレプリケーション セットを作成します。

元のプロバイダで、新しい定期購入を追加する必要があります。AlloyDB Omni サブスクライバー データベースにノードとサブスクリプションを作成するで、コマンド pglogical.create_subscriptionsynchronize_data パラメータが false に設定されていることを確認して、新しいサブスクライバーを作成します。これにより、データの最初のテーブル コピーを回避できます。

pglogical レプリケーションによるフェイルオーバー

フェイルオーバーは、なんらかの理由でプロバイダ データベースが使用できなくなったときに発生します。この場合、サブスクライバー データベースを使用するようにアプリケーションを切り替える必要があります。

重複データがフェイルオーバーされたサブスクライバー データベースに誤って適用されないようにするには、サブスクリプションを無効にする必要があります。これにより、復元されたプロバイダの変更が、プロバイダが再び利用可能になったときに誤って適用されなくなります。

  1. サブスクライバー test_sub_1 を停止します。

    SELECT pglogical.alter_subscription_disable(`test_sub_1`);
    
  2. ステータスが disabled に設定されていることを確認します。

    SELECT pglogical.show_subscription_status('test_sub_1');
    

    出力は次のようになります。

    show_subscription_status                                                                           
    ----------------------------------------------------------------------------
    (test_sub1,disabled,subscriber,"host=10.45.0.108 port=5432 dbname=my_test_db user=pglogical_replication",subscriber,{failover_set},{all})
    
  3. ステータス出力で無効なキーワードを確認します。

  4. 高可用性と障害復旧機能を維持するために、新しいプロバイダ/サブスクライバー構成を構築します。

  5. 元々複製されていたすべてのテーブルを含む新しいレプリケーション セットを作成して、古いプロバイダ データベースが復元され、新しいサブスクライバーに変換されたときに新しいサブスクライバーが作成されるか、新しいサブスクライバーが作成されるようにします。

  6. 定期購入を設定する

  7. 古いプロバイダ データベースを障害発生時まで復元できる場合は、このデータベースを新しいサブスクライバーとして設定します。同じ手順でサブスクリプションを作成し、pglogical.create_subscription コマンドの synchronize_data パラメータを false に設定して、最初のテーブルのコピーを回避します。

  8. WAL ファイルの蓄積を回避するため、復元されたノードで古いプロバイダ構成を削除します。

  9. 古いプロバイダ データベースを使用している場合は、レプリケーション セット全体を削除するか、レプリケーション セットからすべてのテーブルを 1 つずつ削除します。

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    
  10. 新しいノードに書き込むようにアプリケーションを切り替えます。

次のステップ