테이블의 마지막 수정 시간에 대한 신뢰할 수 있고 권위있는 레코드가 없습니다. relfilenode 사용은 여러 가지 이유로 잘못되었습니다.
처음에는 쓰기 헤드 로그 (WAL)에 기록 된 다음 힙 (테이블 파일)에 느리게 기록됩니다. 레코드가 WAL에 있으면 Pg는 레코드를 힙에 쓰려고 서두르지 않으며 다음 시스템 검사 점까지 기록되지 않을 수도 있습니다.
큰 테이블에는 여러 개의 포크가 있으므로 모든 포크를 확인하고 최신 타임 스탬프를 선택해야합니다.
SELECT
힌트 비트 설정으로 인해 간단한 테이블 기반 쓰기 작업을 생성 할 수 있습니다.
사용자가 볼 수있는 데이터를 변경하지 않는 autovaccum 및 기타 유지 관리는 여전히 관계 파일을 수정합니다.
와 같은 일부 작업 vaccum full
은 relfilenode를 대체합니다. 적절한 잠금 장치를 사용하지 않고 동시에 보려고하면 예상 한 위치가 아닐 수 있습니다.
몇 가지 옵션
신뢰성이 필요하지 않은 경우 pg_stat_database
및 의 정보를 사용할 수 있습니다 pg_stat_all_tables
. 이를 통해 마지막 통계 재설정 시간과 마지막 통계 재설정 이후 활동 통계를 제공 할 수 있습니다 . 가장 최근의 활동이 언제 였는지 알려주지 않고 마지막 통계 재설정 이후의 통계 일 뿐이며 해당 통계가 재설정되기 전에 발생한 일에 대한 정보는 없습니다. 제한되어 있지만 이미 있습니다.
안정적으로 수행하는 한 가지 옵션은 트리거를 사용하여 각 테이블의 마지막 수정 시간이 포함 된 테이블을 업데이트하는 것입니다. 이렇게 하면 테이블에 대한 모든 쓰기가 직렬화 되어 동시성이 손상됩니다. 또한 모든 거래에 상당한 오버 헤드를 추가합니다. 나는 그것을 권장하지 않습니다.
약간 덜 끔찍한 대안은 LISTEN
및 을 사용하는 것 NOTIFY
입니다. 외부 데몬 프로세스가 PostgreSQL 및 LISTEN
이벤트에 연결되도록하십시오 . 테이블이 변경되면 통지 페이로드로 테이블 ON INSERT OR UPDATE OR DELETE
을 사용하여 트리거를 사용 하여을 전송 하십시오 NOTIFY
. 트랜잭션이 커밋 될 때 전송됩니다. 데몬은 변경 알림을 누적하여 지연 시간을 데이터베이스의 테이블에 다시 쓸 수 있습니다. 시스템이 충돌하면 가장 최근의 수정 기록이 손실되지만 괜찮습니다. 충돌 후 시작하면 모든 테이블을 방금 수정 된 것으로 간주합니다.
동시성 문제의 최악을 피하기 위해 대신 before insert or update or delete or truncate on tablename for each statement execute
관계식을 매개 변수로 사용하도록 일반화 된 트리거를 사용하여 변경 타임 스탬프를 기록 할 수 있습니다. 그러면 (relation_oid, timestamp)
변경 로깅 테이블에 쌍이 삽입 됩니다. 그런 다음 별도의 연결에서 도우미 프로세스를 갖거나 앱에서 주기적으로 호출하고 최신 정보를 위해 해당 테이블을 집계하여 최신 변경 사항을 요약 테이블로 병합 한 다음 로그 테이블을 자릅니다. 수신 / 알림 접근 방식에 비해이 방법의 유일한 장점은 충돌시 정보를 잃지 않지만 효율성도 떨어진다는 것입니다.
또 다른 방법은 C 확장 기능을 쓸 수 있습니다 그 용도 (예를 들어) ProcessUtility_hook
, ExecutorRun_hook
트랩 테이블 변경 및 느리게 업데이트 통계에 등. 나는 이것이 얼마나 실용적인지 보지 않았다. 소스의 다양한 _hook 옵션을 살펴보십시오.
가장 좋은 방법은 통계 코드를 패치하여이 정보를 기록하고 핵심에 포함시키기 위해 PostgreSQL에 패치를 제출하는 것입니다. 코드 작성만으로 시작하지 마십시오. 잘 정의 된 방법으로 할 수있을 정도로 충분히 생각한 후에는 해커에 대한 아이디어를 높이십시오 (예 : 코드를 읽는 것으로 시작하고 "어떻게해야합니까 ..."라고 게시하지 마십시오). 에 마지막 업데이트 시간을 추가하는 것이 좋을 수도 pg_stat_...
있지만 오버 헤드에 가치가있는 커뮤니티를 설득하거나 선택적으로 추적 할 수있는 방법을 제공 해야합니다. 통계를 유지하려면 코드를 작성해야합니다. 패치를 제출하십시오. 이 기능을 원하는 사람 만이 그 기능을 방해 할 것입니다.
내가 어떻게
이 작업을 수행해야하는데 제대로 패치를 작성할 시간이 없다면 위에서 설명한 청취 / 알림 방법을 사용했을 것입니다.
PostgreSQL 9.5 커밋 타임 스탬프 업데이트
업데이트 : PostgreSQL 9.5에는 커밋 타임 스탬프가 있습니다. 당신이있는 경우 그들에 사용할 수 postgresql.conf
, 당신은 가장 큰있는 행에 대한 타임 스탬프를 커밋 확인할 수 있습니다 (너무 과거에 그렇게) xmin
할 대략 마지막으로 수정 된 시간. 가장 최근의 행이 삭제 된 경우에는 계산되지 않으므로 근사값 일뿐입니다.
또한 커밋 타임 스탬프 레코드는 제한된 시간 동안 만 유지됩니다. 따라서 많이 수정되지 않은 테이블을 언제 수정해야하는지에 대한 답을 얻으려면 실제로 "잠깐만"이라고 대답하면됩니다.