생계/PostgreSQL2025. 7. 27. 14:23
반응형

pg_repack 를 사용하면 테이블 재구축을 할수있어 vacuum full 을 대체할수 있다. 

vacuum full  은 작업시간동안 대상 테이블의 lock 을 잡아 dml 은 물론 조회까지 불가하다.

반면 pg_repack 은 트리거와 로그테이블을 사용하여 테이블 전체를 복사하는데 잠깐 동안만 lock 을 잡게 된다. 

 

다만 별도의 리눅스 서버에 pg_repack 클라이언트 설치가 필요하고, 이곳에서 명령을 실행해야 한다. 

AWS EC2 서버에 pg_repack 클라이언트를 설치해보자. 

** 참고로 aws free tier 는 스토리지를 20GB 까지 사용할수 있고, 그 이상부터는 유료 과금이 된다. 

postgresql RDS 가 20GB 를 필요로 하니, 추가로 ec2 서버를 생성한다면 유료 과금이 된다.

짧게 테스트용으로만 설치하고 바로 삭제하자. 

 

테스트환경 구축하기

1. postgresql RDS 설치 

postgresql RDS 설치는 이전에 작성한 글을 참고하자.

[AWS] PostreSQL RDS 생성 하기

 

2. EC2 설치 (pg_repack client)

ec2 리눅스 서버 설치도 이전에 작성한 글을 참고하자.

아마존 AWS EC2 생성하기 프리티어

설치가 완료되었으면 ec2 -> RDS 로 접속이 가능하도록 방화벽 작업을 해줘야 한다. 

 

psql 은 설치하지 않아도 pg_repack 사용는 것에는 무방하지만 db접속이 잘 되는지 확인용도로 설치한다. 

# psql (생략가능)

sudo apt update
sudo apt install postgresql-client
sudo apt install libzstd-dev liblz4-dev zlib1g-dev libreadline-dev

psql -h dbid.xxxxxxxxx.ap-northeast-2.rds.amazonaws.com -p 5000 -U pgdba -d postgres

* 나는 기본 포트 대신 5000 을 사용하고 pgdba 라는 유저를 사용한다. 

# pg_repack 설치

설치전에 서버의 pg_repack 버전 확인이 필요하다. 

아직 (db서버에) 설치 전 이라면 아래 명령어로 extension 설치가 필요하다. 

create extension pg_repack;

나는 1.5.0 버전이 설치되어 있는데 client 도 동일하게 버전을 맞춰주자. 



wget https://api.pgxn.org/dist/pg_repack/1.5.0/pg_repack-1.5.0.zip
unzip pg_repack-1.5.0.zip
cd pg_repack-1.5.0

# PostgreSQL 버전에 맞는 컴파일 및 설치
make
sudo make install

* error 가 없이 잘 끝났다면 설치는 완료되었고 경로를 path 에 추가해 준다. 

export PATH=$PATH:/home/ubuntu/pg_repack/bin

이제 pg_repack 을 실행해준다. 

pg_repack -h dbid.xxxxxxxxx .ap-northeast-2.rds.amazonaws.com -p 5000 -U pgdba --table=t1 -k postgres

* RDS 에서 사용하려면 -k 옵션을 붙여줘야 한다. 

만약 pg_repack 의 버전이 맞지 않다면 아래처럼 업그레이드 할수 있는데, postgresql 의 버전이 이를 수용 못하면 

클라이언트를 새로 버전 맞춰서 설치해야 한다. 

ALTER EXTENSION pg_repack UPDATE TO '1.5.2'; 

or 삭제 후 새로 설치 

DROP EXTENSION pg_repack;
CREATE EXTENSION pg_repack VERSION '1.5.2';   -- 클라이언트 버전에 맞추어 변경



# pg_repack client 의 삭제 
sudo apt remove postgresql-repack

rm -rf ./pg_repack

wget https://api.pgxn.org/dist/pg_repack/1.5.0/pg_repack-1.5.0.zip
unzip pg_repack-1.5.0.zip
cd pg_repack-1.5.0

 

3. pg_repack 작업 스크립트 

동일구조 테이블을 2개 생성하여 각각에 vacuum full 과 pg_repack 을 하여 비교해보자 

-- 1. 동일 구조의 두 테이블 생성
DROP TABLE IF EXISTS t_vacu;
DROP TABLE IF EXISTS t_repk;

CREATE TABLE t_vacu (
    id SERIAL PRIMARY KEY,
    data TEXT
);

CREATE TABLE t_repk (
    id SERIAL PRIMARY KEY,
    data TEXT
);

-- 2. 동일 데이터 대량 삽입 (예: 10만 건)
INSERT INTO t_vacu (data)
SELECT md5(random()::text)
FROM generate_series(1, 100000);

INSERT INTO t_repk (data)
SELECT md5(random()::text)
FROM generate_series(1, 100000);

-- 3. 초기 상태 확인 : 테이블 크기 및 dead tuple 비율 조회
SELECT
    relname,
    pg_size_pretty(pg_relation_size(relid)) AS table_size,
    n_live_tup,
    n_dead_tup,
    ROUND((n_dead_tup::numeric / (n_live_tup + n_dead_tup)) * 100, 2) AS dead_tuple_pct
FROM pg_stat_user_tables
WHERE relname IN ('t_vacu', 't_repk');

-- 4. 일부 데이터 삭제 (예: 30% 정도)
DELETE FROM t_vacu WHERE id % 10 < 3;
DELETE FROM t_repk WHERE id % 10 < 3;

-- 5. 삭제 후 상태 다시 확인
SELECT
    relname,
    pg_size_pretty(pg_relation_size(relid)) AS table_size,
    n_live_tup,
    n_dead_tup,
    ROUND((n_dead_tup::numeric / (n_live_tup + n_dead_tup)) * 100, 2) AS dead_tuple_pct
FROM pg_stat_user_tables
WHERE relname IN ('t_vacu', 't_repk');


-- 6. VACUUM FULL,  pg_repack  적용 (t_vacu)
VACUUM FULL t_vacu;

* 아래는 pg_repack 클라이언트에서 실행한다.  
export PATH=$PATH:/home/ubuntu/pg_repack-1.5.0/bin

pg_repack -h dbid.xxxxxxxxx.ap-northeast-2.rds.amazonaws.com -p 5000 -U pgdba --table=t_repk -k postgres
 
-- 7. 적용 후 상태 재확인
SELECT
    relname,
    pg_size_pretty(pg_relation_size(relid)) AS table_size,
    n_live_tup,
    n_dead_tup,
    ROUND((n_dead_tup::numeric / (n_live_tup + n_dead_tup)) * 100, 2) AS dead_tuple_pct
FROM pg_stat_user_tables
WHERE relname IN ('t_vacu', 't_repk');

 

반응형
Posted by 돌고래트레이너