PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment puis-je trouver la dernière fois qu'une base de données PostgreSQL a été mise à jour ?

Vous pouvez écrire un déclencheur s'exécute à chaque fois qu'une insertion/mise à jour est effectuée sur une table particulière. L'utilisation courante consiste à définir une colonne "created" ou "last_updated" de la ligne sur l'heure actuelle, mais vous pouvez également mettre à jour l'heure dans un emplacement central si vous ne souhaitez pas modifier les tables existantes.

Ainsi, par exemple, une méthode typique est la suivante :

CREATE FUNCTION stamp_updated() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$
BEGIN
  NEW.last_updated := now();
  RETURN NEW;
END
$$;
-- repeat for each table you need to track:
ALTER TABLE sometable ADD COLUMN last_updated TIMESTAMP;
CREATE TRIGGER sometable_stamp_updated
  BEFORE INSERT OR UPDATE ON sometable
  FOR EACH ROW EXECUTE PROCEDURE stamp_updated();

Ensuite, pour trouver l'heure de la dernière mise à jour, vous devez sélectionner "MAX(last_updated)" dans chaque table que vous suivez et prendre la plus grande d'entre elles, par exemple :

SELECT MAX(max_last_updated) FROM (
  SELECT MAX(last_updated) AS max_last_updated FROM sometable
  UNION ALL
  SELECT MAX(last_updated) FROM someothertable
) updates

Pour les tables avec une clé primaire en série (ou générée de manière similaire), vous pouvez essayer d'éviter l'analyse séquentielle pour trouver la dernière heure de mise à jour en utilisant l'index de clé primaire, ou vous créez des index sur last_updated.

-- get timestamp of row with highest id
SELECT last_updated FROM sometable ORDER BY sometable_id DESC LIMIT 1

Notez que cela peut donner des résultats légèrement erronés dans le cas où les identifiants ne sont pas tout à fait séquentiels, mais de quelle précision avez-vous besoin ? (Gardez à l'esprit que les transactions signifient que les lignes peuvent devenir visibles pour vous dans un ordre différent de leur création.)

Une autre approche pour éviter d'ajouter des colonnes "mises à jour" à chaque table consiste à disposer d'une table centrale dans laquelle stocker les horodatages de mise à jour. Par exemple :

CREATE TABLE update_log(table_name text PRIMARY KEY, updated timestamp NOT NULL DEFAULT now());
CREATE FUNCTION stamp_update_log() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$
BEGIN
  INSERT INTO update_log(table_name) VALUES(TG_TABLE_NAME);
  RETURN NEW;
END
$$;
-- Repeat for each table you need to track:
CREATE TRIGGER sometable_stamp_update_log
 AFTER INSERT OR UPDATE ON sometable
 FOR EACH STATEMENT EXECUTE stamp_update_log();

Cela vous donnera un tableau avec une ligne pour chaque mise à jour du tableau :vous pouvez alors simplement faire :

SELECT MAX(updated) FROM update_log

Pour obtenir l'heure de la dernière mise à jour. (Vous pouvez diviser cela par table si vous le souhaitez). Cette table va bien sûr continuer à s'agrandir :soit créer un index sur "mise à jour" (ce qui devrait accélérer l'obtention de la dernière) soit la tronquer périodiquement si cela correspond à votre cas d'utilisation (par exemple, prendre un verrou exclusif sur la table, obtenez la dernière heure de mise à jour, puis tronquez-la si vous devez vérifier périodiquement si des modifications ont été apportées).

Une approche alternative - qui pourrait être ce que les gens du forum voulaient dire - consiste à définir 'log_statement =mod' dans la configuration de la base de données (soit globalement pour le cluster, soit sur la base de données ou l'utilisateur que vous devez suivre), puis toutes les déclarations qui modifier la base de données sera écrit dans le journal du serveur. Vous devrez ensuite écrire quelque chose en dehors de la base de données pour analyser le journal du serveur, filtrer les tables qui ne vous intéressent pas, etc.