sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo encuentro la última vez que se actualizó una base de datos PostgreSQL?

Puede escribir un disparador para ejecutarse cada vez que se realiza una inserción/actualización en una tabla en particular. El uso común es establecer una columna "creada" o "última actualización" de la fila a la hora actual, pero también puede actualizar la hora en una ubicación central si no desea cambiar las tablas existentes.

Entonces, por ejemplo, una forma típica es la siguiente:

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

Luego, para encontrar la hora de la última actualización, debe seleccionar "MAX (last_updated)" de cada tabla que está rastreando y tomar la mayor de ellas, por ejemplo:

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 las tablas con una clave principal en serie (o generada de manera similar), puede intentar evitar el escaneo secuencial para encontrar la hora de actualización más reciente usando el índice de clave principal, o puede crear índices en last_updated.

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

Tenga en cuenta que esto puede dar resultados ligeramente erróneos en el caso de que las identificaciones no sean bastante secuenciales, pero ¿cuánta precisión necesita? (Tenga en cuenta que las transacciones significan que las filas pueden volverse visibles para usted en un orden diferente al de su creación).

Un enfoque alternativo para evitar agregar columnas 'actualizadas' a cada tabla es tener una tabla central para almacenar las marcas de tiempo de actualización. Por ejemplo:

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

Esto le dará una tabla con una fila para cada actualización de la tabla:luego puede hacer:

SELECT MAX(updated) FROM update_log

Para obtener la hora de la última actualización. (Puedes dividir esto por mesa si quieres). Por supuesto, esta tabla seguirá creciendo:cree un índice en 'actualizado' (lo que debería hacer que obtener el último sea bastante rápido) o trunque periódicamente si eso se ajusta a su caso de uso (por ejemplo, tome un bloqueo exclusivo en la tabla, obtener la hora de actualización más reciente y luego truncarla si necesita verificar periódicamente si se han realizado cambios).

Un enfoque alternativo, que podría ser lo que la gente del foro quiso decir, es establecer 'log_statement =mod' en la configuración de la base de datos (ya sea globalmente para el clúster, o en la base de datos o el usuario que necesita rastrear) y luego todas las declaraciones que modificar la base de datos se escribirá en el registro del servidor. Luego deberá escribir algo fuera de la base de datos para escanear el registro del servidor, filtrar las tablas que no le interesan, etc.