PostgreSQLでの物理的複製と論理的複製の違いについて誰か教えてもらえますか?
TL; DR:論理レプリケーションは行ごとの変更を送信し、物理レプリケーションはディスクブロックの変更を送信します。論理的なレプリケーションは、一部のタスクには適していますが、他のタスクには物理的なレプリケーションが適しています。
9.5の時点で、論理レプリケーションはかなり未熟です。この質問をする場合は、物理レプリケーションを使用してください。
ストリーミング複製は、論理複製にすることができます。それはすべて少し複雑です。
PostgreSQLでマスターからレプリカにデータを送信するには、主に2つの方法があります。
WAL-shippingまたは連続アーカイブ、個々の先読みログファイルは、マスターで実行されているpg_xlog
によってarchive_command
から他の場所にコピーされます。レプリカのrestore_command
で構成されたrecovery.conf
は、レプリカでWALを再生できるようにアーカイブをフェッチするためにレプリカで実行されます。
これは、ポイントインタイムレプリケーション(PITR)に使用されるものであり、連続バックアップの方法として使用されます。
マスターサーバーへの直接ネットワーク接続は必要ありません。特にarchive_timeout
が設定されていない場合、レプリケーションの遅延が長くなる可能性があります。 WALシッピングは、同期レプリケーションには使用できません。
ストリーミングレプリケーション。各変更は、TCP/IP接続を介して1つ以上のレプリカサーバーに直接送信されます。レプリカには、recovery.conf
のprimary_conninfo
オプションで構成されたマスターの直接ネットワーク接続が必要です。
複製が遅れないように十分に高速である限り、ストリーミングレプリケーションの遅延はほとんど、またはまったくありません。 同期レプリケーションに使用できます。 PITRにはストリーミングレプリケーションを使用できません1 そのため、連続バックアップにはあまり使用されません。マスターにテーブルをドロップすると、レプリカにもドロップされます。
したがって、2つの方法の目的は異なります。
その上に、synchronousとasynchronousストリーミングレプリケーションがあります。
非同期ストリーミングレプリケーションでは、マスターが高速/ビジーの場合、レプリカはマスターに遅れをとることができます。マスターがクラッシュすると、まだ複製されていないデータが失われる可能性があります。
非同期レプリカがマスターから大幅に遅れる場合、wal_keep_segments
が低すぎてスロットが使用されない場合、マスターはレプリカが必要とする情報を破棄する可能性があります。つまり、レプリカを最初から再作成する必要があります。または、pg_xlog
が高すぎるか、スロットが使用されている場合、マスターのwal_keep_segments
がいっぱいになり、ディスク容量が解放されるまでマスターが動作しなくなる可能性があります。
同期レプリケーションでは、マスターはレプリカがトランザクションを受信したことを確認するまでコミットを終了しません2。マスターがクラッシュした場合、データを失うことはなく、レプリカにフェールオーバーする必要があります。マスターは、レプリカが必要とするデータを破棄したり、レプリカの遅延のためにxlogをいっぱいにしたり、ディスク領域を使い果たしたりすることはありません。その代わりに、レプリカに問題がある場合、マスターの速度が低下したり、動作が停止したりする可能性があります。また、ネットワーク遅延により、マスターのパフォーマンスに常に何らかの影響があります。
複数のレプリカがある場合、一度に1つだけが同期します。 synchronous_standby_names
を参照してください。
同期ログ配布を使用することはできません。
実際には、ログ配布と非同期レプリケーションを組み合わせて、マスターに影響を与えるリスクを冒すことなく、レプリカが遅れすぎた場合にレプリカを再作成する必要がないように保護できます。これは、多くの展開にとって理想的な構成であり、レプリカがマスターからどれだけ離れているかを監視して、許容される災害復旧の制限内であることを確認します。
thatの上に、logicalvsphysicalPostgreSQL 9.4で導入されたストリーミングレプリケーション:
物理ストリーミングレプリケーションの変更は、「123123のディスクページ18のオフセット14で、16進値0x2342beef1222でタプルを書き込みました」のように、ほぼディスクブロックレベルで変更が送信されます.... "。
物理レプリケーションはeverythingを送信します:PostgreSQLインストールのすべてのデータベースの内容、すべてのデータベースのすべてのテーブル。インデックスエントリを送信し、VACUUM FULL
のときに新しいテーブルデータ全体を送信し、ロールバックしたトランザクションのデータを送信します。したがって、大量の「ノイズ」を生成し、大量の過剰データを送信します。また、レプリカが完全に同一である必要があるため、一時テーブルまたはログなしテーブルの作成など、トランザクションを必要とすることはできません。レプリカのクエリはレプリケーションを遅らせるので、レプリカの長いクエリをキャンセルする必要があります。
その代わりに、レプリカに変更を適用するのは簡単で効率的であり、レプリカは確実にマスターとまったく同じです。 DDLは、他のすべてと同様に透過的に複製されるため、特別な処理は必要ありません。また、大きなトランザクションが発生したときにストリーミングできるため、大きな変更があったとしても、マスターでのコミットとレプリカでのコミットの間に遅延はほとんどありません。
物理レプリケーションは成熟しており、十分にテストされており、広く採用されています。
論理ストリーミングレプリケーションは、9.4の新機能であり、変更をより高いレベルで送信し、より選択的に送信します。
一度に1つのデータベースのみを複製します。行の変更のみ、コミットされたトランザクションのみに送信します。バキュームデータ、インデックスの変更などを送信する必要はありません。データベース内の一部のテーブルのみにデータを選択的に送信できます。これにより、論理レプリケーションmuchの帯域幅効率が向上します。
また、より高いレベルで動作するということは、レプリカデータベースでトランザクションを実行できることを意味します。一時テーブルとログなしテーブルを作成できます。必要に応じて、通常のテーブルでも。外部データラッパー、ビュー、関数の作成など、好きなものを使用できます。クエリの実行時間が長すぎる場合でも、クエリをキャンセルする必要はありません。
論理レプリケーションを使用して、PostgreSQLでマルチマスターレプリケーションを構築することもできますが、これは物理レプリケーションでは不可能です。
ただし、これと引き換えに、大きなトランザクションが発生したときに(現在)ストリーミングすることはできません。コミットするまで待つ必要があります。そのため、マスターでコミットする大きなトランザクションとレプリカに適用されるまでに長い遅延が発生する可能性があります。
トランザクションを厳密にコミット順でリプレイするため、小さな高速トランザクションが大きなトランザクションの背後でスタックし、かなり遅れる可能性があります。
DDLは自動的に処理されません。マスターとレプリカの間でテーブル定義の同期を自分で維持する必要があります。そうしないと、論理レプリケーションを使用するアプリケーションに独自の機能が必要になります。これを正しくするのは複雑な場合があります。
適用プロセス自体は、「指示された場所にいくつかのバイトを書き込む」よりも複雑です。また、物理的な複製よりもレプリカ上のリソースが多くなります。
現在の論理レプリケーションの実装は、成熟していないか、広く採用されていないか、特に使いやすいです。
ふう。複雑ですか?また、遅延レプリケーション、スロット、wal_keep_segments
、タイムライン、プロモーションの仕組み、Postgres-XL、BDR、マルチマスターなどの詳細についても触れていません。
それで、何をすべきかdo?
正しい答えはありません。それ以外の場合、PostgreSQLはその一方向のみをサポートします。ただし、いくつかの一般的な使用例があります。
バックアップと災害復旧の場合、pgbarman
を使用してベースバックアップを作成し、WALを保持して、管理しやすい連続バックアップを提供します。追加の保険として定期的にpg_dump
バックアップを取る必要があります。
データ損失ゼロの高可用性の場合、ストリーミング同期レプリケーションを使用します。
データ損失リスクが低く、パフォーマンスが高い高可用性の場合、非同期ストリーミングレプリケーションを使用する必要があります。フォールバック用にWALアーカイブを有効にするか、複製スロットを使用します。 Icingaなどの外部ツールを使用して、レプリカがマスターからどれだけ離れているかを監視します。