Reference · Cheat sheet

The heap & MVCC

Lesson 0001 distilled — Postgres never updates in place, and everything that follows from it. Built to print.

From lesson 0001Context: PostgreSQL current

The keystone

A table is a heap — an unordered pile of pages of tuples (row versions).

UPDATE/DELETE never overwrite. They write a new version and mark the old one expired. The old version survives until VACUUM reclaims it.

The derivation chain (memorize this)

never update in place → old versions linger as dead tuples → they occupy space → bloatVACUUM/autovacuum reclaims → space reused.

versions kept inline → readers see an old one while writers add a new one → readers don't block writers.

Indexes

Every Postgres index is secondary — stored apart from the heap, pointing into it by ctid (page, slot). There is no clustered index.

CLUSTER reorders once and is not maintained on later writes.

Visibility lives in the heap, not the index → an index scan usually visits the heap; the visibility map lets an index-only scan skip it when a page is all-visible.

Postgres vs InnoDB

AspectInnoDBPostgres
Table is…clustered B+treeunordered heap
UPDATEin placenew version
Old versionsundo login the heap
CleanuppurgeVACUUM
Clustered idxonenone

See it in 3 commands (later)

SELECT ctid,* FROM t; → note the ctid.

UPDATE t SET …; then re-select — ctid changed = new tuple.

SELECT n_dead_tup FROM pg_stat_user_tables; → 1, then VACUUM t; → 0.