📢 본 문서에서는 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의 동작 과정에 대해 다루도록 하겠습니다.
기획 및 글 | 기술기획팀
이미지 제작 | 디자인그룹 이민석
'엑셈 경쟁력 > DB 인사이드' 카테고리의 다른 글
DB 인사이드 | PostgreSQL Vacuum - 6. Autovacuum (4) | 2022.04.29 |
---|---|
DB 인사이드 | PostgreSQL Vacuum - 5. Manual Vacuum (0) | 2022.04.29 |
DB 인사이드 | PostgreSQL Vacuum - 3. Age (2) | 2022.04.29 |
DB 인사이드 | PostgreSQL Vacuum - 2. Transaction ID (0) | 2022.04.29 |
DB 인사이드 | PostgreSQL Vacuum - 1. MVCC (2) | 2022.04.29 |
댓글