Postgresql Vacuum 0 0 4,724

by 지현명 [PostgreSQL 노하우/팁/자료] Vacuum AutoVacuum [2017.09.15 17:08:39]


Vacuum#2.ods (20,754Bytes)
Vacuum.png (27,353Bytes)

Postgresql에서 Vacuum은 중요하고 AutoVacuum은 2가지 type으로 구분 할 수 있습니다.

테이블이  Age가 Vacuum_freeze_min_age(0.5억), vacuum_freeze_table_age (1.5억) 이상 되서 실행되는 경우와,  삭제된 행수가 임계값 이상 넘었을때

(vacuum threshold >= vacuum base threshold + vacuum scale factor * number of tuples) 실행 되는 경우로  나눌  수 있습니다.

그러나, 이 2개는가 처리되는 프로세스가 다릅니다. 크게는 공간을 재활용하는것과 못하는 것으로 구분 할 수 있습니다.

공식 메뉴얼에는 이 2개의 AutoVacuum을 구분하지 않아 제가 임의로 t_infomask 9bit를 1로만 하는 경우를 Semi Vacuum이라 명칭했습니다.


/*
Semi-Vacuum
특징 : 공간 재활용 못함, t_infomask의 9 bit를 1로 변경
발생 시점 :
Table Age >= Vacuum_freeze_min_age(0.5억)

만약 Vacuum_freeze_min_age(0.5억) 이내에 Manual Vacuum을 실행하면
vacuum_freeze_table_age (1.5억) 에서 실행된다.

*/

drop table t_test;


CREATE TABLE t_test (
i1 int,
v1 char(1000)
);


insert into t_test
SELECT i,'abcd'
FROM generate_series(1, 250) a(i);

SELECT pg_relation_size('t_test');
--294912

--AutoVacuum되지 않게 20% 이내로 삭제
DELETE from t_test
where i1  <= 45;

SELECT pg_relation_size('t_test');
--294912

SELECT COUNT(*) FROM T_TEST

select dblink_connect('myconn', 'dbname=postgres port=5432 user=postgres password=0152');

--Vacuum_freeze_min_age(0.5억) 이상 트랜잭션 발생
--테스트로 50000 설정
select loop_insert_txid_bump_t(1, 50000);

--Table Age
select relname as name, age(relfrozenxid)
from pg_class
where relname = 't_test';


--1분 기다림.

--Vacuum모니터링
--이 경우는 pg_stat_all_tables의 last_autovacuum 에 AutoVacuum이 반영되지 않고,
-- t_infomask의 9번째 bit가 1로 변경 됐는지 확인해야 한다.
SELECT last_autovacuum FROM pg_stat_all_tables
WHERE RELNAME = 't_test'

--AutoVacuum발생함.
--트랜잭션이 > Vacuum_freeze_min_age 되어

--page 수량, relpage : 885
select relpages from  pg_class
where relname ='t_test'

--Scan해야 할 Page : 조회된 (relpage -1)
--배열 0부터 시작 하기 때문에 relpages에서 하나를 빼준다.

--9번째 bit 1로 변경 됐는지 확인
select
    substr(cast(b.t_infomask::bit(16) as text), 7, 1) Freeze_flag,
    substr(cast(b.t_infomask::bit(16) as text), 8, 1) Vacuum_flag,
    count(*)
from (select i from generate_series(0,35) a(i)) a,
LATERAL(select * from heap_page_items(get_raw_page('t_test', a.i))) b
group by
    substr(CAST(b.t_infomask::bit(16) as text),7,1) --Freeze, 10번째 Bit
,    substr(CAST(b.t_infomask::bit(16) as text),8,1); --Vacuum, 9번째 Bit


--삭제한 만큼 입력
insert into t_test
SELECT i,'abcd'
FROM generate_series(1, 45) a(i);


--공간 재활용 못함.
SELECT pg_relation_size('t_test');
--352256


/*
AutoVacuum
특징 : 공간 재활용, t_infomask의 9 bit를 1로 변경
발생 시점 :
vacuum threshold >= vacuum base threshold + vacuum scale factor * number of tuples
*/


drop table t_test;


CREATE TABLE t_test (
i1 int,
v1 char(1000)
);


insert into t_test
SELECT i,'abcd'
FROM generate_series(1, 250) a(i);


SELECT pg_relation_size('t_test');
--294912


--AutoVacuum되게 20% 삭제
DELETE from t_test
where i1  <= 100;

select count(*) from t_test;

--1분 기다림.

--Vacuum모니터링
SELECT * FROM pg_stat_all_tables
WHERE RELNAME = 't_test'

--page 수량, relpage : 885
select relpages from  pg_class
where relname ='t_test'

--Scan해야 할 Page : 조회된 (relpage -1)
--배열 0부터 시작 하기 때문에 relpages에서 하나를 빼준다.
select
    substr(cast(b.t_infomask::bit(16) as text), 7, 1) Freeze_flag,
    substr(cast(b.t_infomask::bit(16) as text), 8, 1) Vacuum_flag,
    count(*)
from (select i from generate_series(0,35) a(i)) a,
LATERAL(select * from heap_page_items(get_raw_page('t_test', a.i))) b
group by
    substr(CAST(b.t_infomask::bit(16) as text),7,1) --Freeze, 10번째 Bit
,    substr(CAST(b.t_infomask::bit(16) as text),8,1); --Vacuum, 9번째 Bit


insert into t_test
SELECT i,'abcd'
FROM generate_series(1, 100) a(i);


--공간 재활용 가능.
SELECT pg_relation_size('t_test');
--294912
 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입