답변:
원하는 행 번호를 유지하기 위해 트리거를 정의 할 수 있습니다.
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();
이것은 가장 성능이 좋은 옵션은 아니지만 한계에 도달하면 절대 초과하지 않습니다. 변동을위한 공간이 있으면 주기적으로 행 번호를 확인하고 처음부터 초과 행을 삭제할 수 있습니다.
편집 : 파티션
보다 실제로 큰 로그 (예 : 한 달에 백만)가있는 경우 가장 쉬운 해결책이 될 수 있습니다. 그런 다음 불필요한 테이블을 삭제하면됩니다 (예 : wheremax(timestamp) < CURRENT_DATE - 1 year). 타임 스탬프 (또는 파생 날짜)를 범위 파티셔닝 조건으로 사용할 수 있습니다.
그러나 오래된 로그를 삭제하기 전에주의하십시오. 당신은 결코 그것들을 필요로하지 않을 것이라고 확신합니까?
더 일반적인 테이블 독립 함수를 만들었습니다.
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);
이 기능에는 4 가지 매개 변수가 사용됩니다.
이 방법으로 동일한 함수를 호출하려는 트리거 수를 만들 수 있습니다.
도움이 되었기를 바랍니다.
이 proc을 작성하고 PG 에이전트 (또는 Windows 작업 또는 cron 작업에 따라)에서 실행했습니다. 더 많은 행을 가질 수 있습니다. 이것은 내 로그 테이블을 너무 크게 유지하지 않습니다. 트리거의 오버 헤드를 저장합니다.
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;
$$;