2009-05-22 19 views
17

Estoy trabajando con una base de datos postgreSQL que se actualiza en lotes. Necesito saber cuándo será la última vez que se haya actualizado o modificado la base de datos (o una tabla en la base de datos).¿Cómo encuentro la última vez que se actualizó una base de datos PostgreSQL?

Vi que alguien en el foro postgeSQL había sugerido que utilizara el registro y consultara sus registros por el momento. Esto no funcionará para mí ya que no tengo control sobre la base de código de los clientes.

Respuesta

22

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

Así, 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(); 

y para buscar el último tiempo de actualización, es necesario seleccionar "MAX (LAST_UPDATED)" de cada tabla está realizando el seguimiento y tomar la mayor de los que, 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 similarmente generados), puede intentar evitar la secuencia de exploración para encontrar la última hora de actualización mediante el índice de clave principal, o 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 poco mal en el caso de las identificaciones no ser bastante secuencial, pero la cantidad de exactitud se puede pedir? (Tenga en cuenta que las transacciones significan que las filas pueden ser visibles para usted en un orden diferente al creado).

Un enfoque alternativo para evitar agregar columnas 'actualizadas' a cada tabla es tener una tabla central para almacenar la actualización marcas de tiempo en, 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: a continuación, puede simplemente hacer:

SELECT MAX(updated) FROM update_log 

para conseguir la última hora de actualización. (Podrías dividir esto por mesa si quisieras). Esta tabla, por supuesto, seguirá creciendo: cree un índice de "actualizado" (que debería hacer que el último sea bastante rápido) o trunque periódicamente si eso concuerda con su caso de uso (por ejemplo, tome un candado exclusivo en la mesa, obtenga la última hora de actualización, luego trunque si necesita verificar periódicamente si se han realizado cambios).

Un enfoque alternativo, que podría ser lo que significaban las personas en el foro, 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 usuario que necesita rastrear) y a continuación, todas las declaraciones que modifican la base de datos se escribirán 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.

4

Parece que se puede utilizar pg_stat_database para obtener un recuento de transacciones y comprobar si esto cambia de carrera de una copia de seguridad a la siguiente - ver this dba.se answer y comentarios para más detalles

0

puede escribir un procedimiento almacenado en una "no es de confianza idioma "(por ejemplo, plpythonu): Esto permite el acceso a los archivos en el directorio" base "de postgres. Devuelve el mayor tiempo de estos archivos en el procedimiento almacenado.

Pero esto es solo vago, ya que el vacío cambiará estos archivos y el mtime.

3

Me gusta el enfoque de Jack. Puede consultar las estadísticas de mesa y saber el número de inserciones, actualizaciones, eliminaciones y así:

select n_tup_upd from pg_stat_user_tables where relname = 'YOUR_TABLE'; 

cada actualización se incrementará el recuento en 1.

desnudo en cuenta que este método es viable cuando se tiene una solo DB. múltiples instancias requerirán un enfoque diferente, probablemente.

Cuestiones relacionadas