No existe un registro confiable y automático de la última hora modificada de una tabla. Usar el relfilenode está mal por muchas razones:
Las escrituras se registran inicialmente en el registro de encabezado de escritura (WAL), luego , lentamente, en el montón (los archivos de la tabla). Una vez que el registro está en WAL, Pg no se apresura a escribirlo en el montón, y es posible que ni siquiera se escriba hasta el próximo punto de control del sistema;
Las tablas más grandes tienen múltiples horquillas, tendría que verificar todas las horquillas y elegir la marca de tiempo más nueva;
Un simple SELECT
puede generar actividad de escritura en la tabla subyacente debido a la configuración de bits de pista;
autovaccum y otro mantenimiento que no cambia los datos visibles del usuario todavía modifica los archivos de relación;
Algunas operaciones, como vaccum full
, reemplazarán el relfilenode. Es posible que no sea lo que espera si está tratando de verlo simultáneamente sin tomar un bloqueo adecuado.
Algunas opciones
Si no necesita confiabilidad, puede usar la información en pg_stat_database
y pg_stat_all_tables
. Estos pueden darle el tiempo del último restablecimiento de estadísticas y las estadísticas de actividad desde el último restablecimiento de estadísticas. No te dice cuándo fue la actividad más reciente, solo que fue desde el último restablecimiento de estadísticas, y no hay información sobre lo que sucedió antes de que se restablecieran las estadísticas. Entonces es limitado, pero ya está ahí.
Una opción para hacerlo de manera confiable es usar un disparador para actualizar una tabla que contiene los últimos tiempos modificados para cada tabla. Tenga en cuenta que al hacerlo se serializarán todas las escrituras en la tabla , destruyendo la concurrencia. También agregará un poco de sobrecarga a cada transacción. No lo recomiendo
Una alternativa un poco menos horrible es usar LISTEN
y NOTIFY
. Haga que un proceso de demonio externo se conecte a PostgreSQL y LISTEN
para eventos. Use ON INSERT OR UPDATE OR DELETE
disparadores para enviar mensajes de NOTIFY
correo electrónico cuando una tabla cambia, con la tabla oid como la carga útil de notificación. Estos se envían cuando se confirma la transacción. Su demonio puede acumular notificaciones de cambio y perezosamente escribirlas de nuevo en una tabla en la base de datos. Si el sistema falla, pierde su registro de las modificaciones más recientes, pero está bien, solo trata todas las tablas como recién modificadas si está iniciando después de un bloqueo.
Para evitar el peor de los problemas de concurrencia, puede registrar las marcas de tiempo de cambio utilizando un before insert or update or delete or truncate on tablename for each statement execute
disparador, generalizado para tomar la relación oid como parámetro. Esto insertaría un (relation_oid, timestamp)
par en una tabla de registro de cambios. Luego, tiene un proceso auxiliar en una conexión separada, o su aplicación lo llama periódicamente, agrega esa tabla para obtener la información más reciente, la fusiona en una tabla resumen de los cambios más recientes y trunca la tabla de registro. La única ventaja de esto sobre el enfoque de escuchar / notificar es que no pierde información sobre el bloqueo, pero también es menos eficiente.
Otro enfoque podría ser la de escribir una función de extensión de C que los usos (por ejemplo) ProcessUtility_hook
, ExecutorRun_hook
, etc a cambios en la tabla de trampas y las estadísticas de actualización pereza. No he mirado para ver cuán práctico sería esto; Eche un vistazo a las diversas opciones de _hook en las fuentes.
La mejor manera sería parchear el código de estadísticas para registrar esta información y enviar un parche a PostgreSQL para incluirlo en el núcleo. No solo comience escribiendo código; plantee su idea sobre los piratas informáticos una vez que lo haya pensado lo suficiente como para tener una forma bien definida de hacerlo (es decir, comience leyendo el código, no solo publique preguntando "¿cómo ...?"). Podría ser bueno agregar los últimos tiempos actualizados pg_stat_...
, pero tendría que convencer a la comunidad de que valía la pena los gastos generales o proporcionar una forma de hacer un seguimiento opcional, y tendría que escribir el código para mantener las estadísticas y envíe un parche , porque solo alguien que quiera esta función se molestará con eso.
Como lo haría
Si tuviera que hacer esto y no tuviera tiempo de escribir un parche para hacerlo correctamente, probablemente usaría el enfoque de escuchar / notificar descrito anteriormente.
Actualización para las marcas de tiempo de confirmación de PostgreSQL 9.5
Actualización : PostgreSQL 9.5 tiene marcas de tiempo de confirmación . Si los ha habilitado postgresql.conf
(y también lo hizo en el pasado), puede verificar la marca de tiempo de confirmación de la fila con el mayor xmin
para aproximar la última hora modificada. Es solo una aproximación porque si se han eliminado las filas más recientes, no se contarán.
Además, los registros de marca de tiempo de confirmación solo se mantienen durante un tiempo limitado. Entonces, si desea saber cuándo se modifica una tabla que no se modifica mucho, la respuesta será efectivamente "no sé, hace un tiempo".