sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan finder jeg sidste gang en PostgreSQL-database er blevet opdateret?

Du kan skrive en trigger at køre hver gang der laves en indsættelse/opdatering på en bestemt tabel. Den almindelige brug er at indstille en "created" eller "last_updated" kolonne i rækken til det aktuelle klokkeslæt, men du kan også opdatere tiden på en central placering, hvis du ikke vil ændre de eksisterende tabeller.

Så for eksempel en typisk måde er følgende:

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();

For derefter at finde det sidste opdateringstidspunkt skal du vælge "MAX(last_updated)" fra hver tabel, du sporer, og tage den største af dem, f.eks.:

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

For tabeller med en seriel (eller tilsvarende genereret) primærnøgle kan du prøve at undgå den sekventielle scanning for at finde det seneste opdateringstidspunkt ved at bruge primærnøgleindekset, eller du opretter indekser på last_updated.

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

Bemærk, at dette kan give lidt forkerte resultater i tilfælde af, at ID'er ikke er helt sekventielle, men hvor meget nøjagtighed har du brug for? (Husk, at transaktioner betyder, at rækker kan blive synlige for dig i en anden rækkefølge, end de oprettes.)

En alternativ tilgang til at undgå at tilføje 'opdaterede' kolonner til hver tabel er at have en central tabel til at gemme opdateringstidsstempler i. For eksempel:

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();

Dette vil give dig en tabel med en række for hver tabelopdatering:du kan så bare gøre:

SELECT MAX(updated) FROM update_log

For at få den sidste opdateringstid. (Du kunne opdele dette efter tabel, hvis du ville). Denne tabel vil selvfølgelig bare blive ved med at vokse:enten opret et indeks på 'opdateret' (hvilket burde gøre at få den seneste ret hurtig) eller afkort den med jævne mellemrum, hvis det passer med din brugssag, (f.eks. tag en eksklusiv lås på bordet, få det seneste opdateringstidspunkt, og afkort det, hvis du med jævne mellemrum skal kontrollere, om der er foretaget ændringer).

En alternativ tilgang - hvilket kan være hvad folk på forummet mente - er at indstille 'log_statement =mod' i databasekonfigurationen (enten globalt for klyngen eller på databasen eller brugeren, du skal spore) og derefter alle sætninger, der ændre databasen vil blive skrevet til serverloggen. Du bliver derefter nødt til at skrive noget uden for databasen for at scanne serverloggen, filtrere tabeller fra, du ikke er interesseret i osv.



  1. Oracle:Hvordan opdager man klientprocesterminering, som den virker for sqlplus?

  2. MySQL prædikat pushing

  3. Hvordan opdeles en streng i PL/SQL?

  4. Administrer MySQL med phpMyAdmin på Ubuntu 9.10 (Karmic)