liveBook · Manning

Multi-version concurrency control

As explained in PostgreSQL Mistakes and How to Avoid Them

Multi-Version Concurrency Control is a database concurrency technique that maintains multiple row versions to support consistent reads alongside concurrent writes.

Multi-Version Concurrency Control (MVCC) is PostgreSQL’s concurrency model for keeping reads and writes moving at the same time. Rather than making readers wait on writers, PostgreSQL creates a new tuple version for each write. A transaction reads from a point-in-time snapshot, so it sees only tuple versions visible to that snapshot. This gives consistent reads: writing does not block reading, and reading does not block writing. section 6.4.1

Figure 6.2 PostgreSQL transaction timeline showing linear sequence of XIDs
figure

The transaction timeline helps distinguish transaction order from visibility: a transaction may see neighboring XIDs only when their work committed before its snapshot permits it. section 6.4.1

Visibility is tracked with transaction IDs (XIDs) and timestamps. A snapshot records the earliest still-active transaction, the first unassigned transaction, and active transactions; PostgreSQL uses that information to decide which tuple versions a transaction can see. Inspect the current snapshot with pg_current_snapshot() when investigating snapshot behavior. section 6.4.1

Updates create dead row versions

An UPDATE is effectively an insert plus a delete: the new tuple is written to the table heap, while the prior version becomes deletable. Tuple metadata includes xmin, the inserting XID, and xmax when a deleting XID exists. Those retained versions are the cost of MVCC and must eventually be handled by vacuuming. section 6.6.1

Treat these operational symptoms as MVCC consequences, not reasons to disable maintenance:

  • Avoid excessive open sessions. Snapshot creation must examine open connections, so its computational cost grows with the total connection count; apparently idle sessions still consume resources. section 6.4.2
  • Do not leave sessions idle in transaction or run needlessly long transactions. They can block or postpone autovacuum, causing bloat, delays, and potentially more serious failures. section 6.13
  • Use a connection pooler such as PgBouncer in Transaction Mode when many application connections cannot be avoided. section 6.13
  • Keep autovacuum effective. High transaction rates can outpace its work, while disabling or weakening it accumulates bloat, degrades statistics, and risks forced anti-wraparound work. section 6.13

XIDs are unsigned 32-bit values, so PostgreSQL treats their space as circular. A tuple more than roughly 2.15 billion XIDs in the past can become ambiguous—apparently from the future—and create a wraparound hazard. VACUUM prevents this by freezing sufficiently old tuples. If prevention falls behind, PostgreSQL runs noninterruptible anti-wraparound autovacuum, which can slow the system severely. section 6.6.1

MVCC also changes disk-space expectations. Deleting data needs WAL space, leaves dead rows, and does not immediately return space to the operating system. VACUUM marks space reusable inside table files; VACUUM FULL can return it to the OS but rewrites the table under an ACCESS EXCLUSIVE lock. Deleting rows during a disk emergency is therefore often a poor immediate remedy. section 7.1

How PostgreSQL Mistakes and How to Avoid Them covers it

How deep it goes
Explains tuple visibility, snapshot contents, XID metadata, wraparound, freezing, and operational consequences without exhaustive implementation detail.
Examples
Uses transaction 1000’s visibility of transactions 999 and 1001, tuple xmin/xmax metadata, and disk-pressure deletion behavior.
What it assumes
Assumes familiarity with PostgreSQL transactions and database sessions while defining snapshots, XIDs, and tuple-version visibility.
What you can do after
Operate/configure PostgreSQL by limiting excess sessions, preserving autovacuum, and anticipating version-retention and disk-reclamation costs.
How it connects
Connects MVCC to transactions, snapshot isolation, transaction IDs, autovacuum, VACUUM, WAL, and connection pooling.

Also explained in

Compare how 4 books explain multi-version concurrency control →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of PostgreSQL Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.