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 ne seule RAFRAÎCHISSEMENT à la fois peut fonctionner contre n'importe laquellene vue matérialisée.
I had une fonction qui vérifiait le dernier temps de rafraîchissement pour une VUE MATÉRIALISÉE et, si plus de 60 secondes s'étaient écoulées, elle le rafraîchirait.
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 en le définissant sur false
une fois le processus terminé.
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 valeur refreshing
. Si refreshing
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?
Comme mentionné dans cette réponse , "REFRESH MATERIALIZED VIEW CONCURRENTLY
prend un EXCLUSIVE
lock "sur la table. En suivant le chemin des miettes vers documentation nous pouvons lire qu'un EXCLUSIVE
lock sur une table" autorise uniquement les ACCESS SHARE
les verrous, c'est-à-dire que seules les lectures de la table peuvent continuer ". Dans le même paragraphe, nous pouvons voir que" EXCLUSIVE
entre en conflit avec ... EXCLUSIVE
", ce qui signifie qu'un autre REFRESH MATERIALIZED VIEW CONCURRENTLY
, qui demande le même verrou EXCLUSIVE
, devra attendre que le verrou EXCLUSIVE
précédent soit libéré.
Si vous voulez éviter d'attendre ce verrou pendant une période indéfinie, vous pouvez définir la variable de session lock_timeout
à une valeur sensible.
Comme indiqué par mustaccio , cette question chevauche de manière significative --- Postgres Refresh Materialized View Locks .
Cependant, alors que 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 un verrou EXCLUSIVE
. Le verrou EXCLUSIVE
semble bloquer tous les autres verrous sauf ACCESS SHARE
- qui inclut d'autres verrous EXCLUSIVE
.
Donc une seconde REFRESH MATERIALIZED VIEW CONCURRENTLY
la requête sur la même vue attendra que le verrou obtenu par le premier soit libéré.
Grâce aux réponses de mustaccio et RDFozz , j'ai finalement compris que REFRESH ... CONCURRENTLY
la prise d'un verrou exclusif est la raison pour laquelle la documentation PostgreSQL indique :
Même avec cette option , une seule RAFRAÎCHISSEMENT à la fois peut s'exécuter contre n'importe quelle vue matérialisée .
J'avais peur que cela signifie que toute tentative de rafraîchissement simultané déclencherait une erreur , mais à la lumière de leurs réponses, il n'y a pas de erreur 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:
Le verrouillage acquis au cours de cette opération empêchera toute opération autre que la lecture de la VUE MATÉRIALISÉE. D'autres tentatives d'actualisation de la vue matérialisée pendant l'exécution de REFRESH ... CONCURRENTLY feront la queue jusqu'à ce que le premier verrou soit libéré.