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

PostgreSQLストリーミングレプリケーション-詳細

    データベースを管理する人にとって、レプリケーションの知識は必須です。それはおそらくあなたが何度も何度も見たことがあるが、決して古くなることのないトピックです。このブログでは、PostgreSQLの組み込みレプリケーション機能の歴史を少し確認し、ストリーミングレプリケーションの仕組みについて詳しく説明します。

    レプリケーションについて話すときは、WALについてたくさん話します。それでは、先行書き込みログについて少し簡単に確認しましょう。

    先行書き込みログ(WAL)

    先行書き込みログは、データの整合性を確保するための標準的な方法であり、デフォルトで自動的に有効になります。

    WALは、PostgreSQLのREDOログです。しかし、REDOログとは正確には何ですか?

    REDOログには、データベースで行われたすべての変更が含まれ、レプリケーション、リカバリ、オンラインバックアップ、およびポイントインタイムリカバリ(PITR)に使用されます。データページに適用されていない変更は、REDOログからやり直すことができます。

    WALを使用すると、トランザクションによって変更されたすべてのデータファイルではなく、トランザクションがコミットされたことを保証するためにログファイルのみをディスクにフラッシュする必要があるため、ディスク書き込みの数が大幅に減少します。

    WALレコードは、データに加えられた変更をビットごとに指定します。各WALレコードはWALファイルに追加されます。挿入位置はログシーケンス番号(LSN)であり、ログへのバイトオフセットであり、新しいレコードごとに増加します。

    WALは、データディレクトリの下のpg_walディレクトリ(またはPostgreSQLバージョン<10の場合はpg_xlog)に保存されます。これらのファイルのデフォルトサイズは16MBです(サーバーの構築時に--with-wal-segsize設定オプションを変更することでサイズを変更できます)。これらには、「000000010000000000000000」という形式の一意の増分名があります。

    pg_walに含まれるWALファイルの数は、postgresql.conf構成ファイルのパラメーターcheckpoint_segments(または、バージョンによってはmin_wal_sizeとmax_wal_size)に割り当てられた値によって異なります。

    すべてのPostgreSQLインストールを構成するときに設定する必要があるパラメーターの1つは、wal_levelです。 wal_levelは、WALに書き込まれる情報の量を決定します。デフォルト値は最小で、クラッシュまたは即時シャットダウンから回復するために必要な情報のみを書き込みます。アーカイブは、WALアーカイブに必要なロギングを追加します。 hot_standbyは、スタンバイサーバーで読み取り専用クエリを実行するために必要な情報をさらに追加します。論理は、論理デコードをサポートするために必要な情報を追加します。このパラメーターは再起動が必要なため、それを忘れた場合、実行中の実稼働データベースで変更するのは難しい場合があります。

    詳細については、こちらまたはこちらの公式ドキュメントを確認してください。 WALについて説明したので、PostgreSQLでのレプリケーションの履歴を確認しましょう。

    PostgreSQLでのレプリケーションの歴史

    PostgreSQLが実装した最初のレプリケーション方法(ウォームスタンバイ)(バージョン8.2、2006年に遡る)は、ログ配布方法に基づいていました。

    これは、WALレコードが1つのデータベースサーバーから別のデータベースサーバーに直接移動されて適用されることを意味します。継続的なPITRと言えます。

    PostgreSQLは、WALレコードを一度に1つのファイル(WALセグメント)に転送することにより、ファイルベースのログ配布を実装します。

    このレプリケーションの実装には欠点があります。プライマリサーバーで重大な障害が発生した場合、まだ出荷されていないトランザクションが失われます。そのため、データ損失のウィンドウがあります(archive_timeoutパラメーターを使用してこれを調整できます。このパラメーターは数秒に設定できます。ただし、このような低い設定では、ファイルの転送に必要な帯域幅が大幅に増加します)。

    このファイルベースのログ配布方法は、次の図で表すことができます。

    PostgreSQLファイルベースのログ配布その後、バージョン9.0(2010年に遡る) )、ストリーミングレプリケーションが導入されました。

    ストリーミングレプリケーションを使用すると、ファイルベースのログ配布で可能な場合よりも最新の状態を維持できます。これは、WALファイルがいっぱいになるのを待たずに、プライマリサーバーと1つまたは複数のスタンバイサーバー間でWALレコード(WALファイルはWALレコードで構成されます)をオンザフライ(レコードベースのログ配布)で転送することで機能します。

    実際には、スタンバイサーバーで実行されているWALレシーバーと呼ばれるプロセスは、TCP/IP接続を使用してプライマリサーバーに接続します。プライマリサーバーには、WAL送信者という名前の別のプロセスが存在し、WALレジストリをスタンバイサーバーに送信する役割を果たします。

    次の図は、ストリーミングレプリケーションを表しています。

    PostgreSQLストリーミングレプリケーション上の図を見ると、何が起こるのか不思議に思うかもしれません。 WAL送信者とWAL受信者の間の通信が失敗した場合

    ストリーミングレプリケーションを構成するときに、WALアーカイブを有効にするオプションがあります。

    この手順は必須ではありませんが、堅牢なレプリケーション設定にとって非常に重要です。メインサーバーがスタンバイサーバーにまだ適用されていない古いWALファイルをリサイクルしないようにする必要があります。これが発生した場合は、レプリカを最初から再作成する必要があります。

    継続的なアーカイブを使用してレプリケーションを構成する場合、バックアップから開始します。プライマリとの同期状態に到達するには、バックアップ後に発生したWALでホストされているすべての変更を適用する必要があります。このプロセス中、スタンバイは最初にアーカイブの場所で使用可能なすべてのWALを復元します(restore_commandを呼び出すことによって実行されます)。 restore_commandは、最後にアーカイブされたWALレコードに到達すると失敗するため、その後、スタンバイはpg_walディレクトリを調べて、そこに変更が存在するかどうかを確認します(これにより、プライマリサーバーがクラッシュしたときのデータ損失と、すでに移動され、レプリカに適用されていますが、まだアーカイブされていません。

    それが失敗し、要求されたレコードがそこに存在しない場合、ストリーミングレプリケーションを介してプライマリサーバーとの通信を開始します。

    ストリーミングレプリケーションが失敗すると、手順1に戻り、アーカイブからレコードが再度復元されます。アーカイブpg_walからの再試行のこのループは、サーバーが停止するか、トリガーファイルによってフェイルオーバーがトリガーされるまで続きます。

    次の図は、継続的なアーカイブを使用したスト​​リーミングレプリケーション構成を表しています。

    継続的なアーカイブを使用したPostgreSQLストリーミングレプリケーションストリーミングレプリケーションはデフォルトで非同期であるため、いつでも、プライマリサーバーにコミットでき、スタンバイサーバーにまだレプリケートされていないトランザクションが発生する可能性があります。これは、潜在的なデータ損失を意味します。

    ただし、コミットとレプリカの変更の影響との間のこの遅延は、もちろん、レプリカサーバーが追いつくのに十分強力であると仮定すると、非常に小さい(数ミリ秒)と想定されます。負荷。

    わずかなデータ損失のリスクさえ許容できない場合のために、バージョン9.1では同期レプリケーション機能が導入されました。

    同期レプリケーションでは、書き込みトランザクションの各コミットは、コミットがプライマリサーバーとスタンバイサーバーの両方のディスクの先行書き込みログに書き込まれるという確認が受信されるまで待機します。

    この方法は、データ損失の可能性を最小限に抑えます。そのためには、プライマリとスタンバイの両方が同時に失敗する必要があります。

    この構成の明らかな欠点は、すべての関係者が応答するまで待機する必要があるため、各書き込みトランザクションの応答時間が長くなることです。したがって、コミットの時間は、少なくとも、プライマリとレプリカの間のラウンドトリップです。読み取り専用トランザクションはこれによる影響を受けません。

    同期レプリケーションを設定するには、各スタンバイserver.confファイルのリカバリのprimary_conninfoでapplication_nameを指定する必要があります:primary_conninfo ='... aplication_name=standbyX'。

    同期レプリケーションに参加するスタンバイサーバーのリストも指定する必要があります:synchronous_standby_name ='standbyX、standbyY'。

    1つまたは複数の同期サーバーをセットアップできます。このパラメーターは、リストされたものから同期スタンバイを選択する方法(FIRSTおよびANY)も指定します。同期レプリケーションモードの設定の詳細については、このブログをご覧ください。 ClusterControlを介してデプロイするときに同期レプリケーションを設定することもできます。

    レプリケーションを構成して稼働させたら、モニタリングを実装する必要があります

    PostgreSQLレプリケーションの監視

    マスターサーバーのpg_stat_replicationビューには、多くの関連情報があります。

    postgres=# SELECT * FROM pg_stat_replication;
    -[ RECORD 1 ]----+------------------------------
    pid              | 756
    usesysid         | 16385
    usename          | cmon_replication
    application_name | pgsql_0_node_0
    client_addr      | 10.10.10.137
    client_hostname  |
    client_port      | 36684
    backend_start    | 2022-04-13 17:45:56.517518+00
    backend_xmin     |
    state            | streaming
    sent_lsn         | 0/400001C0
    write_lsn        | 0/400001C0
    flush_lsn        | 0/400001C0
    replay_lsn       | 0/400001C0
    write_lag        |
    flush_lag        |
    replay_lag       |
    sync_priority    | 0
    sync_state       | async
    reply_time       | 2022-04-13 17:53:03.454864+00
    これを詳しく見てみましょう:

    • pid:walsenderプロセスのプロセスID。

    • usesysid:ストリーミングレプリケーションに使用されるユーザーのOID。

    • usename:ストリーミングレプリケーションに使用されるユーザーの名前。

    • application_name:マスターに接続されているアプリケーション名。

    • client_addr:スタンバイ/ストリーミングレプリケーションのアドレス。

    • client_hostname:スタンバイのホスト名。

    • client_port:スタンバイがWAL送信者と通信するTCPポート番号。

    • backend_start:SRがプライマリに接続したときの開始時刻。

    • 状態:現在のWAL送信者の状態、つまりストリーミング。

    • send_lsn:スタンバイに送信された最後のトランザクションの場所。

    • write_lsn:スタンバイ時にディスクに書き込まれた最後のトランザクション。

    • flush_lsn:スタンバイ時のディスクでの最後のトランザクションフラッシュ。

    • reply_lsn:スタンバイ時のディスクでの最後のトランザクションフラッシュ。

    • sync_priority:同期スタンバイとして選択されたスタンバイサーバーの優先度。

    • sync_state:スタンバイの同期状態(非同期か同期か)

    サーバー上で実行されているWAL送信者/受信者プロセスも確認できます。

    送信者(プライマリノード):

    [[email protected] ~]# ps aux |grep postgres
    postgres     727  0.0  2.2 917060 47936 ?        Ss   17:45   0:00 /usr/pgsql-14/bin/postmaster -D /var/lib/pgsql/14/data/
    postgres     732  0.0  0.2 351904  5280 ?        Ss   17:45   0:00 postgres: 14/main: logger
    postgres     734  0.0  0.5 917188 10560 ?        Ss   17:45   0:00 postgres: 14/main: checkpointer
    postgres     735  0.0  0.4 917208  9908 ?        Ss   17:45   0:00 postgres: 14/main: background writer
    postgres     736  0.0  1.0 917060 22928 ?        Ss   17:45   0:00 postgres: 14/main: walwriter
    postgres     737  0.0  0.4 917748  9128 ?        Ss   17:45   0:00 postgres: 14/main: autovacuum launcher
    postgres     738  0.0  0.3 917060  6320 ?        Ss   17:45   0:00 postgres: 14/main: archiver last was 00000001000000000000003F
    postgres     739  0.0  0.2 354160  5340 ?        Ss   17:45   0:00 postgres: 14/main: stats collector
    postgres     740  0.0  0.3 917632  6892 ?        Ss   17:45   0:00 postgres: 14/main: logical replication launcher
    postgres     756  0.0  0.6 918252 13124 ?        Ss   17:45   0:00 postgres: 14/main: walsender cmon_replication 10.10.10.137(36684) streaming 0/400001C0

    受信者(スタンバイノード):

    [[email protected] ~]# ps aux |grep postgres
    postgres     727  0.0  2.2 917060 47576 ?        Ss   17:45   0:00 /usr/pgsql-14/bin/postmaster -D /var/lib/pgsql/14/data/
    postgres     732  0.0  0.2 351904  5396 ?        Ss   17:45   0:00 postgres: 14/main: logger
    postgres     733  0.0  0.3 917196  6360 ?        Ss   17:45   0:00 postgres: 14/main: startup recovering 000000010000000000000040
    postgres     734  0.0  0.4 917060 10056 ?        Ss   17:45   0:00 postgres: 14/main: checkpointer
    postgres     735  0.0  0.3 917060  6304 ?        Ss   17:45   0:00 postgres: 14/main: background writer
    postgres     736  0.0  0.2 354160  5456 ?        Ss   17:45   0:00 postgres: 14/main: stats collector
    postgres     737  0.0  0.6 924532 12948 ?        Ss   17:45   0:00 postgres: 14/main: walreceiver streaming 0/400001C0

    レプリケーションがどの程度最新であるかを確認する1つの方法は、プライマリサーバーで生成されたがスタンバイサーバーではまだ適用されていないWALレコードの量を確認することです。

    プライマリ:

    postgres=# SELECT pg_current_wal_lsn();
     pg_current_wal_lsn
    --------------------
     0/400001C0
    (1 row)

    スタンバイ:

    postgres=# SELECT pg_last_wal_receive_lsn();
     pg_last_wal_receive_lsn
    -------------------------
     0/400001C0
    (1 row)
    postgres=# SELECT pg_last_wal_replay_lsn();
     pg_last_wal_replay_lsn
    ------------------------
     0/400001C0
    (1 row)

    スタンバイノードで次のクエリを使用して、秒単位でラグを取得できます。

    postgres=# SELECT CASE WHEN pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn()
    THEN 0
    ELSE EXTRACT (EPOCH FROM now() - pg_last_xact_replay_timestamp())
    END AS log_delay;
     log_delay
    -----------
             0
    (1 row)

    また、最後に受信したメッセージを確認することもできます:

    postgres=# SELECT status, last_msg_receipt_time FROM pg_stat_wal_receiver;
      status   |    last_msg_receipt_time
    -----------+------------------------------
     streaming | 2022-04-13 18:32:39.83118+00
    (1 row)

    ClusterControlを使用したPostgreSQLレプリケーションの監視

    PostgreSQLクラスターを監視するには、ClusterControlを使用して、展開、バックアップ、スケールアウトなどのいくつかの追加の管理タスクを監視および実行できます。

    概要セクションには、データベースクラスターの全体像が表示されます。現在のステータス。詳細を確認するには、ダッシュボードセクションにアクセスしてください。ダッシュボードセクションには、さまざまなグラフに分けられた多くの役立つ情報が表示されます。

    トポロジセクションでは、ユーザーの現在のトポロジを確認できます-使いやすい方法であり、[ノードアクション]ボタンを使用して、ノード上でさまざまなタスクを実行することもできます。

    ストリーミングレプリケーションは、WALレコードを送信してスタンバイに適用することに基づいていますサーバーでは、どのファイルにどのバイトを追加または変更するかを指示します。その結果、スタンバイサーバーは実際にはプライマリサーバーのビットごとのコピーになります。ただし、ここにはいくつかのよく知られた制限があります:

    • 別のバージョンまたはアーキテクチャに複製することはできません。

    • スタンバイサーバーでは何も変更できません。

    • 複製する内容の粒度はあまりありません。

    したがって、これらの制限を克服するために、PostgreSQL10は論理レプリケーションのサポートを追加しました

    論理レプリケーション

    論理レプリケーションもWALファイルの情報を使用しますが、論理変更にデコードします。どのバイトが変更されたかを知る代わりに、どのデータがどのテーブルに挿入されたかを正確に知ることができます。

    これは、「パブリッシュ」および「サブスクライブ」モデルに基づいており、1人以上のサブスクライバーが次のようなパブリッシャーノード上の1つ以上のパブリケーションをサブスクライブします。

    PostgreSQL論理レプリケーション まとめ

    ストリーミングレプリケーションを使用すると、WALレコードを継続的に送信してスタンバイサーバーに適用できるため、プライマリサーバーで更新された情報がスタンバイサーバーにリアルタイムで転送され、両方の同期が維持されます。 。

    ClusterControlを使用すると、ストリーミングレプリケーションの設定が簡単になり、30日間無料で評価できます。

    PostgreSQLでの論理レプリケーションについて詳しく知りたい場合は、論理レプリケーションの概要とPostgreSQLレプリケーションのベストプラクティスに関するこの投稿を確認してください。

    オープンソースベースのデータベースを管理するためのその他のヒントとベストプラクティスについては、TwitterとLinkedInでフォローし、ニュースレターを購読して定期的に更新してください。


    1. Group_Concat()がSQLiteでどのように機能するか

    2. データマスキングによるデータリスクの軽減

    3. 致命的なエラー:nullでメンバー関数query()を呼び出す

    4. CentOS8にMariaDBをインストールして保護する方法