sql >> Databáze >  >> RDS >> PostgreSQL

Jak zjistím, kdy byla naposledy aktualizována databáze PostgreSQL?

Můžete napsat spouštěč spustit pokaždé, když je v konkrétní tabulce provedena vložení/aktualizace. Běžným zvykem je nastavit sloupec „vytvořeno“ nebo „posledně aktualizováno“ na aktuální čas, ale můžete také aktualizovat čas v centrálním umístění, pokud nechcete měnit stávající tabulky.

Typický způsob je například následující:

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

Poté, abyste zjistili čas poslední aktualizace, musíte vybrat „MAX(last_updated)“ z každé tabulky, kterou sledujete, a vybrat největší z nich, např.:

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

U tabulek se sériovým (nebo podobně vygenerovaným) primárním klíčem se můžete pokusit vyhnout se sekvenčnímu prohledávání, abyste zjistili nejnovější čas aktualizace pomocí indexu primárního klíče, nebo můžete vytvořit indexy na last_updated.

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

Všimněte si, že to může poskytnout mírně nesprávné výsledky v případě, že ID nejsou zcela sekvenční, ale jak velkou přesnost potřebujete? (Mějte na paměti, že transakce znamenají, že se vám řádky mohou zobrazit v jiném pořadí, než v jakém byly vytvářeny.)

Alternativním přístupem, jak se vyhnout přidávání „aktualizovaných“ sloupců do každé tabulky, je mít centrální tabulku pro ukládání časových razítek aktualizace. Například:

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

Tím získáte tabulku s řádkem pro každou aktualizaci tabulky:pak můžete udělat:

SELECT MAX(updated) FROM update_log

Chcete-li získat čas poslední aktualizace. (Můžete to rozdělit podle tabulky, pokud chcete). Tato tabulka se samozřejmě bude neustále rozrůstat:buď vytvořte index na 'updated' (což by mělo urychlit získávání nejnovějšího), nebo jej pravidelně zkracujte, pokud to vyhovuje vašemu případu použití (např. vezměte na stůl exkluzivní zámek, získat nejnovější čas aktualizace a poté jej zkrátit, pokud potřebujete pravidelně kontrolovat, zda byly provedeny změny).

Alternativním přístupem – který by mohl být tím, co měli lidé na fóru na mysli – je nastavit 'log_statement =mod' v konfiguraci databáze (buď globálně pro cluster, nebo na databázi nebo uživateli, kterého potřebujete sledovat) a poté všechny příkazy, které upravit databázi se zapíše do protokolu serveru. Pak budete muset napsat něco mimo databázi, abyste mohli skenovat protokol serveru, odfiltrovat tabulky, které vás nezajímají, atd.



  1. Chyba:nehašovatelný typ:'diktát'

  2. Tipy pro ukládání záloh PostgreSQL na Google Cloud (GCP)

  3. SqlAlchemy:Dotazování na pole délky json s polem

  4. Je použití hlavní tabulky pro sdílené sloupce dobrým postupem pro celou databázi?