Laut den Dokumenten:
KONZURRENT Aktualisieren Sie die materialisierte Ansicht, ohne gleichzeitige Auswahlen in der materialisierten Ansicht zu sperren. (...)
... ANDERE INHALTE ...
Selbst mit dieser Option kann jeweils nur ein REFRESH gegen eine materialisierte Ansicht ausgeführt werden .
Ich hatte eine Funktion, die die letzte Aktualisierungszeit für eine MATERIALISIERTE ANSICHT überprüfte, und wenn mehr als 60 Sekunden vergangen waren, würde sie aktualisiert.
Was würde jedoch passieren, wenn ich versuche, eine materialisierte Ansicht aus zwei getrennten Prozessen gleichzeitig zu aktualisieren? Würden sie sich anstellen oder einen Fehler auslösen?
Gibt es eine Möglichkeit zu erkennen, wann eine MATERIALISIERTE ANSICHT aktualisiert wird, und daher zu vermeiden, sie zu berühren?
Derzeit habe ich versucht, einen Tabellendatensatz zu füllen, bevor ich ihn aktualisiere ( refreshing
auf true
) und dann auf, false
wenn der Prozess abgeschlossen ist.
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;
Wenn ich diese Prozedur aufrufe, überprüfe ich dann die aktuellste last_update
und ihren refreshing
Wert. Wenn dies refreshing
zutrifft, versuchen Sie nicht, die materialisierte Ansicht zu aktualisieren.
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;
Ich bin mir jedoch nicht sicher, ob das Aktualisierungsflag synchron aktualisiert wird (ich meine, es wartet wirklich darauf, dass die Aktualisierung tatsächlich abgeschlossen ist).
Ist dieser Ansatz rational oder fehlt mir hier etwas?