Vacuum 테스트 케이스#4
Session#2에서 관련 없는 테이블에 lock발생(아니면 오래 실행되는 조회쿼리) 상태에서
Session#1에서 실행되는 Vacuum의 처리 결과 테스트 문의..
drop table t_test;
drop table t_test2;
drop table t_test3;
drop table t_test4;
drop table t_test5;
CREATE TABLE t_test (i1 int,v1 char(100));
CREATE TABLE t_test2 (i1 int,v1 char(100));
CREATE TABLE t_test3 (i1 int,v1 char(100));
CREATE TABLE t_test4 (i1 int,v1 char(100));
CREATE TABLE t_test5 (i1 int,v1 char(100));
insert into t_test SELECT i,'abcd' FROM generate_series(1, 100000) a(i);
insert into t_test2 SELECT i,'abcd' FROM generate_series(1, 100000) a(i);
insert into t_test3 SELECT i,'abcd' FROM generate_series(1, 100000) a(i);
insert into t_test4 SELECT i,'abcd' FROM generate_series(1, 100000) a(i);
insert into t_test5 SELECT i,'abcd' FROM generate_series(1, 100000) a(i);
--다른 Session#2에서 현재 session과 관련 없는 테이블에 lock발생
--lock이 아니더라도 오래 실해되는 select도 포함
--Session#2
begin;
select * from employee
where emp_id = 1
for update;
--다른 세션의 lock확인
select b.relname,a.locktype,a.pid,a.mode,a.granted
from pg_locks a,pg_class b
where a.relation=b.oid
order by pid;
SELECT * FROM employee AS a, pgrowlocks('employee') AS p
WHERE p.locked_row = a.ctid;
--Vacuum 모니터링 : null
select last_vacuum from pg_stat_all_tables
WHERE RELNAME = 't_test4'
--1개 row삭제 (AutoVacuum작도 안되게 하고 페이지 열어서 확인하기 쉽게 하나만 삭제)
delete from t_test4 where i1 = 1;
--Vacuum 실행 (현재 다른 session#2에 관련 없는 테이블 lock걸려 있음)
vacuum ( verbose) t_test4;
정보: "public.t_test4" 청소 중
정보: "t_test4": 지울 수 있는 자료 0개, 지울 수 없는 자료 100000개를 1725/1725개 페이지에서 찾았음
DETAIL: 1개의 죽은 로우 버전을 아직 지울 수 없습니다. <- Vacuum실패
0개의 사용되지 않은 아이템 포인터가 있습니다.
0 페이지를 버퍼 핀닝으로 건너 뛰었습니다.
--Vacuum 성공하지 못했는데 pg_stat_all_tables에는
--정상으로 처리 됐다고 반영됨.
-- last_vacuum에 작업시간 업데이트 됨...<-실패했는데 왜 성공했다고 기록을 하고 있는걸까?
-- pg_stat_all_tables.last_vacuum으로 모니터링 하고 있었는데 믿으면 안될듯.
select last_vacuum, last_autovacuum from pg_stat_all_tables
WHERE RELNAME = 't_test4'
--그렇다면 실제 Vacuum 반영 됐는지 확인 페이지 열어서 확인
--정상 vacuum 하기 전 상태로 되어 있음..t_xmin, t_xmax..t_infomask등 컬럼에 null값으로 되어야 하나 값 들어가 있음.
--t_data에도 데이터 들어가 있음. (Vacuum 적용 안된 것임)
SELECT * FROM heap_page_items (get_raw_page ( 't_test4', 0));
--Session#2 Lock 종료 후 몇분이 지나서 다시 확인해도 Vacuum반영 안됨.
--다시강제로 Vacuum 실행(다른 session에서 lock이 없는 상태에서..)
vacuum ( verbose) t_test4;
정보: "public.t_test4" 청소 중
정보: "t_test4": 1개의 행 버전을 1개 페이지에서 삭제했습니다.
정보: "t_test4": 지울 수 있는 자료 1개, 지울 수 없는 자료 65개를 2/1725개 페이지에서 찾았음
DETAIL: 0개의 죽은 로우 버전을 아직 지울 수 없습니다.
--페이지 열어서 확인해 보면 이제야 정상으로 Vacuum실행되어 적용됨.
--.t_xmin, t_xmax..t_infomask등 컬럼에 null값에 전부 null로 되어 있고 t_data에도 데이터 없음. <-정상 Vacuum적용된 것임...
SELECT * FROM heap_page_items (get_raw_page ( 't_test4', 0));
다른 session에서 다른 table에 lock발생 된 이후
현재 session에서 vacuum은 반영되지 않습니다.
AutoVacuum, Vacuum, Vacuum Full 모든 Vacuum은 작동안함.
아래 테이블에 정상으로 실행됐다고 되어 있지만
select last_vacuum from pg_stat_all_tables
WHERE RELNAME = 't_test4'
페이지 열어 보면 실제로는 반영되어 있지 않다.
SELECT * FROM heap_page_items (get_raw_page ( 't_test4', 0));
verbose옵션을 기록으로 남겨서 리턴되는 메시지를 반듯이 확인해야 한다.
vacuum ( verbose) t_test4;
--질문사항--
Vacuum이 성공하지도 않았는데 왜 Postgresql은
pg_stat_all_tables.last_vacuum 컬럼에 성공했다고 반영할까요? 이거로 모니터링 하고 있었는데.....
사용자는 verbose 옵션으로 리턴되는 결과를 별도로 저장해서
확인하는 방법 말고 다른 방법이 있을까요?
|