긴 락 없이 bloat된 테이블 재구성(pg_repack)
PostgreSQL유지보수명령어
-- Once per target database (the pg_repack package must be installed on the server)
CREATE EXTENSION pg_repack;
# Dry run: show what would be done
pg_repack -h localhost -U postgres -d mydb --table=public.orders --dry-run
# Rewrite the table and its indexes: 2 parallel index builds, wait at most 60 s for locks
pg_repack -h localhost -U postgres -d mydb --table=public.orders --jobs=2 --wait-timeout=60 --no-kill-backend
# Rebuild indexes only
pg_repack -h localhost -U postgres -d mydb --table=public.orders --only-indexes하는 일
백그라운드에서 테이블의 압축된 사본을 만들고, 트리거로 동시 변경을 로그 테이블에 수집하며, 마지막에 짧은 ACCESS EXCLUSIVE 락으로 테이블을 교체한다. VACUUM FULL과 달리 작업 내내 읽기/쓰기를 블로킹하지 않는다.
사용 시점
VACUUM으로 되돌릴 수 없는 심각한 bloat(pgstattuple로 확인)을 운영 시스템에서 회수해야 할 때.
주의
테이블에 PRIMARY KEY 또는 NOT NULL 컬럼의 UNIQUE 인덱스가 있어야 한다. 일시적으로 테이블과 인덱스만큼의 추가 디스크 공간이 필요하며 WAL이 많이 생성된다(replica 지연, 아카이브 양). 시작과 끝에 ACCESS EXCLUSIVE 락이 필요하다. --wait-timeout이 만료되면 기본 동작은 충돌 쿼리를 취소하고 필요하면 세션을 종료하는 것이며, --no-kill-backend는 대신 해당 테이블을 건너뛴다. 실행 중에는 대상 테이블에 DDL을 실행하지 않는다. 클라이언트와 확장 버전이 일치해야 한다. 중단되면 DROP EXTENSION pg_repack CASCADE; CREATE EXTENSION pg_repack;으로 잔여물을 정리한다.