2009-05-22 35 views
17

Tôi đang làm việc với một cơ sở dữ liệu postgreSQL được cập nhật theo lô. Tôi cần phải biết khi nào cơ sở dữ liệu (hoặc một bảng trong cơ sở dữ liệu) lần cuối cùng được cập nhật hoặc sửa đổi, hoặc sẽ thực hiện.Làm cách nào để tìm cơ sở dữ liệu PostgreSQL được cập nhật lần cuối?

Tôi thấy rằng ai đó trên diễn đàn postgeSQL đã đề xuất sử dụng ghi nhật ký và truy vấn nhật ký của bạn trong thời gian đó. Điều này sẽ không làm việc cho tôi vì tôi không có quyền kiểm soát đối với các codebase của khách hàng.

Trả lời

22

Bạn có thể viết một trigger để chạy mỗi khi chèn/cập nhật được thực hiện trên một bảng cụ thể. Cách sử dụng phổ biến là đặt cột "được tạo" hoặc "last_updated" của hàng thành thời gian hiện tại, nhưng bạn cũng có thể cập nhật thời gian ở vị trí trung tâm nếu bạn không muốn thay đổi các bảng hiện có.

Vì vậy, ví dụ như một cách điển hình là một sau:

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(); 

Sau đó, để tìm ra thời gian cập nhật cuối cùng, bạn cần phải chọn "MAX (LAST_UPDATED)" từ mỗi bảng bạn đang theo dõi và lấy vĩ đại nhất của những người, ví dụ:

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 

Đối với các bảng với một khóa chính nối tiếp (hoặc tương tự tạo), bạn có thể thử tránh quá trình quét tuần tự để tìm ra thời gian cập nhật mới nhất bằng cách sử dụng chỉ số khóa chính, hoặc bạn tạo chỉ số vào last_updated.

-- get timestamp of row with highest id 
SELECT last_updated FROM sometable ORDER BY sometable_id DESC LIMIT 1 

Lưu ý rằng điều này có thể cho kết quả hơi sai trong trường hợp ID không hoàn toàn tuần tự, nhưng bạn cần bao nhiêu độ chính xác? (Lưu ý rằng các giao dịch có nghĩa là các hàng có thể hiển thị cho bạn theo thứ tự khác với chúng được tạo ra.)

Một cách tiếp cận khác để tránh thêm các cột 'cập nhật' vào mỗi bảng là có bảng trung tâm để lưu trữ cập nhật timestamps trong Ví dụ:.

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(); 

này sẽ cung cấp cho bạn một bảng với một hàng cho mỗi lần cập nhật bảng: bạn có thể sau đó chỉ cần làm:

SELECT MAX(updated) FROM update_log 

để có được thời gian cập nhật cuối cùng. (Bạn có thể chia nhỏ bảng này ra nếu bạn muốn). Tất nhiên, bảng này sẽ tiếp tục phát triển: tạo chỉ mục trên 'cập nhật' (sẽ tạo một chỉ mục mới nhất) hoặc cắt theo định kỳ nếu phù hợp với trường hợp sử dụng của bạn (ví dụ: khóa độc quyền trên bàn) có được thời gian cập nhật mới nhất, sau đó cắt bớt nó nếu bạn cần phải định kỳ kiểm tra xem các thay đổi đã được thực hiện) chưa.

Một cách tiếp cận khác - có thể là những gì mọi người trong diễn đàn có nghĩa là đặt 'log_statement = mod' trong cấu hình cơ sở dữ liệu (toàn cầu cho cụm hoặc trên cơ sở dữ liệu hoặc người dùng bạn cần theo dõi) và sau đó tất cả các câu lệnh sửa đổi cơ sở dữ liệu sẽ được ghi vào nhật ký máy chủ. Sau đó, bạn sẽ cần phải viết một cái gì đó bên ngoài cơ sở dữ liệu để quét nhật ký máy chủ, lọc ra các bảng mà bạn không quan tâm, v.v.

4

Dường như bạn có thể sử dụng pg_stat_database để có được một số lượng giao dịch và kiểm tra xem điều này thay đổi từ chạy một backup tiếp theo - xem this dba.se answer và bình luận để biết thêm chi tiết

0

Bạn có thể viết một thủ tục lưu trữ trong một "không tin cậy ngôn ngữ "(ví dụ: plpythonu): Điều này cho phép truy cập các tệp trong thư mục" cơ sở "sau. Trả về thời gian lớn nhất của các tệp này trong quy trình được lưu trữ.

Nhưng điều này chỉ mơ hồ, vì chân không sẽ thay đổi các tệp này và thời gian.

3

Tôi thích cách tiếp cận của Jack. Bạn có thể truy vấn số liệu thống kê bảng và biết số lượng chèn, cập nhật, xóa và như vậy:

select n_tup_upd from pg_stat_user_tables where relname = 'YOUR_TABLE'; 

mỗi bản cập nhật sẽ làm tăng số lượng bằng 1.

trần trong tâm trí phương pháp này là khả thi khi bạn có một DB đơn. nhiều trường hợp sẽ yêu cầu phương pháp tiếp cận khác nhau có thể.

Các vấn đề liên quan