본문 바로가기
엑셈 경쟁력/DB 인사이드

DB 인사이드 | PostgreSQL Vacuum - 4. Visibility Map

by EXEM 2022. 4. 29.

 

 

📢 본 문서에서는 Visibility Map (이하 VM)이라는 메타 파일에 대한 내용을 다룹니다. 우선 Vacuum의 기준정보로 활용하는 ①VM File이란 무엇인지 알아보고, ②사용자 조작에 따라 어떻게 변경되며, 어떻게 관찰할 수 있는지 알아보도록 하겠습니다.

Visibility Map

VM File이란?

VM이란 Heap Relation(*테이블)을 구성하는 개별 페이지의 상태를 2개의 Bit값으로 표현하는 메타정보 파일이며 페이지가 포함하는 Tuple(Row)들의 상태 정보를 축약해서 담고 있습니다.

VM 파일은 Relation OID에 해당하는 숫자에 접미어 "_vm"을 붙인 형태로 관리되며 사용자가 VACUUM 또는 VACUUM FREEZE와 같은 명시적인 Vacuum작업을 수행하거나 Autovacuum Launcher Process에 의해 Autovacuum 이 수행될 때에도 갱신됩니다.

📌 PostgreSQL에서 Relation과 Page는 각각 Table, Block을 의미합니다

VM이 관리하는 정보

VM은 PostgreSQL 9.6 이전 버전까지 Data 페이지 당 1 Bit의 Flag 값을 통해 ALL_VISIBLE 정보만을 표현했었습니다. 하지만 이후 버전부터 성능 향상을 목적으로 페이지 당 2 Bit로 확장하여 ALL_FROZEN 정보까지 표현하고 있습니다. 각 Bit들이 나타내는 의미는 아래와 같습니다.

1st Bit : ALL_VISIBLE

페이지에 포함된 Row가 모든 Transaction에 보이는 상태인지 여부 (Boolean)를 나타내며, Dead Tuple(Row)의 존재 여부를 알 수 있습니다.

이때, ALL_VISIBLE=1(True)인 경우라면 해당 페이지의 모든 Row가 Visible 한상태로, Dead Tuple이 없는 상태를 의미하지만, 0(False)인 경우라면 Dead Tuple이 존재하거나, 아직 Vacuum이 수행되지 않아 모르는 상태까지 포함됩니다.

📌 PostgreSQL에서 Row(Tuple)은 Live 상태와 Dead 상태로 나뉘며, Update/Delete등에 의해 더 이상 참조되지 않은 Tuple을 Dead Tuple이라 부릅니다.

2nd Bit : ALL_FROZEN

ALL_VISIBLE 값이 True인 경우에만 해당사항이 있으며, 페이지에 포함된 모든 Row가 Freeze 되었는지 여부 (Boolean)를 표현합니다.

📌 Freeze란 Frozen XID라는 특수한 XID를 부여하는 작업을 말합니다.

 

2 Bit값으로 이루어진 VM은 다음과 같은 목적으로 사용됩니다.

  • VACUUM Performance : Vacuum수행 시 ALL_VISIBLE 값이 False인 페이지만 대상으로 하기 때문에 불필요한 페이지에 대한 접근을 줄임으로써 Vacuum성능 향상
  • Freezing Performance : Transaction ID Wraparound를 피하기 위해 Row들을 Freezing 하는 작업의 경우 ALL_FROZEN 값이 True 인 페이지를 Skip 하므로 작업 시간이 단축됨
  • Query Performance : Index Only Scan시 (Covering Index) 대상 페이지의 ALL_VISIBLE 값이 True 인 경우 Table Look-up을 피할 수 있으므로 SQL의 성능 향상
📌 안타깝게도 PostgreSQL에서 Index Only Scan을 유도하기 위한 적절한 구성을 하였더라도 Table Look-up이 발생할 수 있습니다. 이는 읽어야 할, 혹은 읽지 말아야 할 Row인지를 판단할 정보가 Index 자체에 존재하지 않기 때문입니다. PostgreSQL에서는 이러한 문제를 피하기 위해 SQL 수행 시점에 VM의 ALL_VISIBLE 값을 확인하여 Table Look-up여부를 결정하게 됩니다.

 

VM의 변화와 관찰

pg_visibility

VM의 2 Bit값은 pg_visibility라는 Extension을 통해 확인할 수 있습니다. pg_visibility('relation name') 형태로 사용이 가능합니다.

create table test_vm (c integer) ;

insert into test_vm select generate_series(1,1001) as c;

SELECT blkno, all_visible, all_frozen FROM pg_visibility('test_vm');
 blkno | all_visible | all_frozen |
-------+-------------+------------+
     0 | f           | f          |
     1 | f           | f          |
     2 | f           | f          |
     3 | f           | f          |
     4 | f           | f          |
(5 rows)

-- Freezing 작업 수행

vacuum freeze test_vm

SELECT blkno, all_visible, all_frozen FROM pg_visibility('test_vm');
 blkno | all_visible | all_frozen |
-------+-------------+------------+
     0 | t           | t          |
     1 | t           | t          |
     2 | t           | t          |
     3 | t           | t          |
     4 | t           | t          |
(5 rows)

VM의 변화

pg_visibility를 통해 관찰 가능한 VM의 2 Bit값은 DML 및 Vacuum 관련 작업 시 아래 그림과 같이 변화하며, 아래와 같은 특징을 갖습니다.

  • Vacuum 관련 작업을 수행하지 않은 최초 생성된 페이지의 VM 값은 [0,0]입니다
  • Vacuum 관련 작업을 수행한 이후 페이지의 VM 값은 [1,0] 또는 [1,1]입니다.
  • Vacuum Freeze 작업 시 이전 상태에 관계없이 [1,1]의 VM 상태가 됩니다.
  • DML 수행 시 이전 상태에 관계없이 [0,0]의 VM 상태가 됩니다.
  • Vacuum Full 수행 시 이전 상태에 관계없이 [0,0]의 VM 상태가 됩니다. (재구성)

 

VM을 마지막으로 Vacuum을 이해하기 위한 기반 지식들에 대한 정리를 마무리하며, 남은 문서들에서는 실제 Vacuum 및 Autovacuum의 동작 과정에 대해 다루도록 하겠습니다.

 

 

 

기획 및 글 | 기술기획팀

이미지 제작 | 디자인그룹 이민석

 

 

 

댓글