PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie finde ich heraus, wann eine PostgreSQL-Datenbank zuletzt aktualisiert wurde?

Sie können einen Trigger schreiben jedes Mal auszuführen, wenn eine Einfügung/Aktualisierung in einer bestimmten Tabelle vorgenommen wird. Die übliche Verwendung besteht darin, eine „erstellt“- oder „letzte_aktualisiert“-Spalte der Zeile auf die aktuelle Zeit zu setzen, aber Sie können die Zeit auch an einer zentralen Stelle aktualisieren, wenn Sie die vorhandenen Tabellen nicht ändern möchten.

Ein typischer Weg ist zum Beispiel der folgende:

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

Um dann die letzte Aktualisierungszeit zu finden, müssen Sie "MAX(last_updated)" aus jeder Tabelle auswählen, die Sie verfolgen, und die größte davon nehmen, z. B.:

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

Bei Tabellen mit einem seriellen (oder ähnlich generierten) Primärschlüssel können Sie versuchen, den sequenziellen Scan zu vermeiden, um die letzte Aktualisierungszeit zu finden, indem Sie den Primärschlüsselindex verwenden, oder Sie erstellen Indizes auf last_updated.

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

Beachten Sie, dass dies zu leicht falschen Ergebnissen führen kann, wenn IDs nicht ganz sequenziell sind, aber wie viel Genauigkeit benötigen Sie? (Beachten Sie, dass Transaktionen bedeuten, dass Zeilen in einer anderen Reihenfolge für Sie sichtbar werden können, als sie erstellt wurden.)

Ein alternativer Ansatz, um das Hinzufügen von „aktualisierten“ Spalten zu jeder Tabelle zu vermeiden, besteht darin, eine zentrale Tabelle zum Speichern von Aktualisierungszeitstempeln zu haben. Zum Beispiel:

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

Dadurch erhalten Sie eine Tabelle mit einer Zeile für jede Tabellenaktualisierung:Sie können dann einfach Folgendes tun:

SELECT MAX(updated) FROM update_log

Um die letzte Aktualisierungszeit zu erhalten. (Sie könnten dies nach Tabelle aufteilen, wenn Sie möchten). Diese Tabelle wird natürlich immer weiter wachsen:Erstellen Sie entweder einen Index auf „aktualisiert“ (was das Abrufen des neuesten ziemlich schnell machen sollte) oder kürzen Sie ihn regelmäßig, wenn dies zu Ihrem Anwendungsfall passt (z. Holen Sie sich die neueste Aktualisierungszeit und kürzen Sie sie dann, wenn Sie regelmäßig überprüfen müssen, ob Änderungen vorgenommen wurden).

Ein alternativer Ansatz – was vielleicht das ist, was die Leute im Forum gemeint haben – besteht darin, „log_statement =mod“ in der Datenbankkonfiguration festzulegen (entweder global für den Cluster oder für die Datenbank oder den Benutzer, den Sie verfolgen müssen) und dann alle Anweisungen, die Änderungen an der Datenbank werden in das Serverprotokoll geschrieben. Sie müssen dann etwas außerhalb der Datenbank schreiben, um das Serverprotokoll zu scannen, Tabellen herauszufiltern, an denen Sie nicht interessiert sind, usw.