postgresql에서 최대 레코드 수를 유지할 수 있습니까?


9

기본적으로 Postgresql 테이블의 일부는 서버 액세스 로그를 유지하는 데 사용되며 때로는 생산 중에 상당히 커질 수 있습니다. postgresql에서 테이블이 가질 수있는 최대 레코드 수를 보유하고 가장 오래된 레코드를 푸시하도록 설정하는 방법이 있습니까?

답변:


12

원하는 행 번호를 유지하기 위해 트리거를 정의 할 수 있습니다.

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). 타임 스탬프 (또는 파생 날짜)를 범위 파티셔닝 조건으로 사용할 수 있습니다.

그러나 오래된 로그를 삭제하기 전에주의하십시오. 당신은 결코 그것들을 필요로하지 않을 것이라고 확신합니까?


우리는 주기적으로 실행할 수 있고, 테이블이 이것을 요구하기에 충분히
커지면

또한 postgres가 어느 것이 더 오래된 것인지 알 수 있기를 바랐지만 ID가 없으면 날짜 생성 타임 스탬프 필드 "2012-06-22 17 : 17 : 52.692514"
Jharwood

@Jharwood-내 답변을 편집했습니다. 자세한 내용이 필요하면 알려주십시오.
dezso 2016 년

2
파티셔닝 제안에 +1. 매번 테이블을 검색하는 극단적 인 오버 헤드없이 카운트를 사용하려면 근사치에 pg_class.reltuples를 사용하거나 트리거를 사용하여 "제어"테이블에서 카운트를 유지할 수 있습니다.
kgrittn

4

더 일반적인 테이블 독립 함수를 만들었습니다.

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 가지 매개 변수가 사용됩니다.

  • 탭 : 테이블 이름
  • keyfld : 숫자, 프로그레시브 키 필드
  • nritems : 보유 할 항목 수
  • rnd : 0 내지 1의 난수; 클수록 테이블이 더 자주 정리됩니다 (0 = never, 1 = 항상, 0.1 = 10 %)

이 방법으로 동일한 함수를 호출하려는 트리거 수를 만들 수 있습니다.

도움이 되었기를 바랍니다.


0

이 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;
$$;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.