Có thể giữ số lượng bản ghi tối đa trong postgresql?


9

Về cơ bản, một phần của bảng Postgresql của chúng tôi được sử dụng để giữ nhật ký truy cập máy chủ và đôi khi trong quá trình sản xuất, điều này có thể trở nên khá lớn. Có cách nào để thiết lập trong postgresql để có số lượng bản ghi tối đa mà một bảng có thể có và loại bỏ bản ghi cũ nhất không?

Câu trả lời:


12

Bạn có thể xác định một kích hoạt để duy trì số hàng mong muốn của bạn:

CREATE OR REPLACE FUNCTION trf_keep_row_number_steady()
RETURNS TRIGGER AS
$body$
BEGIN
    -- delete only where are too many rows
    IF (SELECT count(id) FROM log_table) > rownum_limit
    THEN 
        -- I assume here that id is an auto-incremented value in log_table
        DELETE FROM log_table
        WHERE id = (SELECT min(id) FROM log_table);
    END IF;
END;
$body$
LANGUAGE plpgsql;

CREATE TRIGGER tr_keep_row_number_steady 
AFTER INSERT ON log_table
FOR EACH ROW EXECUTE PROCEDURE trf_keep_row_number_steady();

Đây có lẽ không phải là tùy chọn hoạt động tốt nhất, nhưng một khi bạn đạt đến giới hạn, nó sẽ không bao giờ vượt quá. Nếu có không gian cho biến động, thì bạn có thể kiểm tra số hàng theo định kỳ và xóa các hàng thừa từ đầu.

EDIT: Nếu bạn có nhật ký thực sự lớn (giả sử một triệu mỗi tháng) thì phân vùng có thể là giải pháp dễ nhất. Sau đó, bạn có thể chỉ cần thả các bảng không cần thiết (nói ở đâumax(timestamp) < CURRENT_DATE - 1 year). Bạn có thể sử dụng dấu thời gian của mình (hoặc ngày bắt nguồn) làm điều kiện để phân vùng phạm vi .

Nhưng hãy cẩn thận trước khi loại bỏ các bản ghi cũ. Bạn có chắc chắn bạn sẽ không bao giờ cần những thứ đó?


chúng tôi có thể thực hiện nó theo định kỳ và chúng tôi chắc chắn rằng chúng tôi sẽ không cần đến chúng khi bảng đủ lớn để yêu cầu điều này, tôi chỉ cố gắng tự động hóa bảo trì DB càng nhiều càng tốt :)
Jharwood

Ngoài ra, tôi đã hy vọng rằng các postgres có thể biết cái nào cũ hơn, nhưng nếu không có ID thì nó có thể sử dụng trường dấu thời gian được tạo ra của chúng tôi "2012-06-22 17: 17: 52,692514"
Jharwood

@Jharwood - Chỉnh sửa câu trả lời của tôi. Xin vui lòng cho tôi biết nếu bạn cần thêm chi tiết.
dezso

2
+1 trên đề xuất phân vùng. Nếu bạn muốn đi với số đếm mà không cần quá nhiều lần quét bảng mỗi lần, bạn có thể sử dụng pg_group.reltuples cho một xấp xỉ bạn có thể sử dụng trình kích hoạt để duy trì số đếm trong bảng "điều khiển".
kgrittn

4

Tôi đã tạo ra một chức năng độc lập bảng chung hơn.

CREATE OR REPLACE FUNCTION keep_row_number_steady()
RETURNS TRIGGER AS
$body$
DECLARE
    tab text;
    keyfld text;
    nritems INTEGER;
    rnd DOUBLE PRECISION;
BEGIN
    tab := TG_ARGV[0];
    keyfld := TG_ARGV[1];
    nritems := TG_ARGV[2]; 
    rnd := TG_ARGV[3];

    IF random() < rnd
    THEN 
        EXECUTE(format('DELETE FROM %s WHERE %s < (SELECT %s FROM %s ORDER BY %s DESC LIMIT 1 OFFSET %s)', tab, keyfld, keyfld, tab, keyfld, nritems));
    END IF;
    RETURN NULL;
END;
$body$
LANGUAGE plpgsql;

CREATE TRIGGER log_table_keep_row_number_steady_trigger
AFTER INSERT ON log_table
FOR EACH STATEMENT EXECUTE PROCEDURE keep_row_number_steady('log_table', 'id', 1000, 0.1);

Hàm có 4 tham số:

  • tab: tên bảng
  • keyfld: trường khóa số, lũy tiến
  • nritems: số lượng vật phẩm cần giữ lại
  • rnd: số ngẫu nhiên, từ 0 đến 1; càng lớn, bảng càng thường xuyên sẽ được làm sạch (0 = không bao giờ, 1 = luôn luôn, 0,1 = 10% số lần)

Bằng cách này bạn có thể tạo bao nhiêu kích hoạt bạn muốn gọi cùng một chức năng.

Hi vọng điêu nay co ich.


0

Tôi đã tạo Proc này và chạy nó từ PG Agent (hoặc windows job hoặc cron job tùy thuộc). Tôi có thể có nhiều hàng hơn, điều này chỉ giữ cho bảng nhật ký của tôi không quá lớn. Tiết kiệm chi phí của một kích hoạt.

CREATE or replace FUNCTION activitylogcleanup(_MaxRows int) RETURNS void
    LANGUAGE plpgsql
    AS $$
DECLARE
   minid    int;
BEGIN
    SELECT logid into minid FROM activitylogapplication 
     order by logid desc limit 1 OFFSET _MaxRows;

    if not found then 
        return;
    END IF; 

    Delete from activitylogapplication where logid < minid;
END;
$$;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.