tl; dr : 커밋 된 후 데이터를 읽는 첫 번째 프로세스는 힌트 비트를 설정합니다. 페이지가 더러워 져 쓰기 작업이 생성됩니다. 다른 것은 VACUUM
필요한 경우 (하지만 다른 명령) 수행은 마크에게 모두 볼 수와 페이지입니다. VACUUM
결국 튜플을 고정시키기 위해 테이블을 쳐야합니다.
인서트 후에 수행해야하는 작업은 실제로는 다른 작업의 의미에서 최소한 정리 VACUUM
되지 않습니다. 세부 정보로 이동하기 전에이 답변은 현재 (릴리스되지 않은) 9.6 코드를 기반으로하며 가시성에 영향을 줄 수 있지만 스트리밍 복제의 영향을 무시하고 있습니다.
MVCC 때문에 Postgres가 튜플을 쿼리에 표시해야하는지 평가할 때마다 다른 기준과 함께 튜플을 생성 한 트랜잭션 (xmin 숨겨진 필드에 기록)이 커밋되었는지 여부를 고려해야합니다. 이 검사는 비용이 많이 들기 때문에 트랜잭션이 현재 열려있는 모든 트랜잭션에 표시되는 것을 알 자마자 튜플 헤더에 "힌트 비트"가 설정되어 있음을 나타냅니다. 해당 비트의 설정은 페이지를 더 럽히므로 디스크에 기록해야합니다. 데이터를 읽는 다음 명령 SELECT
이 갑자기 많은 쓰기 트래픽을 생성하는 명령 인 경우 이는 매우 혼란 스러울 수 있습니다 . VACUUM
삽입 커밋 후를 실행 하면 피할 수 있습니다. 또 다른 중요한 차이점은VACUUM
는 페이지에 정리 잠금이있는 한 항상 페이지에서 튜플을 암시하지만 대부분의 다른 명령은 명령을 시작 하기 전에 삽입 트랜잭션이 커밋 된 경우에만 암시합니다 .
이러한 모든 힌트 비트를 작성하는 데있어 중요한 점은 VACUUM
조절할 수 있다는 것입니다 (자동 진공은 기본적으로 조절됩니다). 다른 명령은 제한되지 않으며 가능한 빨리 더티 데이터를 생성합니다.
VACUUM
페이지를 모두 표시 가능으로 표시하는 유일한 방법으로 일부 작업 (특히 색인 만 스캔)에서 성능을 고려해야합니다. 큰 삽입을 수행하는 경우 새로 삽입 된 튜플 외에는 많은 페이지가있을 가능성이 큽니다. 시작 시 가장 오래된 실행 트랜잭션 이 데이터를 삽입 한 트랜잭션보다 최신 인 경우에만VACUUM
해당 페이지를 모두 표시 가능한 것으로 표시 할 수 있습니다 .VACUUM
MVCC의 작동 방식으로 인해 ~ 20 억 건 이상의 트랜잭션이 삽입 된 튜플 은 " 고정 " 으로 표시 되어야합니다 . 기본적으로 autovacuum은 200M 트랜잭션마다이를 수행합니다. 벌크 인서트 후 vacuum_freeze_min_age를 0으로 설정하여 수동 진공을 실행하면 그 영향을 줄일 수 있습니다. 더 적극적으로, 당신은 삽입 후 테이블에서 실행할 수 있습니다 . 그것은 다음 동결 스캔이 일어날 때 "시계를 재설정"할 것입니다.VACUUM FREEZE
특정 세부 정보를 알고 싶다면 inside HEAPTUPLE_LIVE
호출 후 사례를 살펴보십시오 . 자체 도 참조 하여 비교하십시오 .HeapTupleSatisfiesVacuum()
lazy_scan_heap()
HeapTupleSatisfiesVacuum()
HeapTupleSatisfiesMVCC()
흥미로운 두 가지 다른 프레젠테이션이 있습니다. 첫 번째 비디오는 http://www.pgcon.org/2015/schedule/events/829.en.html 에서 구할 수 있고, 두 번째 비디오는 https://www.youtube 에서 볼 수 있습니다. com / watch? v = L8nErzxPJjQ
EXPLAIN (ANALYZE, BUFFERS) outputs. But, if I understand things correctly, some of the hint bits (at least
* COMMITTED` 및*INVALID
) 에서 더러워진 일부 페이지를 설명 하여COMMIT
또는 로 직접 설정할 수 있습니다ROLLBACK
.