PostgreSQL
강의

#5 - PostgreSQL Heap Page(8KB)와 CTID - 이해가 쉬운 설명

중년개발자
중년개발자

@loxo

17일 전

25

PostgreSQL Heap Page(8KB)와 CTID

PostgreSQL를 처음 배우면 CTID가 뭐지? 왜 페이지가 8KB야?에서 많이 막힙니다.
이 문서는 DB 내부 동작을 모른다는 전제에서, 눈으로 그려지듯 이해하도록 설명합니다.


1️⃣ PostgreSQL Heap이란?

PostgreSQL에서 테이블은 곧 Heap입니다.

  • Heap = 정렬되지 않은 데이터 덩어리
  • INSERT 순서대로 막 쌓임
  • 인덱스가 없으면 전부 Heap Scan

📌 즉, PostgreSQL은 기본적으로 "책장 없이 바닥에 쌓아둔 종이더미" 같은 구조입니다.


2️⃣ 왜 Page 크기는 8KB일까?

PostgreSQL의 기본 Page(Block) 크기:

8 KB (8192 bytes)

이유 요약

  • 디스크 I/O 최소 단위
  • OS 메모리 페이지와 궁합이 좋음
  • 너무 크면 낭비, 너무 작으면 I/O 폭증

👉 "가성비 최적" 사이즈


3️⃣ Heap Page 내부 구조 (핵심)

하나의 Heap Page(8KB)는 이렇게 생겼습니다.

구성 요소 설명

영역역할
Page Header페이지 메타 정보 (LSN, checksum 등)
Item Pointer각 row의 위치 정보
Free Space아직 안 쓴 공간
Tuple Data실제 row 데이터

📌 중요 포인트

Row 데이터는 뒤에서부터, 포인터는 앞에서부터 자람


4️⃣ CTID란 무엇인가?

CTID = (page_number, tuple_index)

ctid = system column name for Tuple Identifier

예시:

ctid = (12, 3)

의미:

  • 12번째 페이지
  • 그 페이지의 3번째 row

📌 CTID는 "주소" 입니다. (물리적 위치)


5️⃣ Heap Page와 CTID 관계 (그림으로 이해)

👉 CTID는 **"12번 페이지의 3번 슬롯"**을 정확히 가리킵니다.


6️⃣ SELECT * FROM table 할 때 내부에서 벌어지는 일

  • 인덱스 없음 → 모든 Page 순회
  • 각 Tuple의 위치는 CTID 기준

6️⃣-1️⃣ 인덱스가 있을 때 SELECT 흐름 (Index Scan)

  • 인덱스는 값 → CTID 만 알고 있음
  • 실제 Row 데이터는 항상 Heap에서 조회
  • 불필요한 Page Scan 없음 → 성능 급상승

📌 핵심 공식

Index Scan = Index Lookup → CTID → Heap Fetch


7️⃣ UPDATE 시 CTID가 바뀌는 이유 (매우 중요)

PostgreSQL은 In-place update를 하지 않습니다.

왜 이렇게 할까?

  • MVCC 때문
  • 트랜잭션 격리 보장

📌 결과

  • UPDATE 후 CTID 변경됨
  • 인덱스는 새 CTID를 가리킴

8️⃣ DELETE 하면 바로 지워질까?

❌ 아님

  • DELETE = "죽음 표시"
  • 실제 공간 회수 = VACUUM

9️⃣ 초보자가 반드시 기억해야 할 핵심 5줄 요약

  1. PostgreSQL 테이블 = Heap
  2. Heap은 8KB Page 단위
  3. CTID는 (페이지, 슬롯)
  4. UPDATE → CTID 변경
  5. VACUUM이 없으면 Heap은 비대해짐

🔚 한 줄 비유로 마무리

PostgreSQL Heap은 이삿짐 박스(8KB)들이 쌓인 창고이고, CTID는 박스 번호 + 물건 위치다.

이 개념이 잡히면,

  • 인덱스 동작
  • VACUUM
  • HOT UPDATE
  • 성능 튜닝

이 전부 자연스럽게 연결됩니다 👍

목차

#PostgreSQL#Heap Page#CTID#DB 내부 구조#Block Size

댓글 0

Ctrl + Enter를 눌러 등록할 수 있습니다
※ AI 다듬기는 내용을 정제하는 보조 기능이며, 최종 내용은 사용자가 확인해야 합니다.