2009-05-22 23 views
17

Pracuję z bazą danych PostgreSQL, która jest aktualizowana partiami. Muszę wiedzieć, kiedy ostatni raz baza danych (lub tabela w bazie danych) została zaktualizowana lub zmodyfikowana, zrobi to.Jak mogę znaleźć ostatnią aktualizację bazy danych PostgreSQL?

Zobaczyłem, że ktoś na forum postsSQL zasugerował, że do korzystania z dzienników i kwerendy dzienników na czas. Nie zadziała to dla mnie, ponieważ nie mam kontroli nad bazą kodów klientów.

Odpowiedz

22

Można napisać trigger uruchomić za każdym razem, gdy insert/update jest wykonany na konkretna tabela. Typowym zastosowaniem jest ustawienie kolumny "utworzony" lub "ostatni_aktualny" wiersza do bieżącego czasu, ale można również zaktualizować czas w lokalizacji centralnej, jeśli nie chcesz zmieniać istniejących tabel.

Tak na przykład typowy sposób jest następujący:

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

Następnie znaleźć ostatni czas aktualizacji, należy wybrać opcję „MAX (LAST_UPDATED)” z każdej tabeli jesteś śledzenia i podjąć największe z nich, np:

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 

na stołach z szeregowym (lub podobnie wygenerowanym) klucza podstawowego, można spróbować uniknąć sekwencyjne skanowanie, aby znaleźć najnowsze czas aktualizacji za pomocą indeksu klucza podstawowego lub utworzyć indeksy na last_updated.

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

Należy pamiętać, że może to dać nieco błędne wyniki w przypadku identyfikatorów nie jest całkiem sekwencyjne, ale ile dokładność jest potrzebna? (Pamiętaj, że transakcje oznaczają, że wiersze mogą być widoczne dla Ciebie w innej kolejności niż ich tworzenie).

Alternatywnym sposobem uniknięcia dodawania "zaktualizowanych" kolumn do każdej tabeli jest posiadanie centralnej tabeli do przechowywania aktualizacji znaczniki czasu w. na przykład:

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

To daje stół z rzędem dla każdej aktualizacji tabeli: można następnie po prostu zrobić:

SELECT MAX(updated) FROM update_log 

Aby uzyskać ostatni czas aktualizacji. (Możesz to podzielić według tabeli, jeśli chcesz). Ta tabela będzie oczywiście nadal rosła: albo utwórz indeks "zaktualizowany" (który powinien sprawić, że otrzymasz najnowszy dość szybko), albo skróć go okresowo, jeśli pasuje on do twojego przypadku użycia (np. Weź wyjątkowy zamek na stole, pobierz najnowszy czas aktualizacji, a następnie skróć go, jeśli chcesz okresowo sprawdzać, czy zmiany zostały wprowadzone).

Alternatywne podejście - które może być tym, co ludzie na forum - oznacza ustawienie "log_statement = mod" w konfiguracji bazy danych (globalnie dla klastra lub bazy danych lub użytkownika, który należy śledzić) i następnie wszystkie instrukcje modyfikujące bazę danych zostaną zapisane w dzienniku serwera. Następnie musisz napisać coś poza bazą danych, aby przeskanować dziennik serwera, odfiltrować tabele, które Cię nie interesują itp.

4

Wygląda na to, można użyć pg_stat_database aby uzyskać liczbę transakcji i sprawdzić, czy to zmienia się z biegu jeden zapasowej do następnego - patrz this dba.se answer i komentarze więcej szczegółów

0

Można napisać procedurę przechowywaną w „niezaufane language "(np. plpythonu): Umożliwia dostęp do plików w katalogu" base "PostgreSQL. Zwróć największą liczbę tych plików w procedurze przechowywanej.

Ale to tylko mgliste, ponieważ próżnia zmieni te pliki i mtime.

3

Podoba mi się podejście Jacka. można wyszukać statystyki tabeli i znać liczbę wkładek, aktualizacje, usuwa i tak:

select n_tup_upd from pg_stat_user_tables where relname = 'YOUR_TABLE'; 

każda zmiana zwiększy liczbę przez 1.

nagie pamiętać, metoda ta jest opłacalne, gdy masz pojedynczy DB. wiele instancji prawdopodobnie będzie wymagało innego podejścia.

Powiązane problemy