プロンプトとコンテキスト
PostgreSQL 18のパブリッシャーは、レポートおよびリージョンサービスに使用されるサブスクライバーに対して、選択されたテナントと列のみをレプリケーションする必要があります。行フィルタと列リストのセマンティクス、UPDATEがフィルタ境界をまたぐ際に何が起こるか、初期同期、パーティションの挙動、および安全な運用計画について説明してください。
PostgreSQLのドキュメントには、行フィルタは行が式を満たすかどうかを発行前に判定する一方で、列リストは転送される列を削減するもののセキュリティ境界ではないと記載されています。この面接では、パブリケーションに WHERE 句を追加すること単体ではなく、レプリケーションのセマンティクス、一貫性、および変更管理が試されます。
面接官がテストしていること
レプリケーション接続ロールがフィルタを評価すること、false または NULL は行を除外すること、および TRUNCATE は影響を受けないことを説明できる必要があります。新旧のUPDATE変換を導出し、レプリカアイデンティティ、初期同期、パブリケーション間でのOR結合フィルタ、パーティションルート、および列リストの変更に対処し、列リストが機密性を提供するものではないことを認識しているかどうかが問われます。
最初に明確にすべき質問
レプリケーション対象
サブスクライバーが必要とするテナント、操作、および列、初期スナップショットが許可されているか、書き込みが双方向であるか、サブスクライバーのバージョンが15または18より古いかを確認します。
アイデンティティとフィルタリング
テーブルのレプリカアイデンティティ、フィルタ列が変更可能かどうか、パーティションルートのパブリケーションが使用されているか、複数のパブリケーションが同一テーブルを対象としているかを確認します。
セキュリティとリカバリ
機密列を完全に不可視にする必要があるか、レプリケーションロールの権限、ネットワーク分離、サブスクリプションの再構築手順、および不正なフィルタに対するロールバック期間を確認します。
30秒での回答
「行フィルタはパブリケーションに含まれる行の変更を定義します。false または NULL は変更を破棄しますが、列リストは転送される列を削減するだけであり、セキュリティ境界ではありません。UPDATEは新旧両方の行を評価します。不一致から一致への変化はINSERTになり、一致から不一致への変化はDELETEになり、一致から一致の場合のみUPDATEのままになります。UPDATEまたはDELETEの場合、フィルタ列および発行される列はレプリカアイデンティティをカバーしている必要があります。ロールアウト前には、パブリケーションの変更を凍結し、初期同期、パーティション、OR結合フィルタ、旧バージョンの挙動をテストするとともに、パブリッシャー側の権限やビューで機密データを保護します。」
ステップバイステップの詳細な回答
ステップ 1: パブリケーションの不変条件を定義する
各テーブルについて、許可されるテナントセット、操作、列セット、フィルタ式、およびサブスクライバーのバージョンを記録します。目的がパフォーマンスのための削減なのか、動作の分離なのか、セキュリティなのかを決定します。セキュリティの目的を列リストのみに依存することはできません。
ステップ 2: 行フィルタを設計する
フィルタはレプリケーション接続のロールを使用し、ドキュメントに記載された単純な式のみを使用してパブリケーション前に実行されます。false または NULL の結果は行を除外(抑制)し、TRUNCATE は影響を受けません。UPDATEまたはDELETEを含むパブリケーションの場合、フィルタ列はレプリカアイデンティティによってカバーされている必要があります。INSERTのみのパブリケーションは他の列を使用できます。
ステップ 3: UPDATEの変換を導出する
更新の前後でフィルタを評価します。一致から一致はUPDATEを送信し、不一致から不一致は何もしません。不一致から一致はINSERTを送信し、一致から不一致はDELETEを送信します。したがって、サブスクライバーはすべてのUPDATEを盲目的に再生するのではなく、フィルタを満たす現在の行セットを表現します。
ステップ 4: 列リストを制約する
列リストにはレプリカアイデンティティ列が含まれている必要があり、サブスクライバーテーブルには少なくとも発行される列が含まれている必要があります。リストの順序はレプリケーションに影響しません。リストを省略すると、後から追加された列が自動的に含まれます。現在のすべての列を明示的に指定した場合、将来追加される列は含まれません。パブリケーション間で同一テーブルに対して異なるリストが存在するとサブスクリプションの再開が妨げられる場合があるため、変更前に確認してください。
CREATE PUBLICATION tenant_eu
FOR TABLE orders (order_id, tenant_id, status, total)
WHERE (tenant_id = 'eu');ステップ 5: 初期同期を処理する
初期同期では、行フィルタを満たす既存の行と、リスト内の列のみがコピーされます。バージョン15より前のサブスクライバーはテーブル全体をコピーする可能性があり、18より前のバージョンには生成列に関する追加の制限があります。トラフィックを切り替える前に、スナップショット中のバージョンマトリックスと書き込みバックログを確認してください。
ステップ 6: パーティションと複数のパブリケーションを処理する
publish_via_partition_root=true の場合、ルートのパーティションテーブルのフィルタまたは列リストが使用されます。デフォルトの false の場合、各パーティションの定義が使用されます。パブリケーション間において、同一テーブルかつ同一発行操作に対する行フィルタはOR結合されます。したがって、フィルタのないパブリケーションがあると、他のフィルタで期待されるプルーニングが無効になる可能性があります。
ステップ 7: 運用上のガードレールを追加する
パブリケーション定義をマイグレーションとしてレビューし、フィルタヒット率、レプリケーション遅延、競合、初期同期行数、およびルールバージョンを記録します。シャドウサブスクリプションで新旧の境界ケースをテストします。行が漏洩または消失した場合は、サブスクリプションを一時停止し、パブリケーションを修正し、整合性チェックを行った後に再構築します。
模範解答
行フィルタは発行対象セットの定義として、列リストは転送削減として扱います。レプリケーションロールがフィルタを評価するため、false/NULL および TRUNCATE には明示的なテストが必要です。UPDATEは新旧の行を比較し、境界を越える際にはINSERTまたはDELETEに変換されます。UPDATE/DELETEの場合、フィルタ列および発行列はレプリカアイデンティティをカバーしなければなりません。初期同期、パーティションルート、およびOR結合されたパブリケーションはテストマトリックスに含めるべきです。機密データはパブリッシャーの権限、ビュー、または個別のデータマスキングパイプラインで保護し、列リストはパフォーマンスと形状制御のために使用します。
よくある間違い
- 間違い: 列リストによって悪意のあるサブスクライバーが未発行の列を取得するのを防げると想定すること。 → なぜ失敗するか: 公式ドキュメントにはセキュリティ機構ではないと記載されています。 → 修正方法: パブリッシャーの権限、ビュー、またはデータマスキングによって機密性を強制します。
- 間違い: 新しい行のみでUPDATEを評価すること。 → なぜ失敗するか: 行がフィルタされたセットから出たり入ったりする可能性があるためです。 → 修正方法: 新旧両方の行を評価し、4つの結果すべてを適用します。
- 間違い: レプリカアイデンティティを無視すること。 → なぜ失敗するか: UPDATE/DELETEが古い行を安全に特定できなくなります。 → 修正方法: フィルタおよび列リストにおけるアイデンティティのカバレッジを確認します。
- 間違い: 複数の限定的なパブリケーションがあれば、全体としてのストリームも限定されると想定すること。 → なぜ失敗するか: 同一の発行操作に対するフィルタはOR結合されます。 → 修正方法: 和集合を計算し、フィルタのないカバレッジを拒否します。
フォローアップの質問と回答
行フィルタと個別のパブリケーションはそれぞれどのような場合に使用すべきですか?
テナントやリージョンの境界が安定的で、式が単純な場合は行フィルタを使用します。権限、ライフサイクル、および運用担当チームが異なる場合は、パブリケーションとサブスクリプションを分離した方が監査が容易になります。どちらの場合も、初期同期と変更コストを評価してください。
新しい列の偶発的なレプリケーションを防ぐにはどうすればよいですか?
明示的な列リストを使用し、スキーマレビューを通じてそれを更新します。現在のすべての列を明示的に指定することと、リストを省略することを混同しないでください。省略すると将来の列が自動的に含まれます。
境界をまたぐUPDATEをテストするにはどうすればよいですか?
「旧=false/新=true」、「旧=true/新=false」、「両方=true」、「両方=false」の4つのケースを作成します。サブスクライバー側でそれぞれINSERT、DELETE、UPDATE、およびイベントなしとなることを検証します。
フィルタリングでマルチテナントのセキュリティ分離を代替できますか?
いいえ。論理レプリケーションのデータを選択するだけです。分離には引き続き最小権限のパブリッシャーロール、個別の認証情報、ネットワーク制御、および必要に応じたデータマスキングが必要です。