Bir tablonun son değiştirilme zamanının güvenilir ve yetkili bir kaydı yoktur. Relfilenode kullanımı birçok nedenden dolayı yanlıştır:
Yazma başlangıçta yazma kafası günlüğüne (WAL), ardından tembel olarak yığına (tablo dosyaları) kaydedilir. Kayıt WAL'a girdiğinde, Pg yığına yazmak için acele etmez ve bir sonraki sistem kontrol noktasına kadar yazılmayabilir;
Daha büyük tablolarda birden fazla çatal bulunur, tüm çatalları kontrol etmeniz ve en yeni zaman damgasını seçmeniz gerekir;
Bir basit SELECTipucu-bit ayarı nedeniyle alttaki tabloya yazma etkinliği üretebilir;
autovaccum ve kullanıcının görünür verilerini değiştirmeyen diğer bakımlar hala ilişki dosyalarını değiştirir;
Gibi bazı işlemler vaccum fullrelfilenode yerini alacak. Uygun bir kilit almadan aynı anda bakmaya çalışıyorsanız, beklediğiniz yerde olmayabilir.
Birkaç seçenek
Güvenilirliğe ihtiyacınız yoksa, pg_stat_databaseve içindeki bilgileri potansiyel olarak kullanabilirsiniz pg_stat_all_tables. Bunlar, son istatistiklerin sıfırlanmasının zamanını ve son istatistiklerin sıfırlanmasından bu yana etkinlik istatistiklerini verebilir . En son etkinliğin ne zaman olduğunu, yalnızca son istatistiklerin sıfırlanmasından bu yana olduğunu söylemez ve bu istatistiklerin sıfırlanmasından önce ne olduğu hakkında hiçbir bilgi yoktur. Bu yüzden sınırlı, ama zaten orada.
Güvenilir bir şekilde yapmak için bir seçenek, her bir tablo için en son değiştirilen süreleri içeren bir tabloyu güncellemek için bir tetikleyici kullanmaktır. Bunu yapmanın , tüm yazıları masaya serileştirip eşzamanlılığı yok edeceğini unutmayın . Ayrıca, her işlem için bir miktar ek yük ekler. Tavsiye etmiyorum.
Biraz daha az kötü alternatif kullanmaktır LISTENve NOTIFY. PostgreSQL'e ve LISTENetkinlikler için harici bir daemon sürecinin bağlanmasını sağlayın . Bir tablo değiştiğinde tabloları bildirmek ON INSERT OR UPDATE OR DELETEiçin tetikleyicileri kullanın NOTIFY; tablo, bildirim yükü olarak verilir. İşlem tamamlandığında bunlar gönderilir. Arka planınız değişiklik bildirimleri toplayabilir ve bunları tembel olarak veritabanındaki bir tabloya geri yazabilir. Sistem çökerse, en son değişikliklerin kaydını kaybedersiniz, ancak sorun değil, yalnızca bir çökmeden sonra başlarsanız tüm tabloları değiştirilmiş olarak kabul edersiniz.
Eşzamanlılık sorunlarının en kötüsünü önlemek için, bunun yerine bir before insert or update or delete or truncate on tablename for each statement executeilişki parametresi olarak almak üzere genelleştirilmiş bir tetikleyici kullanarak değişiklik zaman damgalarını günlüğe kaydedebilirsiniz . Bu, (relation_oid, timestamp)bir değişiklik günlüğü tablosuna bir çift ekler . Daha sonra ayrı bir bağlantıda veya uygulamanız tarafından periyodik olarak adlandırılan bir yardımcı işlem görürsünüz, bu tabloyu en son bilgiler için toplar, en son değişikliklerin bir özet tablosunda birleştirir ve günlük tablosunu kesersiniz. Bunun dinleme / bildirim yaklaşımına göre tek avantajı kaza ile ilgili bilgileri kaybetmemesidir - ancak bu daha az verimlidir.
Diğer bir yaklaşım, bir C uzatma işlevi yazmak olabileceğini kullandığı (örn) ProcessUtility_hook, ExecutorRun_hooktuzak masa değişiklikleri ve tembel güncelleme istatistiklerine vb. Bunun ne kadar pratik olacağını görmedim; Kaynaklardaki çeşitli _hook seçeneklerine bir göz atın.
Bu bilgiyi kaydetmek için istatistik kodunu yamalamak ve çekirdeğe dahil edilmek üzere PostgreSQL'e bir yama göndermek en iyi yoldur. Sadece kod yazarak başlamayın; Bunu yapmak için iyi tanımlanmış bir yol için yeterli olduğunu düşündüğünüzde, bilgisayar korsanlarına dair fikrinizi yükseltin (örneğin, kodu okuyarak başlayın, sadece "nasıl yaparım ..." diye soran göndermeyin). Adresine en son güncellenen süreleri eklemek güzel olabilir pg_stat_..., ancak toplumu genel giderlere değdiğine ikna etmeniz veya isteğe bağlı olarak izlenmesi için bir yol sağlamanız gerekir - istatistikleri korumak için kodu da yazmanız gerekir. Bir düzeltme eki gönder , çünkü yalnızca bu özelliği isteyen biri bununla uğraşacak.
Nasıl yaparım
Bunu yapmak zorunda olsaydım ve düzgün bir şekilde yapmak için bir yama yazmak için vaktim olmadıysa, muhtemelen yukarıda belirtilen dinleme / bildirim yaklaşımını kullanırdım.
PostgreSQL 9.5 güncelleme zaman damgası güncellemesi
Güncelleme : PostgreSQL 9.5'in zaman damgaları var . Eğer varsa onları etkinleştirilmiş postgresql.conf, sen en ile satır için zaman damgası işlemek kontrol edebilirsiniz (ve de geçmişte öyle yaptım) xminiçin tahmin son değiştirilme zamanı. Bu sadece bir yaklaşım çünkü en son satırlar silindiyse sayılmayacak.
Ayrıca, kesin zaman damgası kayıtları yalnızca sınırlı bir süre için saklanır. Bu nedenle, çok fazla değiştirilmemiş bir masanın ne zaman değiştirildiğini anlatmak istiyorsanız, cevap etkili bir şekilde "bir süre önce" dunno olacaktır.