データベース
 Computer >> コンピューター >  >> プログラミング >> データベース

PostgreSQLレプリケーション完全ガイド:種類・仕組みからストリーミングレプリケーションの構築手順まで

レプリケーションとは、あるデータベースサーバー(ソース)から別のサーバー(レプリカ)へデータを複製する仕組みです。高可用性の実現や災害復旧(DR)対策を支える、PostgreSQLの強力な機能の一つです。

はじめに

レプリカサーバーは、テストやレポーティング用途にも活用でき、本番のOLTP(オンライントランザクション処理)データベースへの負荷を軽減できます。この記事では、PostgreSQLにおけるレプリケーションの種類を整理したうえで、ストリーミングレプリケーションを実際に構築するための手順を解説します。

レプリケーションの詳細

まずは、PostgreSQLのレプリケーションモード(同期/非同期)、モデル(単一ソース/マルチソース)、そしてWAL(ライトアヘッドログ)の仕組みについて理解しましょう。

非同期モードと同期モード

非同期レプリケーションでは、ソースサーバーはレプリカからのトランザクション完了通知を待ちません。レプリケーション用のトランザクションはレプリカ側でキューイングされ、処理が完了するまでの間、両サーバーは一定時間同期が取れない状態になることがあります。

一方、同期モードでは、ソースサーバーは各レプリケーショントランザクションの完了確認をレプリカ(または複数のレプリカ)から受け取ってから次の処理に進みます。ソースとレプリカの両方が常に稼働している必要があり、レプリカからトランザクション失敗の応答を受け取った場合は、ソースサーバーがそのトランザクションをロールバックします。このモードでは両サーバーは常に同期状態を保てますが、レプリカがダウンしたりトランザクションを完了できない場合、ソースサーバーがハングアップ状態に陥るという欠点があります。

単一ソース型とマルチソース型のレプリケーションモデル

単一ソース(Single-source)モデルでは、ソースサーバーは1台のみで、1台以上のレプリカサーバーが存在します。ソースがすべてのレプリカへレプリケーショントランザクションを送信します。

レプリカサーバーはソースサーバーからの変更のみを受け付けます。仮にソース以外のサーバーから変更を受け取ったとしても、そのトランザクションをソースへ逆方向にレプリケーションすることはありません。

マルチソース(Multi-source)モデルでは、ソースサーバーが複数存在します。あるソースデータベース上でテーブル行が更新されると、その変更が他のソースサーバーの対応する行にも反映されます。このモデルを成功させるには、重複する主キーやその他の競合を防ぐための競合解決スキームが必要です。

レプリケーションの種類

PostgreSQLのレプリケーションには主に3つの種類があります。

  • ストリーミングレプリケーション: PostgreSQL 9以降で利用可能。レプリカはSELECTクエリ専用で使用されます。ソースとレプリカのメジャーバージョンが同一であることが主な要件です。
  • カスケーディングレプリケーション: PostgreSQL 9.2で導入。スタンバイサーバーから直接ではなく、別のスタンバイサーバー経由でレプリケーションできるため、ソースサーバーの負荷を軽減できます。
  • 論理レプリケーション: 特定のデータセットやデータベースオブジェクトだけを選択してレプリケーションしたり、異なるメジャーバージョン間でレプリケーションしたりできます。スタンバイサーバーへの書き込みも可能ですが制限があり、TRUNCATE、ラージオブジェクト(LOB/BLOB/CLOB)、シーケンス、スキーマ、DDLはレプリケーションできません。

ライトアヘッドログ(WAL)

ストリーミングレプリケーションを使い始める前に、WAL(Write-Ahead Logging)の仕組みを理解しておくことが重要です。

PostgreSQLでは、データベースへの変更はまずログファイルに書き込まれ、その後データファイルに保存されます。これらの変更レコードを「WALレコード」と呼び、各WALレコードにはLSN(ログシーケンス番号)という一意の番号が付与されます。

ストリーミングレプリケーションでは、レプリカ側のデータベースサーバーがこのWALファイルを利用して、ソースサーバー上の変更を複製します。

ストリーミングレプリケーションにおいて重要な役割を果たす必須プロセスは次の3つです。

  • WAL sender(ソースサーバー上で動作)
  • WAL receiver(レプリカサーバー上で動作)
  • Startup(レプリカサーバー上で動作)

レプリケーション開始時には、以下のイベントが順に発生します。

  1. WAL receiverプロセスが、レプリカが再生済みのWALデータ位置を示すLSNをソースへ通知します。
  2. ソース上のWAL senderプロセスが、WAL receiverから通知された最新のLSNに達するまでWALデータをレプリカへ送信します。
  3. WAL receiverが受信したWALデータをWALセグメントに書き込みます。
  4. レプリカ上のstartupプロセスが、WALセグメントに書き込まれたデータを再生(リプレイ)します。
  5. 以上でストリーミングレプリケーションが開始されます。

検証環境:ストリーミングレプリケーションの設定手順

ここからは、ソースサーバー1台とレプリカ1台の間でストリーミングレプリケーションを構築する具体的な手順を紹介します。

ステップ1: SSHパスワードレス認証の準備

まず、ソースとレプリカの両サーバー間でSSHのパスワードなし認証が設定されていることを確認します。未設定の場合は ssh-keygen を使って鍵ペアを作成し、公開鍵を配布してください。

ソースノード: 192.168.24.28
レプリカノード: 192.168.24.29
両ノードともユーザー名は postgres

ステップ2: ファイアウォールの停止

両サーバーで以下のコマンドを実行し、ファイアウォールを停止・無効化します。

$ sudo systemctl stop firewalld
$ sudo systemctl disable firewalld

ステップ3: ソースサーバーの設定

  1. ソースサーバーでデータディレクトリへ移動します。

    cd /var/lib/pgsql/11/data
    
  2. postgresql.conf を編集し、以下のように設定します。

    archive_mode = on
    archive_command = 'cp %p /var/lib/pgsql/archive/%f'
    max_wal_senders = 5
    wal_keep_segments = 32
    wal_level = replica
    listen_addresses = '*'
    
  3. pg_hba.conf にレプリカサーバーのIPアドレスのエントリを追加します。

    host    postgres     postgres     192.168.24.29/32 trust
    host    replication  postgres     192.168.24.29/32 trust
    
  4. pg_hba.conf を変更した場合は、サービスをリロードして反映させます。

    $ /usr/local/pgsql_11/bin/pg_ctl -D /var/lib/pgsql/11/ reload
    
  5. アーカイブディレクトリ /var/lib/pgsql/archive/ が存在しない場合は作成します。

  6. 設定を反映させるためサーバーを再起動します。

ステップ4: レプリカサーバーでのベースバックアップ

レプリカサーバーで以下の作業を行います。

  1. データディレクトリへ移動し、サービスを停止します。

    $ /usr/pgsql-11/bin/pg_ctl -D /var/lib/pgsql/11/data/ stop
    
  2. レプリカのデータディレクトリ内をすべて削除し、次のコマンドでソースへ接続できることを確認します。

    $ /usr/pgsql-11/bin/psql -h 192.168.24.28
    
  3. 接続できたら、レプリカからベースバックアップを開始します。

    $ cd /var/lib/pgsql/11/data
    $ /usr/pgsql-11/bin/pg_basebackup -D /var/lib/pgsql/11/data/ -X fetch -h 192.168.24.28 -R -P
    

これらのコマンドにより、ソースデータベースのデータディレクトリ全体がレプリカのデータディレクトリへコピーされ、recovery.conf ファイルが自動生成されます。

ステップ5: recovery.conf の確認と編集

ベースバックアップ完了後、recovery.conf ファイルの存在を確認します。データディレクトリにこのファイルがあるサーバーはレプリカであり、ソースサーバーの接続情報を含んでいます。以下のように編集します。

standby_mode = 'on'
primary_conninfo = 'user=postgres host=192.168.24.28 port=5432'

実際のファイルは次のようになります。

$ vi recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=postgres passfile=''/home/postgres/.pgpass'' host=192.168.24.28 port=5432 sslmode=disable sslcompression=0 target_session_attrs=any'

ステップ6: サーバー起動と動作検証

サーバーを起動し、設定が正しく反映されているかを検証します。

  1. ソースサーバーにログインし、レプリケーション状態を確認します。

    /usr/local/pgsql_11/bin/psql
    postgres=# SELECT * FROM pg_stat_replication;
    
    -[ RECORD 1 ]----+------------------------------
    pid              | 1934
    usesysid         | 26712
    usename          | postgres
    application_name | walreceiver
    client_addr      | 192.168.24.29
    client_hostname  |
    client_port      | 52143
    backend_start    | 2020-11-07 11:30:31.035614-05
    backend_xmin     |
    state            | streaming
    sent_lsn         | 0/50000E34
    write_lsn        | 0/50000E34
    flush_lsn        | 0/50000E34
    replay_lsn       | 0/50000E34
    write_lag        |
    flush_lag        |
    replay_lag       |
    sync_priority    | 0
    sync_state       | async
    
  2. レプリカサーバーにログインし、リカバリモードであることを確認します。

    /usr/local/pgsql_11/bin/psql
    postgres=# SELECT * FROM pg_is_in_recovery();
     pg_is_in_recovery
    -------------------
     t
    
  3. ソースサーバーでOSレベルのコマンドでも確認できます。

    $ ps -ef | grep sender
    
    postgres  1934  1718  0 11:31 ?  00:00:00 postgres: wal sender process replicator 192.168.24.29(52143) streaming 0/50000E34
    
  4. 同様に、レプリカサーバーでも確認します。

    $ ps -ef | grep receiver
    
    postgres  1358  1748  0 11:31 ?  00:00:04 postgres: wal receiver process   streaming 0/50000E34
    

    senderとreceiverのLSNが一致していれば正常です。なお、レプリカは常に読み取り専用モードで動作します。

  5. (任意)デフォルトのレプリケーションは非同期モードです。同期レプリケーションに切り替えるには、ソースサーバーの postgresql.conf に以下を追加します。

    synchronous_standby_names = '*'
    

    その後、サービスを再起動します。

    $ /usr/local/pgsql-11/bin/pg_ctl -D /var/lib/pgsql/11/ restart
    

まとめ

この記事では、PostgreSQLのレプリケーションの種類と、ストリーミングレプリケーションを構築する手順を解説しました。読み取り専用のレプリカを用意してプライマリサーバーの負荷を分散させる構成は、分析系ワークロードで特に広く採用されています。

また、高可用性環境の構築や、プライマリ障害時のホットスタンバイサーバーへのフェイルオーバー対策としても有効です。まずは検証環境で手順を試しながら、自社システムに適したレプリケーション設計を検討してみてください。

  1. クリスマスの贈り物は高可用性レプリカ2台――ObjectRocket PostgreSQL HAサービス徹底解説

    2019年12月12日にObjectRocket.com/blogで公開された記事をもとにしています。 ホリデーシーズンの到来とともに、Rackspace ObjectRocketの歴史における重要な節目から1年が経ちました。2019年のホリデーシーズンに合わせて、私たちはObjectRocket PostgreSQL®サービスに高可用性(HA)を導入しました。ObjectRocketが提供するすべてのデータストアは本番ワークロード向けに構築されており、HAはすべてのお客様にとって必須の機能となっています。 なぜHA(高可用性)が重要なのか? 「HA」という用語に馴染みがない方のために、まず

  2. Oracle WebLogic Server 12cでSSLを構成する完全ガイド

    本記事では、Oracle® WebLogic® Server 12c(12.1.2)環境にSSL(Secure Socket Layer)を構成する具体的な手順を解説します。 概要 現代において、データや情報のセキュリティは最優先課題の一つです。多くのアプリケーションが、ネットワーク上での安全な通信を実現するためにSSLプロトコルを採用しており、SSLは最も広く利用されているネットワーク通信プロトコルの一つとなっています。 WebLogic ServerをSSL対応に設定すると、2つのアプリケーション間の接続に対して「ID認証」と「通信中データの暗号化」という2つの機能が提供されます。これによ