PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como encontro a última vez que um banco de dados PostgreSQL foi atualizado?


Você pode escrever um trigger para ser executado toda vez que uma inserção/atualização é feita em uma tabela específica. O uso comum é definir uma coluna "created" ou "last_updated" da linha para a hora atual, mas você também pode atualizar a hora em um local central se não quiser alterar as tabelas existentes.

Então, por exemplo, uma maneira típica é a seguinte:
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();

Então, para encontrar a hora da última atualização, você precisa selecionar "MAX(last_updated)" de cada tabela que você está rastreando e pegar a maior delas, por exemplo:
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

Para tabelas com uma chave primária serial (ou gerada de forma semelhante), você pode tentar evitar a varredura sequencial para encontrar a hora de atualização mais recente usando o índice de chave primária ou criar índices em last_updated.
-- get timestamp of row with highest id
SELECT last_updated FROM sometable ORDER BY sometable_id DESC LIMIT 1

Observe que isso pode fornecer resultados um pouco errados no caso de IDs não serem muito sequenciais, mas quanta precisão você precisa? (Lembre-se de que as transações significam que as linhas podem se tornar visíveis para você em uma ordem diferente daquela em que foram criadas.)

Uma abordagem alternativa para evitar a adição de colunas 'atualizadas' a cada tabela é ter uma tabela central para armazenar registros de data e hora de atualização. Por exemplo:
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();

Isso lhe dará uma tabela com uma linha para cada atualização de tabela:você pode fazer:
SELECT MAX(updated) FROM update_log

Para obter a hora da última atualização. (Você pode dividir isso por tabela, se quiser). Esta tabela, é claro, continuará crescendo:crie um índice em 'atualizado' (o que deve tornar a obtenção do mais recente muito rápido) ou trunque-o periodicamente se isso se encaixar no seu caso de uso (por exemplo, use um bloqueio exclusivo na tabela, obter a hora de atualização mais recente e truncá-la se precisar verificar periodicamente se as alterações foram feitas).

Uma abordagem alternativa - que pode ser o que o pessoal do fórum quis dizer - é definir 'log_statement =mod' na configuração do banco de dados (globalmente para o cluster ou no banco de dados ou usuário que você precisa rastrear) e, em seguida, todas as instruções que modificar o banco de dados será gravado no log do servidor. Você precisará escrever algo fora do banco de dados para verificar o log do servidor, filtrando as tabelas nas quais não está interessado, etc.