Không có hồ sơ đáng tin cậy, có thẩm quyền về thời gian sửa đổi cuối cùng của bảng. Sử dụng relfilenode là sai vì rất nhiều lý do:
Các bài viết ban đầu được ghi vào nhật ký đầu ghi (WAL), sau đó lười biếng vào heap (các tệp bảng). Khi bản ghi đã ở WAL, PG không vội viết nó vào heap và nó thậm chí có thể không được ghi cho đến khi điểm kiểm tra hệ thống tiếp theo;
Các bảng lớn hơn có nhiều nhánh, bạn phải kiểm tra tất cả các nhánh và chọn dấu thời gian mới nhất;
Một đơn giản SELECT
có thể tạo ra hoạt động ghi vào bảng bên dưới do cài đặt gợi ý bit;
autovaccum và bảo trì khác không thay đổi dữ liệu hiển thị của người dùng vẫn sửa đổi các tệp quan hệ;
một số hoạt động, như vaccum full
, sẽ thay thế relfilenode. Nó có thể không phải là nơi bạn mong đợi nếu bạn đang cố gắng nhìn vào nó đồng thời mà không có một khóa thích hợp.
Một vài lựa chọn
Nếu bạn không cần độ tin cậy, bạn có thể sử dụng thông tin trong pg_stat_database
và pg_stat_all_tables
. Chúng có thể cung cấp cho bạn thời gian đặt lại thống kê cuối cùng và thống kê hoạt động kể từ lần đặt lại thống kê cuối cùng. Nó không cho bạn biết khi nào hoạt động gần đây nhất, chỉ có điều đó là từ lần đặt lại thống kê cuối cùng và không có thông tin nào về những gì đã xảy ra trước khi thống kê lại. Vì vậy, nó có giới hạn, nhưng nó đã ở đó.
Một tùy chọn để thực hiện nó một cách đáng tin cậy là sử dụng trình kích hoạt để cập nhật bảng chứa thời gian được sửa đổi lần cuối cho mỗi bảng. Hãy lưu ý rằng làm như vậy sẽ tuần tự hóa tất cả ghi vào bảng , phá hủy đồng thời. Nó cũng sẽ thêm một chút chi phí hợp lý cho mỗi giao dịch. Tôi không khuyên bạn nên nó.
Một thay thế ít tệ hại hơn là sử dụng LISTEN
và NOTIFY
. Có một quy trình trình nền bên ngoài kết nối với PostgreSQL và LISTEN
cho các sự kiện. Sử dụng các ON INSERT OR UPDATE OR DELETE
kích hoạt để gửi NOTIFY
s khi một bảng thay đổi, với bảng oid là tải trọng thông báo. Chúng được gửi khi giao dịch cam kết. Trình nền của bạn có thể tích lũy các thông báo thay đổi và lười biếng viết chúng trở lại một bảng trong cơ sở dữ liệu. Nếu hệ thống gặp sự cố, bạn sẽ mất bản ghi các sửa đổi gần đây nhất, nhưng không sao, bạn chỉ coi tất cả các bảng là vừa được sửa đổi nếu bạn khởi động sau sự cố.
Để tránh những vấn đề tồi tệ nhất xảy ra, thay vào đó, bạn có thể ghi lại dấu thời gian thay đổi bằng cách sử dụng trình before insert or update or delete or truncate on tablename for each statement execute
kích hoạt, được khái quát hóa để lấy mối quan hệ oid làm tham số. Điều này sẽ chèn một (relation_oid, timestamp)
cặp vào bảng ghi nhật ký thay đổi. Sau đó, bạn có một quy trình trợ giúp trên một kết nối riêng hoặc được gọi theo định kỳ bởi ứng dụng của bạn, tổng hợp bảng đó cho thông tin mới nhất, hợp nhất nó vào một bảng tóm tắt các thay đổi gần đây nhất và cắt bớt bảng nhật ký. Ưu điểm duy nhất của phương pháp này so với phương pháp lắng nghe / thông báo là nó không bị mất thông tin về sự cố - nhưng nó thậm chí còn kém hiệu quả hơn.
Một cách khác có thể là để viết một hàm mở rộng C sử dụng (ví dụ) ProcessUtility_hook
, ExecutorRun_hook
, vv để thay đổi bảng bẫy và số liệu thống kê cập nhật một cách lười biếng. Tôi đã không nhìn thấy điều này sẽ thực tế như thế nào; hãy xem các tùy chọn _hook khác nhau trong các nguồn.
Cách tốt nhất là vá mã thống kê để ghi lại thông tin này và gửi một bản vá cho PostgreQuery để đưa vào lõi. Đừng chỉ bắt đầu bằng cách viết mã; nêu ý tưởng của bạn về những kẻ tấn công một khi bạn nghĩ về nó đủ để có một cách được xác định rõ ràng để thực hiện nó (tức là bắt đầu bằng cách đọc mã, đừng chỉ đăng câu hỏi "làm thế nào để tôi ..."). Có thể tốt hơn khi thêm thời gian cập nhật lần cuối vào pg_stat_...
, nhưng bạn phải thuyết phục cộng đồng rằng nó đáng để chi trả hoặc cung cấp cách để làm cho nó được theo dõi tùy chọn - và bạn phải viết mã để giữ số liệu thống kê và gửi một bản vá , bởi vì chỉ có ai đó muốn tính năng này sẽ bận tâm với điều đó.
Làm thế nào tôi làm điều đó
Nếu tôi phải làm điều này và không có thời gian để viết một bản vá để thực hiện đúng cách, có lẽ tôi sẽ sử dụng phương pháp nghe / thông báo đã nêu ở trên.
Cập nhật cho dấu thời gian cam kết PostgreSQL 9.5
Cập nhật : PostgreSQL 9.5 có dấu thời gian cam kết . Nếu bạn đã bật chúng trong postgresql.conf
quá khứ (và cũng đã làm như vậy trong quá khứ), bạn có thể kiểm tra dấu thời gian cam kết cho hàng với mức lớn nhất xmin
để xấp xỉ thời gian sửa đổi cuối cùng. Đó chỉ là một xấp xỉ bởi vì nếu các hàng gần đây nhất đã bị xóa thì chúng sẽ không được tính.
Ngoài ra, các bản ghi dấu thời gian cam kết chỉ được lưu giữ trong một thời gian giới hạn. Vì vậy, nếu bạn muốn biết khi nào một bảng không được sửa đổi nhiều được sửa đổi, câu trả lời sẽ có hiệu quả là "dunno, một thời gian trước".