Não há nenhum registro confiável e autoritário do horário da última modificação de uma tabela. O uso do relfilenode está errado por vários motivos:
As gravações são inicialmente registradas no WAL (write-head log) e depois preguiçosamente no heap (os arquivos da tabela). Quando o registro está no WAL, a página não se apressa em gravá-lo no heap e pode até não ser gravado até o próximo ponto de verificação do sistema;
Tabelas maiores têm vários garfos, você precisará verificar todos os garfos e escolher o carimbo de data / hora mais recente;
Um simples SELECT
pode gerar atividade de gravação na tabela subjacente devido à configuração do bit de dica;
autovaccum e outras manutenções que não alteram os dados visíveis do usuário ainda modificam os arquivos de relação;
algumas operações, como vaccum full
, substituirão o relfilenode. Pode não ser o esperado, se você estiver tentando visualizá-lo simultaneamente sem usar o bloqueio apropriado.
Algumas opções
Se você não precisar de confiabilidade, poderá usar as informações em pg_stat_database
e pg_stat_all_tables
. Isso pode indicar o horário da última redefinição de estatísticas e as atividades desde a última redefinição. Ele não informa quando foi a atividade mais recente, apenas que ocorreu desde a última redefinição de estatísticas e não há informações sobre o que aconteceu antes da redefinição dessas estatísticas. Portanto, é limitado, mas já está lá.
Uma opção para fazer isso de forma confiável é usar um gatilho para atualizar uma tabela que contém os horários da última modificação para cada tabela. Esteja ciente de que isso serializará todas as gravações na tabela , destruindo a simultaneidade. Ele também adicionará um pouco de sobrecarga a todas as transações. Eu não recomendo.
Uma alternativa um pouco menos terrível é usar LISTEN
e NOTIFY
. Tenha um processo de daemon externo conectado ao PostgreSQL e LISTEN
para eventos. Use ON INSERT OR UPDATE OR DELETE
gatilhos para enviar NOTIFY
s quando uma tabela for alterada, com a tabela oid como carga útil de notificação. Eles são enviados quando a transação é confirmada. Seu daemon pode acumular notificações de alteração e gravá-las lentamente em uma tabela no banco de dados. Se o sistema travar, você perderá o registro das modificações mais recentes, mas tudo bem, você tratará todas as tabelas como modificadas apenas se estiver iniciando após uma falha.
Para evitar os piores problemas de simultaneidade, você pode registrar os carimbos de data / hora da mudança usando um before insert or update or delete or truncate on tablename for each statement execute
gatilho, generalizado para usar a relação oid como parâmetro. Isso inseriria um (relation_oid, timestamp)
par em uma tabela de registro de alterações. Você tem um processo auxiliar em uma conexão separada ou chamado periodicamente pelo seu aplicativo, agrega essa tabela para obter as informações mais recentes, mescla-a em uma tabela de resumo das alterações mais recentes e trunca a tabela de log. A única vantagem disso em relação à abordagem de ouvir / notificar é que ela não perde informações em caso de falha - mas é ainda menos eficiente também.
Outra abordagem poderia ser a de escrever uma função de extensão C que usa (por exemplo) ProcessUtility_hook
, ExecutorRun_hook
, etc à mesa alterações armadilha e estatísticas de atualização preguiçosamente. Não olhei para ver como isso seria prático; dê uma olhada nas várias opções _hook nas fontes.
A melhor maneira seria corrigir o código estatístico para registrar essas informações e enviar um patch ao PostgreSQL para inclusão no núcleo. Não basta começar escrevendo código; aumente sua idéia em -hackers quando você pensar sobre isso o suficiente para ter uma maneira bem definida de fazê-lo (por exemplo, comece lendo o código, não apenas poste perguntando "como faço para ..."). Pode ser bom acrescentar os horários da última atualização pg_stat_...
, mas você precisa convencer a comunidade de que vale a pena a sobrecarga ou fornecer uma maneira de torná-la opcionalmente rastreada - e você deve escrever o código para manter as estatísticas e envie um patch , porque apenas alguém que deseja esse recurso se incomodará com isso.
Como eu faria isso
Se eu tivesse que fazer isso e não tivesse tempo de escrever um patch para fazê-lo corretamente, provavelmente usaria a abordagem de ouvir / notificar descrita acima.
Atualização para os carimbos de data e hora do commit do PostgreSQL 9.5
Atualização : O PostgreSQL 9.5 possui registros de data e hora . Se você os tiver ativado postgresql.conf
(e também o fez no passado), poderá verificar o registro de data e hora da confirmação com a maior linha xmin
para aproximar a hora da última modificação. É apenas uma aproximação, porque se as linhas mais recentes forem excluídas, elas não serão contadas.
Além disso, os registros de registro de data e hora de confirmação são mantidos apenas por um tempo limitado. Portanto, se você quiser saber quando uma tabela que não é muito modificada é modificada, a resposta será efetivamente "não sei, há um tempo atrás".