Domanda

Sto lavorando con un database PostgreSQL che viene aggiornato in lotti. Ho bisogno di sapere quando l'ultima volta che il database (o una tabella nel database) sono stati aggiornati o modificati, sia lo farà.

Ho visto che qualcuno sul forum postgeSQL aveva suggerito che per utilizzare la registrazione e interrogare i vostri ceppi per il tempo. Questo non funziona per me come che non ho il controllo sui clienti codebase.

È stato utile?

Soluzione

È possibile scrivere una innescare per eseguire ogni volta un inserto / aggiornamento viene effettuato su una particolare tabella. L'uso comune è quello di impostare una o colonna "creato" "LAST_UPDATED" della riga per l'ora corrente, ma si potrebbe anche aggiornare l'ora in una posizione centrale se non si desidera modificare le tabelle esistenti.

Così, per esempio, un modo tipico è il seguente:

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

Poi, per trovare l'ultimo tempo di aggiornamento, è necessario selezionare "MAX (LAST_UPDATED)" da ogni tabella si sta seguendo e prendere il più grande di questi, per esempio:.

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

Per le tabelle con una chiave primaria di serie (o simile generati), si può provare a evitare la scansione sequenziale per trovare le ultime tempo di aggiornamento utilizzando l'indice chiave primaria, oppure creare indici su LAST_UPDATED.

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

Si noti che questo può dare risultati leggermente sbagliato nel caso di ID non essere abbastanza sequenziale, ma quanto la precisione cosa hai bisogno? (Tenete a mente che le operazioni fanno sì che le righe possono diventare visibile a voi in un ordine diverso da loro creati.)

Un approccio alternativo per evitare di aggiungere colonne 'aggiornata' ad ogni tavolo è di avere un tavolo centrale per aggiornare timestamp negozio a. Ad esempio:

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

Questo vi darà una tabella con una riga per ogni aggiornamento della tabella: si può quindi solo fare:

SELECT MAX(updated) FROM update_log

Per ottenere l'ultima volta aggiornamento. (Si potrebbe dividere questo da tavolo se si voleva). Questo tavolo sarà naturalmente solo continuare a crescere: o creare un indice su 'aggiornato' (che dovrebbe fare ottenere la più recente piuttosto veloce) o troncare periodicamente se che si adatta con il vostro caso d'uso, (ad esempio, prendere un blocco esclusivo sul tavolo, ottenere l'ultimo tempo di aggiornamento, quindi tronca, se avete bisogno di controllare periodicamente se sono state apportate modifiche).

Un avvicinamento-alternativa, che potrebbe essere quello che la gente sul meant- Forum è quello di impostare 'log_statement = mod' nella configurazione del database (sia a livello globale per il cluster, o sulla base di dati o l'utente è necessario tenere traccia) e poi tutte le dichiarazioni che modificano il database verranno scritti nel registro del server. Avrete quindi bisogno di scrivere qualcosa al di fuori del database per eseguire la scansione del registro del server, filtrare le tabelle che non interessa, etc.

Altri suggerimenti

Sembra che è possibile utilizzare pg_stat_database per ottenere un conteggio delle transazioni e verificare se questo cambia da un'esecuzione di backup per il prossimo - vedi questo dba.se risposta e commenti per maggiori dettagli

Mi piace l'approccio di Jack. È possibile interrogare le statistiche di tabella e conoscere il numero di inserimenti, aggiornamenti, eliminazioni e così:

select n_tup_upd from pg_stat_user_tables  where relname = 'YOUR_TABLE';

ogni aggiornamento sarà aumentare il numero di 1.

nudo in mente questo metodo è praticabile quando si dispone di un singolo DB. più istanze richiederanno probabilmente approccio diverso.

Vedere il seguente articolo:

MySQL vs PostgreSQL: aggiunta di una colonna 'Last Time Modified' a una tabella http://www.pointbeing.net/weblog/2008/03/mysql-versus-postgresql-adding-a-last-modified-column-to-a-table.html

È possibile scrivere una stored procedure in un "linguaggio non attendibile" (ad esempio plpythonu): Questo permette di accedere ai file nella directory di postgres "base". Riportare la mtime piu 'grande di questi file nella stored procedure.

Ma questo è vaga solo, dal momento che il vuoto cambierà questi file e il mtime.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top