J'ai une fonctionnalité d'extraction de données qui, toutes les 5 secondes, récupère toutes les données de la table Postgres sur la base de la colonne modified_timestamp . Cela fonctionne de la manière suivante:
SELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp
Où horodatage modifié mis à jour avec le déclencheur (après toute mise à jour de ligne horodatage modifié devient CURRENT_TIMESTAMP
). Cela a bien fonctionné jusqu'à ce que je remarque que CURRENT_TIMESTAMP
dans Postgres est en fait l'horodatage de début de transaction et certaines des mises à jour sont perdues. Pourquoi sont-ils perdus? C'est assez simple - au moment où j'exécute la requête SELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp
certaines des modifications ont déjà eu lieu, mais modified_timestamp est avant la mise à jour _ some_persisted_timestamp car la transaction est toujours en cours.
Ce problème pourrait être facilement résolu en affectant dans étape 2 horodatage lorsque la mise à jour devient visible pour d'autres transactions (horodatage de validation de transaction en d'autres termes) au lieu de CURRENT_TIMESTAMP ou clock_timestamp ().
J'ai lu la documentation, mais je n'ai rien trouvé concernant l'horodatage de la validation de transaction. Pourriez-vous gentiment suggérer smth?
Btw, je suis conscient de décodage logique et je sais que ce mécanisme convient mieux à mes besoins en théorie, mais il y a certains problèmes pratiques qui ne me permettent pas de l'utiliser.
Ce problème pourrait être facilement résolu en affectant à l'étape 2 un horodatage lorsque la mise à jour devient visible pour d'autres transactions (horodatage de validation de transaction en d'autres termes) au lieu de CURRENT_TIMESTAMP ou clock_timestamp ().
C'est logiquement impossible. Postgres écrit de nouvelles versions de lignes avant il s'engage enfin à les rendre visibles. Il faudrait des capacités prophétiques pour écrire un horodatage futur encore inconnu au moment de la rédaction.
Cependant , vous pouvez obtenir des horodatages de validation à partir d'une source différente: depuis Postgres 9.5, il existe un paramètre GUC - track_commit_timestamp
pour démarrer la journalisation des horodatages de validation à l'échelle mondiale.
Ensuite, vous pouvez obtenir des horodatages de validation avec la fonction utilitaire pg_xact_commit_timestamp(xid)
. Votre requête pourrait ressembler à:
SELECT * FROM my_table t
WHERE pg_xact_commit_timestamp(t.xmin) > _some_persisted_timestamp;
Vos étape 2 et étape 3 positions commerciales, et vous enregistrez l'horodatage de validation au lieu de CURRENT_TIMESTAMP
- ou xmin
à partir de toute ligne fraîchement mise à jour pour dériver l'horodatage de validation avec pg_xact_commit_timestamp()
une fois de plus.
Plus:
À propos de xmin
:
Mais je ne suis pas sûr de bien comprendre votre tâche. Vous avez peut-être besoin d'un outil de mise en file d'attente ou de traiter les lignes une par une, comme indiqué ici: