データはどのように複製されるのですか?
PostgreSQL ロジカルデコード
ReplacingMergeTree
_peerdb_version) を持つ行の insert として表現され、削除はより新しいバージョンを持ち、_peerdb_is_deleted が true に設定された行の insert として表現されます。ReplacingMergeTree エンジンはバックグラウンドでデータの重複排除とマージを行い、指定された主キー (id) ごとに最新バージョンの行を保持することで、UPDATE と DELETE をバージョン付き insert として効率的に処理できます。
以下は、ClickPipes が ClickHouse にテーブルを作成する際に実行する CREATE TABLE ステートメントの例です。
図解例
users を同期する基本的な例を示しています。
Step 1 では、PostgreSQL 内の 2 行の初期スナップショットと、ClickPipes がその 2 行を ClickHouse に初期ロードする様子を示しています。ご覧のとおり、2 行ともそのまま ClickHouse にコピーされます。
Step 2 では、users テーブルに対する 3 つの操作、つまり新しい行の挿入、既存の行の更新、別の行の削除を示しています。
Step 3 では、ClickPipes が INSERT、UPDATE、DELETE の各操作を、バージョン付きの INSERT として ClickHouse にレプリケートする仕組みを示しています。UPDATE は ID 2 の行の新しいバージョンとして現れ、DELETE は _is_deleted が true に設定された ID 1 の新しいバージョンとして現れます。このため、ClickHouse には PostgreSQL より 3 行多く存在することになります。
その結果、SELECT count(*) FROM users; のような単純なクエリを実行すると、ClickHouse と PostgreSQL で異なる結果になる場合があります。ClickHouse のマージに関するドキュメント によると、古い行バージョンは最終的にマージ処理の中で破棄されます。ただし、このマージがいつ行われるかは予測できないため、それまでは ClickHouse のクエリが一貫しない結果を返す可能性があります。
ClickHouse と PostgreSQL の両方で同一のクエリ結果を確実に得るには、どうすればよいでしょうか?
FINALキーワードを使って重複排除する
- シンプルな件数カウントクエリ: posts の数をカウントします。
- JOIN を使った単純な集計: 最も多くの閲覧数を獲得しているユーザー上位 10 人。
FINAL 設定
ROW POLICY
_peerdb_is_deleted = 0 フィルタを隠す簡単な方法は、ROW POLICY. を使用することです。以下は、テーブル votes に対するすべてのクエリから削除済みの行を除外する ROW POLICY を作成する例です。
ROW POLICY は、ユーザーとロールの一覧に対して適用されます。この例では、すべてのユーザーとロールに適用されます。必要に応じて、特定のユーザーまたはロールのみに適用するよう調整できます。
Postgresと同じようにクエリする
ビュー
リフレッシャブルmaterialized view
deduplicated_posts を通常どおりクエリできます。