5秒に1回、modified_timestamp列に基づいてPostgresテーブルからすべてのデータを取得するデータプル機能があります。次のように機能します。
SELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp
modified_timestampがトリガーで更新された場所(行の更新後modified_timestampはCURRENT_TIMESTAMP
)。 CURRENT_TIMESTAMP
Postgresは実際にはトランザクション開始のタイムスタンプであり、一部の更新が失われています。なぜ彼らは失われたのですか?それは非常に簡単です-クエリを実行する現時点ではSELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp
一部の変更はすでに発生していますが、modified_timestampは更新される前です_ some_persisted_timestampトランザクションがまだ進行中であるため。
この問題は、step 2timestampを他のトランザクションで更新が表示されたときに割り当てることで簡単に解決できます(つまり、トランザクションコミットのタイムスタンプ)CURRENT_TIMESTAMPまたはclock_timestamp()の代わり。
ドキュメントを読みましたが、トランザクションコミットのタイムスタンプに関連するものは何も見つかりませんでした。あなたは親切に親切に提案してもらえますか?
ところで、私は 論理デコード を知っています。理論上、このメカニズムは私のニーズにより適していることを知っていますが、使用できない特定の実際的な問題があります。
この問題は、ステップ2で、CURRENT_TIMESTAMPまたはclock_timestamp()の代わりに、他のトランザクション(トランザクションコミットのタイムスタンプ)の更新が表示されるときのタイムスタンプを割り当てることで簡単に解決できます。
これは論理的に不可能です。 Postgresは新しい行バージョンbeforeを書き込み、最終的にコミットしてそれらを可視にします。執筆時点では不明な将来のタイムスタンプを書き込むには、予言機能が必要です。
ただし、別のソースからコミットタイムスタンプを取得できます。Postgres9.5以降、GUC設定があります- _track_commit_timestamp
_コミットタイムスタンプのグローバルなロギングを開始します。
次に、ユーティリティ関数 pg_xact_commit_timestamp(xid)
でコミットタイムスタンプを取得できます。クエリは次のようになります。
_SELECT * FROM my_table t
WHERE pg_xact_commit_timestamp(t.xmin) > _some_persisted_timestamp;
_
あなたのstep 2 andstep 3トレードポジション、そして_CURRENT_TIMESTAMP
_-またはxmin
の代わりにコミットタイムスタンプを記録して、新しく更新された行からpg_xact_commit_timestamp()
でコミットタイムスタンプをもう一度取得します。
もっと:
xmin
について:
しかし、私はあなたの仕事を理解していることを完全には確信していません。たぶん、ここで説明したように、キューイングツールが必要か、行を1つずつ処理します。