ロジカルデコーディングは、データベースのテーブルへの恒久的な更新を、一貫性があって、データベース内部の状態に関する詳細な知識がなくても容易に理解できる形式として取得するプロセスです。
PostgreSQLにおいてロジカルデコーディングは、記憶装置のレベルで更新を記述する書き込先行みログの内容を、タプルやSQL文のストリームといったアプリケーション固有の形式にデコードすることによって実装されています。
ロジカルレプリケーションの文脈ではスロットは、元のサーバで行われた変更と同じ順序でクライアント上でリプレイできるようなストリームを表します。 それぞれのスロットは、単一のデータベース上の変更操作の連鎖をストリームとして流します。その際、それぞれの変更操作は厳密に一度だけ送出されます(ストリーム上で前方を覗き見る場合を除きます)。
またPostgreSQLには、ストリーミングレプリケーションスロットがあります (25.2.5. ストリーミングレプリケーション参照)。しかし、ここでの説明とは少し違う使い方がされています。
それぞれのレプリケーションスロットはPostgreSQLクラスタの中でユニークな識別子を持っています。スロットは、そのために使用される接続とは独立しており、クラッシュセーフです。
単一のデータベース中に、お互いに独立した複数のスロットが存在しても構いません。 それぞれのスロットは自分自身の状態を持っており、データベース更新のストリーム上の別の場所から変更データを受信する異なる消費者があり得ます。 多くのアプリケーションにとっては、各消費者に対して個別のスロットが必要となるでしょう。
ロジカルレプリケーションスロットは、受信者の状態については関知しません。同時にでなければ、同じスロットを使う複数の異なる受信者を持つことさえできます。その場合は、直近の受信者がストリームの消費を終了した時点から更新データを受信するだけです。
レプリケーションスロットは、クラッシュをまたがって永続し、消費者の状態については関知しません。
スロットを使う接続がない場合でも、消費者が必要としているリソースが削除されることを防ぎます。
これによりストレージが消費されます。何故ならば、関連するWALもシステムカタログの行も、レプリケーションスロットが必要とする限りVACUUM
によって削除されないからです。
したがって、必要でなくなったスロットは削除すべきです。
出力プラグインは、書き込み先行ログの内部データ表現を、レプリケーションスロットの消費者が必要とする形式に変換します。
ストリーミングレプリケーションのインターフェイスを使って新しいスロットを作ると、スナップショットがエキスポートされます(9.26.5. スナップショット同期関数参照)。
このスナップショットはまさにその時点でのデータベースの状態を示しており、スナップショット以後のすべての変更は更新ストリームに含まれるようになります。
このことを利用して、スロットが作られた際のデータベースの状態をSET TRANSACTION SNAPSHOT
を使って読み込むことにより、新しいレプリカを作ることができます。
このトランザクションは、その時点のデータベースの状態をダンプするために使用することができます。
また、スロットに含まれるデータを使って、ダンプした後で行われた更新を失うことなくデータベースを更新できます。