Selon les documents:
CONCURRENTLY Actualisez la vue matérialisée sans verrouiller les sélections simultanées sur la vue matérialisée. (...)
... AUTRES CONTENUS ...
Même avec cette option, un seul REFRESH à la fois peut s'exécuter sur une seule vue matérialisée .
J'eu une fonction qui a vérifié la dernière fois de rafraîchissement pour une vue et, si MATERIALIZED plus de 60 secondes se sont écoulées, il le rafraîchir.
Cependant, que se passerait-il si j'essayais d'actualiser une vue matérialisée à partir de deux processus distincts en même temps? feraient-ils la queue ou soulèveraient-ils une erreur?
Existe-t-il un moyen de détecter quand une VUE MATÉRIALISÉE est en cours de rafraîchissement et donc d'éviter de la toucher?
Actuellement, j'ai recouru à remplir un enregistrement de table avant d'actualiser (en définissant refreshing
sur true
) puis de le définir à la false
fin du processus.
EXECUTE 'INSERT INTO refresh_status (last_update, refreshing)
VALUES (clock_timestamp(), true) RETURNING id') INTO refresh_id;
EXECUTE 'REFRESH MATERIALIZED VIEW CONCURRENTLY my_mat_view';
EXECUTE 'UPDATE refresh_status SET refreshing=false WHERE id=$1' USING refresh_id;
Ensuite, chaque fois que j'appelle cette procédure, je vérifie la plus récente last_update
et sa refreshing
valeur. Si refreshing
c'est vrai, n'essayez pas de rafraîchir la vue matérialisée.
EXECUTE 'SELECT
extract(epoch FROM now() - (last_update))::integer,
refreshing
FROM refresh_status
ORDER BY last_update DESC
LIMIT 1' INTO update_seconds_ago, refreshing;
IF(updated_seconds_ago > 60 AND refreshing = FALSE) THEN
-- the refresh block above
END IF;
Cependant, je ne suis pas sûr que l'indicateur d'actualisation soit mis à jour de manière synchrone (je veux dire, il attend vraiment que le rafraîchissement soit réellement terminé)
Cette approche est-elle rationnelle ou manque-t-il quelque chose ici?
la source
pg_locks
et commencez votre rafraîchissement. Un moyen approprié pour résoudre les conflits de verrouillage consiste à définir le délai d'expiration et à gérer l'erreur.Comme l'a noté mustaccio , cette question chevauche considérablement les verrous de vue matérialisée Postgres Refresh .
Cependant, alors que la réponse acceptée à cette question a un lien qui répond à celle-ci, la réponse à cette question n'est pas directement incluse dans celle-ci.
Donc, pour être précis: selon la page de manuel de PostgreSQL sur le verrouillage explicite (le lien est vers la page de la version actuelle, pour PostGres 10),
REFRESH MATERIALIZED VIEW CONCURRENTLY
prend unEXCLUSIVE
verrou. LeEXCLUSIVE
verrou semble bloquer tous les autres verrous saufACCESS SHARE
- cela inclut les autresEXCLUSIVE
verrous.Une seconde
REFRESH MATERIALIZED VIEW CONCURRENTLY
requête sur la même vue attendra donc que le verrou obtenu par la première soit libéré.la source
Grâce aux réponses de mustaccio et RDFozz , j'ai finalement compris que la
REFRESH ... CONCURRENTLY
prise d'un verrou exclusif est la raison pour laquelle la documentation PostgreSQL dit :J'avais peur que cela signifie que toute tentative de rafraîchissement simultané entraînerait une erreur , mais à la lumière de leurs réponses, aucune erreur particulière n'est impliquée. C'est juste une question de verrous qui mettront en file d'attente les tentatives simultanées. Ainsi, la documentation pourrait plutôt être interprétée comme:
la source