sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLの物理レプリケーションメカニズム

    Postgresには、物理​​的および論理的なレプリケーション機能が付属しています。物理レプリケーションのさまざまな側面について詳しく知るために読んでください。

    物理レプリケーション

    物理レプリケーション方式は、単一のクラスター(Postgresではクラスター)のデータ全体の完全なコピーを維持するために使用されます は、 postmasterと呼ばれる単一のメインPostgresサーバープロセスによって管理されるデータベースのセットです。 )、通常は別のマシン。ソースマシンはプライマリと呼ばれます Postgresの専門用語では、宛先はスタンバイと呼ばれます 。

    ホット、ウォーム、および「コールド」スタンバイ

    プライマリをリアルタイムで可能な限り最新の状態に保ち、クライアントが読み取り専用トランザクションを実行できるようにするスタンバイサーバーは、「ホット」と呼ばれます。 スタンバイ、またはより一般的にはリードレプリカ 。バージョン9ではホットスタンバイがPostgresに追加されましたが、それ以前はウォームしかありませんでした。 スタンバイ。ウォームスタンバイは、クライアントがそれに接続できないことを除いて、ホットスタンバイに似ています。

    (余談ですが、ホットスタンバイは一時テーブルを作成するクエリを実行できません。これはPostgresの制限です。)

    「コールド」スタンバイ(正式な用語ではありません)は通常、フェイルオーバーまで起動しないスタンバイサーバーです。コールドスタンバイは稼働していないため、起動時に、クライアント接続の受け入れを開始する前に、保留中の変更を最初に適用する必要がある可能性があります。

    WALファイル

    通常の操作では、PostgreSQLサーバーは順序付けられた一連のWAL(ログ先行書き込み)レコードを生成します。これらは基本的に変更のログであり、RedisのAOFまたはMySQLのbinlogに似ています。基本的に、物理レプリケーションは、これらのレコードを別のマシンに転送し、そこで実行されている他のポストマスターに、これらのレコードを受け入れてローカルデータベースに適用させることです。

    WALレコードは、WALセグメントと呼ばれる同じサイズ(通常は16MB)のファイルにチャンクされます。 または単にWALファイル 。これらのファイルは、pg_walというディレクトリに作成されます。 クラスターデータディレクトリの下(pg_wal pg_xlogと呼ばれていました 10より前のPostgresバージョン)。古いWALファイルは、不要になったときに破棄されます(また、いくつかの構成パラメーターに基づいて)。

    リカバリモード

    ポストマスターは、リカバリモードと呼ばれるモードで起動できます。 、 restorey.confという有効な構成ファイルを配置する リカバリモードでは、Postgresはプライマリサーバーによって生成されたWALファイルのみをインポートして適用し、それ自体ではWALファイルを生成しません。ウォームサーバーとホットスタンバイサーバーはリカバリモードで実行されます。

    リカバリモードで起動すると、Postgresは最初にアーカイブで利用可能なすべてのWALファイルをインポートしようとします。 (これについては以下で詳しく説明します)。アーカイブに提供するWALファイルがなくなると、initのpg_walの周囲にあるファイルをインポートしようとします。 ディレクトリ。これらも行われ、プライマリ接続が構成され、standby_modesetがonに設定されている場合 Recovery.confでは、Postgresはプライマリに接続し、プライマリで作成された新しいWALレコードをプルして適用します。

    ログ配布

    新しいWALファイルが作成されるたびにプライマリサーバーで呼び出されるトリガーがあると想像してください。このトリガーは、たとえばrsyncを使用して、新しいWALファイルを別のマシンにコピーできます。 、pg_walに配置します リカバリモードで実行されているpostmasterのディレクトリ。このようにスタンバイできますか?

    答えはイエスです。実際、これは、Postgresv9でstreamingreplicationが追加される前の標準的な方法でした。この方法はログ配布と呼ばれます 。

    トリガーはシェルスクリプトであり、archive_commandを使用して構成できます。WALファイルの名前とパスをスクリプトに渡すことができます。

    WALアーカイブ

    WALファイルをrsyncする代わりに、スタンバイマシンからもアクセスできるS3バケットまたはNFSマウントディレクトリにコピーするとします。この共有場所には、プライマリによって生成されたすべてのWALファイルが含まれます。 アーカイブになります 、およびWALファイルをアーカイブに保存するプロセスは連続アーカイブと呼ばれます。 または単にWALアーカイブ

    この操作の逆、つまりアーカイブからarecoveryモードのPostgresにWALファイルをフェッチすることは、restore_commandを使用して構成できます。archive_commandと同様です。 、これもシェルスクリプトへのパスです。リカバリモードで実行されているポストマスターは、必要なWALファイルを認識しています。ファイルの名前をスクリプトに渡すことができます。

    例として、S3バケットとの間でWALファイルを保存およびフェッチするためのアーカイブおよび復元コマンドを次に示します。

    archive_command = 's3cmd put %p s3://BUCKET/path/%f' # in postgresql.conf
    restore_command = 's3cmd get s3://BUCKET/path/%f %p' # in recovery.conf

    リカバリモードで起動する場合、restore_command が構成されている場合、Postgresは最初にアーカイブからWALファイルをフェッチしようとします。

    pg_standby

    リカバリモードでは、Postgresはこれまでに生成されたWALファイルの数を事前に知ることはできません。 restore_commandが構成されている場合、Postgresは、コマンドがエラーを返すまで、プログレッシブWALファイル名(名前は予測可能な順序になっています)を使用して繰り返し呼び出します。

    たとえば、復元コマンドはWALファイルの要求を満たすことができました000000010000000000000001 00000001000000000000001Aを介して ただし、00000001000000000000001Bでは失敗します アーカイブの場所に見つからなかったため。他のソースからのWALファイルがない場合、PostgresはWALfile 00000001000000000000001Bと見なします。 はまだプライマリによって生成されておらず、00000001000000000000001Aを適用した後にリカバリを終了します 。

    復元コマンドがファイル00000001000000000000001Bを待機した場合にどうなるかを検討してください。 見つからなかったため、エラーで終了するのではなく、使用可能になります。 Postgresは復元コマンドを待機し続けるため、引き続きリカバリモードになります。

    これは有効な構成であり、ウォームスタンバイをセットアップするための有効な方法です。

    Postgresにはpg_standbyというコマンドが付属しています。このコマンドを使用して、アーカイブがディレクトリである限り、この方法でウォームスタンバイを設定できます。pg_standby ファイルが見つからない場合は、ファイルが利用可能になるのを待ちます。

    pg_standbyを使用したアーカイブおよび復元コマンドは、次のようになります。

    archive_command = 'cp %p /some/path/%f'         # in postgresql.conf
    restore_command = 'pg_standby /some/path %f %p' # in recovery.conf
    ストリーミングレプリケーション

    アーカイブされたWALファイルとpg_wal内のファイルを処理した後 ディレクトリ、Postgresはネットワーク経由でプライマリサーバーに接続し、作成された新しいWALファイルを繰り返しフェッチして適用できます。 Postgres 9で追加されたこの機能は、ストリーミングレプリケーションと呼ばれます。 。

    接続するプライマリサーバーは、recovery.confファイルで指定できます:

    # recovery.conf
    standby_mode = on
    primary_conninfo = 'host=10.0.1.10 user=repl password=p@ssw0rd'
    ホットスタンバイ

    デフォルトでは、リカバリモードの場合、Postgresはクライアント接続を受け入れず、「データベースシステムはリカバリモードです」というエラーメッセージでクライアント接続を拒否します。 hot_standby = onという行を追加します Recovery.confでは、Postgresacceptクライアント接続を確立し、読み取り専用トランザクションの実行を許可できます。

    # recovery.conf
    hot_standby = on

    通常、hot_standbyをオフにする理由はありません。

    PostgreSQLのドキュメントには、「ホットスタンバイ」モードでのスタンバイの設定と実行に関する詳細情報があります。

    レプリケーションスロット

    レプリケーションスロットはPostgres9.4で導入されました。これらは、スタンバイがプライマリからどれだけ遅れているかを正確かつ永続的に追跡するメカニズムです。これにより、プライマリは、スタンバイが追いつくためにまだ必要なWALファイルが削除されないようにすることができます。

    レプリケーションスロットの前は、プライマリがこれを判断することはできませんでした。また、必要なWALファイルがプライマリによって削除されたためにスタンバイが取り残されたままになる状況になりました。もちろん、WALアーカイブでこの問題を修正できます。ただし、WALアーカイブがない場合、唯一のオプションは、新しいバックアップからスタンバイを再構築することでした。

    レプリケーションスロットの詳細については、こちらをご覧ください。

    ホットスタンバイをセットアップする手順

    既存のプライマリのホットスタンバイをセットアップするために必要な手順を見てみましょう。

    1。レプリケーションユーザーの作成

    まず、スタンバイのユーザーが次のように接続する必要があります:

    $ psql -p 6000
    psql (11.2 (Debian 11.2-1.pgdg90+1))
    Type "help" for help.
    
    postgres=# CREATE USER repluser REPLICATION PASSWORD 'p@ssw0rd';
    CREATE USER

    そして、pg_hba.confの対応する変更 :

    # TYPE  DATABASE        USER          ADDRESS        METHOD
    host    replication     repluser      standby-ip/32  md5
    # (replace standby-ip)

    もちろん、PostgreSQLの標準的な認証メカニズムを使用できます。ユーザーはレプリケーションとログインの権限を持っている必要があり、特定のデータベースにアクセスする必要はありません。

    pg_hba.confへの変更を有効にするには、必ずプライマリサーバーをリロードしてください。

    2。バックアップを取る

    スタンバイは、プライマリのバックアップから開始する必要があります。 pg_basebackupを使用してこれを行うことができ、またそうすべきです。 新しいレプリケーションスロットを使用する場合:

    pg_basebackup -h primary-ip -p 6000 -U repluser -C -S slot_standby1 -R -D standby

    これは、primary-ip:6000でプライマリに接続します 作成したばかりのユーザーを使用して、ディレクトリstandbyにバックアップします。 。新しいレプリケーションスロットslot_standby1 作成されます。

    3。スタンバイ状態でrecovery.confを追加

    このスロットをスタンバイレプリケーションスロットとして使用して、バックアップからの継続性を確保します。

    pg_basebackupに質問しました recovery.confを作成します 上記の私たちのために(「-R」オプション)。それを見てみましょう:

    $ cat standby/recovery.conf
    standby_mode = 'on'
    primary_conninfo = 'user=repluser password=''p@ssw0rd'' host=primary-ip port=6000 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
    primary_slot_name = 'slot_standby1'

    これは実際にはかなり良いことであり、さらに変更する必要はありません。今すぐスタンバイを起動しましょう:

    o$ pg_ctl -D standby -l log_standby -o --port=6001 start
    waiting for server to start.... done
    server started
    postgres@stg1:/tmp/demo$ cat log_standby
    2019-06-19 09:17:50.032 UTC [21733] LOG:  listening on IPv4 address "127.0.0.1", port 6001
    2019-06-19 09:17:50.034 UTC [21733] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.6001"
    2019-06-19 09:17:50.067 UTC [21734] LOG:  database system was interrupted; last known up at 2019-06-19 09:12:05 UTC
    2019-06-19 09:17:50.111 UTC [21734] LOG:  entering standby mode
    2019-06-19 09:17:50.119 UTC [21734] LOG:  redo starts at 0/2000028
    2019-06-19 09:17:50.120 UTC [21734] LOG:  consistent recovery state reached at 0/20000F8
    2019-06-19 09:17:50.120 UTC [21733] LOG:  database system is ready to accept read only connections
    2019-06-19 09:17:50.138 UTC [21739] LOG:  started streaming WAL from primary at 0/3000000 on timeline 1

    以上です!ログファイルは、ストリーミングレプリケーションが稼働中であることを示しています。これで、ポート6001でスタンバイに接続し、読み取り専用クエリを実行して、変更がプライマリからほぼリアルタイムで複製されることを確認できるようになります。

    次のステップ

    PostgreSQLdocsは、Postgresのすべてのレプリケーション関連機能をさらに掘り下げるのに最適な場所です。遅延レプリケーション、カスケードレプリケーション、同期スタンバイなどのトピックを調べる必要があります。

    Postgresには印象的な機能セットが付属していますが、サポートされていないユースケースもあります。このPostgreswikiページには、追加のレプリケーション関連機能を提供するサードパーティツールのリストがあります。


    1. VirtualBoxを使用してMacにSQLServerをインストールする方法

    2. SQL ServerデータベースをMySQLにエクスポートする方法は?

    3. JDBC接続のネットワークタイムアウトの設定

    4. 単一のSQLステートメントの列ヘッダー出力を抑制するにはどうすればよいですか?