나는 테이블 VACUUM
에서 SELECT
ing 행 VACUUM
이 나중에 작업을 줄여야하는 것처럼 보이는 예기치 않은 동작을 발견 했습니다.
테스트 데이터
참고 : autovacuum은 비활성화되어 있습니다
CREATE TABLE numbers (num bigint);
ALTER TABLE numbers SET (
autovacuum_enabled = 'f',
toast.autovacuum_enabled = 'f'
);
INSERT INTO numbers SELECT generate_series(1, 5000);
시험 1
이제 모든 행에서 업데이트를 실행합니다.
UPDATE numbers SET num = 0;
그리고 우리는 실행할 때 VACUUM (VERBOSE) numbers;
우리가 얻을,
INFO: vacuuming "public.numbers"
INFO: "numbers": removed 5000 row versions in 23 pages
INFO: "numbers": found 5000 removable, 5000 nonremovable row versions in 45 out of 45 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 6585
There were 0 unused item pointers.
시험판 2
이제 우리는 다른 것을 발행 UPDATE
하지만 이번에는 SELECT
나중에 추가합니다 .
UPDATE numbers SET num = 1;
SELECT * FROM numbers;
그리고 우리는 실행할 때 VACUUM (VERBOSE) numbers;
우리가 얻을,
INFO: vacuuming "public.numbers"
INFO: "numbers": removed 56 row versions in 22 pages
INFO: "numbers": found 56 removable, 5000 nonremovable row versions in 45 out of 45 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 6586
There were 56 unused item pointers.
여기서 정확히 무슨 일이 일어나고 있습니까? SELECT
방문한 페이지에서 죽은 튜플을 제거한 후에 두 번째 버전을 실행하는 이유는 무엇 VACUUM
입니까?
macOS 10.14.5에서 Postgres 11.3을 실행하고 있습니다.
답변
/ r / PostgreSQL의이 게시물 부터 Laurenz Albe 의 답변에 이르기까지 힙 전용 튜플 (HOT) 업데이트가 책임이있는 것 같습니다. HOT 업데이트 설명 에서src/backend/access/heap/README.HOT
효과적으로, 페이지가 거의 가득 차고 (<10 % 사용 가능) 버퍼 정리 잠금을 확보 할 수있을 때 튜플 검색 중에 공간 회수가 발생합니다. 이 수단
UPDATE
,DELETE
및SELECT
CAN 트리거 공간 간척하지만, 종종 동안INSERT ... VALUES
이 행을 검색하지 않기 때문에.
따옴표는 원래 답변에 없지만 나머지는 따옴표입니다.
이 이론을지지하거나 반박하려면 다음 쿼리를 실행하십시오.
SELECT n_tup_upd, n_tup_hot_upd FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 'TABLE_NAME';
경우
n_tup_hot_upd
0보다 큰 경우, 우리는 사건을 가지고있다.
답변
인덱싱되지 않은 테이블의 특수한 경우 예, SELECT는 VACUUM과 동일한 작업을 수행 할 수 있습니다 (사후 행 제거에 관한 한).