Multi-Version Concurrency Control (MVCC)

College Depth 73 in the knowledge graph I know this Set as goal
Unlocks 1 downstream topic
concurrency mvcc read-consistency

Core Idea

MVCC maintains multiple versions of rows, allowing readers to access consistent snapshots without blocking writers. Each transaction sees data as of a snapshot timestamp, reducing lock contention.

How It's Best Learned

Observe that in a database with MVCC (PostgreSQL, MySQL InnoDB), read operations do not block writes and vice versa, even without explicit locking.

Common Misconceptions

MVCC still prevents write-write conflicts via locking; it only eliminates read-write blocking. Old versions are garbage-collected when no active transaction references them.

Explainer

You already understand that concurrent database access creates problems: one transaction might read data that another is in the middle of modifying, or two transactions might try to update the same row simultaneously. Traditional locking-based concurrency control solves this by making readers wait for writers and writers wait for readers, but this serialization kills throughput. Multi-Version Concurrency Control (MVCC) offers an elegant alternative: instead of forcing transactions to wait, the database keeps multiple versions of each row so that readers and writers can operate simultaneously without blocking each other.

The core mechanism works like this: when a transaction modifies a row, the database does not overwrite the existing version. Instead, it creates a new version of the row tagged with the writing transaction's ID or timestamp. The old version remains available for other transactions that started before the write. Each transaction operates against a snapshot — a consistent view of the database as it existed at the transaction's start time. When transaction T1 reads a row, the database finds the most recent version of that row that was committed before T1's snapshot timestamp. Even if transaction T2 is actively modifying that same row, T1 sees the old version and proceeds without waiting.

This means readers never block writers, and writers never block readers — a dramatic improvement over lock-based schemes where a long-running analytical query could stall all concurrent updates. However, MVCC does not eliminate all conflicts. Write-write conflicts still require coordination: if two transactions attempt to modify the same row, the second one must either wait or abort, depending on the database's conflict resolution strategy. PostgreSQL, for example, uses a "first updater wins" policy — the second transaction blocks until the first commits or rolls back, then either proceeds or aborts depending on the outcome.

The cost of maintaining multiple versions is storage overhead and garbage collection. As transactions create new versions, old versions accumulate. The database must periodically determine which old versions are no longer visible to any active transaction and reclaim their storage — a process PostgreSQL calls VACUUM and MySQL/InnoDB handles through a background purge thread. If garbage collection falls behind (for example, because a long-running transaction holds an old snapshot open), the database accumulates bloat that degrades performance. Understanding this lifecycle — version creation, snapshot visibility, and garbage collection — is essential for diagnosing performance problems in MVCC-based systems like PostgreSQL, MySQL InnoDB, and Oracle.

Practice Questions 5 questions

Prerequisite Chain

Counting to 10Counting to 20Understanding ZeroThe Number ZeroCounting to FiveOne-to-One CorrespondenceCombining Small Groups Within 5Addition Within 10Addition Within 20Two-Digit Addition Without RegroupingTwo-Digit Addition with RegroupingAddition Within 100Repeated Addition as MultiplicationMultiplication Facts Within 100Division as Equal SharingDivision as Grouping (Measurement Division)Division: Grouping (Repeated Subtraction) ModelDivision: Fair Sharing ModelDivision as Equal SharingDivision as GroupingBasic Division FactsDivision Facts Within 100Two-Digit by One-Digit DivisionDivision with RemaindersRemainders and Quotients in DivisionDivision Word ProblemsIntroduction to Long DivisionFactors and MultiplesPrime and Composite NumbersEquivalent FractionsRelating Fractions and DecimalsDecimal Place ValueReading and Writing DecimalsComparing and Ordering DecimalsAdding and Subtracting DecimalsMultiplying DecimalsDividing DecimalsDividing FractionsMixed Number ArithmeticOrder of OperationsOperators and ExpressionsArithmetic Operators and Operator PrecedenceComparison Operators and Boolean TestsLogical Operators and Boolean AlgebraBoolean Algebra and Fundamental LawsCombinational Circuit DesignFlip-Flops and LatchesBinary Counters: Design and AnalysisBinary ArithmeticFixed-Point Number RepresentationTwo's Complement RepresentationOverflow and Underflow DetectionBinary Adders: Half-Adders and Full-AddersFull Adder and Carry PropagationCarry Lookahead Adder DesignHalf Adder Circuit DesignMultiplication Circuit DesignSequential Circuit DesignRegisters and Register FilesInstruction Set Architecture (ISA)Kernel Architecture and OS StructureSystem Calls and User/Kernel ModeProcesses and the Process Control BlockProcess Creation: fork() and exec()Process Termination and Resource CleanupProcess States and State TransitionsThreads and ConcurrencyThe Critical Section Problem and Race ConditionsMutual Exclusion and LocksConcurrency Control in DatabasesLost Update Problem: Overwriting Concurrent WritesOptimistic Concurrency Control: Version NumbersPessimistic Concurrency Control: LockingMulti-Version Concurrency Control (MVCC)

Longest path: 74 steps · 278 total prerequisite topics

Prerequisites (3)

Leads To (1)