Вы можете написать триггер для запуска каждый раз, когда выполняется вставка / обновление в определенной таблице. Обычно используется для установки столбца «create» или «last_updated» строки на текущее время, но вы также можете обновить время в центральном местоположении, если вы не хотите изменять существующие таблицы.
Так, например, типичный способ следующий:
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();
Затем, чтобы найти время последнего обновления, вам нужно выбрать «MAX (last_updated)» из каждой таблицы, которую вы отслеживаете, и взять самую большую из них, например ::10000
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
Для таблиц с последовательным (или сгенерированным аналогичным образом) первичным ключом вы можете попытаться избежать последовательного сканирования, чтобы найти последнее время обновления, используя индекс первичного ключа, или создать индексы для last_updated.
-- get timestamp of row with highest id
SELECT last_updated FROM sometable ORDER BY sometable_id DESC LIMIT 1
Обратите внимание, что это может дать немного неправильные результаты в случае, если идентификаторы не являются достаточно последовательными, но какая точность вам нужна? (Помните, что транзакции означают, что строки могут становиться видимыми для вас в порядке, отличном от создаваемого ими.)
Альтернативный подход, позволяющий избежать добавления «обновленных» столбцов в каждую таблицу, состоит в том, чтобы иметь центральную таблицу для хранения временных меток обновления. Например:
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();
Это даст вам таблицу со строкой для каждого обновления таблицы: тогда вы можете просто сделать:
SELECT MAX(updated) FROM update_log
Чтобы получить время последнего обновления. (Вы можете разделить это по таблице, если хотите). Эта таблица, конечно, будет продолжать расти: либо создайте индекс для «обновленного» (что должно сделать получение последнего достаточно быстрым), либо периодически усекайте его, если это соответствует вашему варианту использования (например, установите эксклюзивную блокировку таблицы, получите последнее время обновления, а затем обрежьте его, если вам нужно периодически проверять, были ли внесены изменения).
Альтернативный подход - который может означать то, что имели в виду люди на форуме - это установить 'log_statement = mod' в конфигурации базы данных (либо для кластера глобально, либо для базы данных или пользователя, которого нужно отслеживать), а затем все операторы, которые изменяют базу данных, будут записаны в журнал сервера. Затем вам нужно будет написать что-то вне базы данных, чтобы просканировать журнал сервера, отфильтровать таблицы, которые вам не интересны, и т. Д.