How MVCC Works Across Databases

Multi-Version Concurrency Control explained across PostgreSQL, MySQL/InnoDB, Oracle, and SQL Server

📋 Table of Contents

Introduction

Multi-Version Concurrency Control (MVCC) is the cornerstone of how modern databases handle concurrent transactions while maintaining ACID properties. Different databases implement MVCC in fundamentally different ways, each with its own trade-offs.

PostgreSQL MySQL/InnoDB Oracle SQL Server

PostgreSQL: Heap Tuples with xmin/xmax

PostgreSQL stores each row version as a heap tuple with visibility metadata in the tuple header:

PostgreSQL MVCC Example:
BEGIN;
-- Transaction updates create new tuple
UPDATE accounts SET balance = balance + 100 WHERE id = 1;
-- Old tuple marked with xmax, new tuple with xmin

-- Another session reading sees old version
SELECT balance FROM accounts WHERE id = 1;

Key PostgreSQL MVCC Features:

MySQL/InnoDB: Rollback Segments

InnoDB stores before-images in undo logs organized into rollback segments:

MySQL InnoDB MVCC:
START TRANSACTION;
-- Before-image stored in undo log
UPDATE accounts SET balance = balance + 100 WHERE id = 1;

-- Other transactions read from undo log
-- Each transaction has its own read view

Key InnoDB MVCC Features:

Oracle: System Change Number (SCN)

Oracle uses System Change Number (SCN) and undo segments for consistent reads:

Oracle MVCC:
BEGIN
-- Oracle assigns SCN to each change
UPDATE accounts SET balance = balance + 100 WHERE id = 1;

-- Other transactions see consistent read using undo
-- Supports Flashback queries via undo retention

Key Oracle MVCC Features:

SQL Server: Version Store

SQL Server uses a version store in tempdb for row versioning:

SQL Server Version Store:
-- Enable snapshot isolation
ALTER DATABASE MyDB SET ALLOW_SNAPSHOT_ISOLATION ON;

-- Row versions stored in tempdb
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
SELECT balance FROM accounts WHERE id = 1;

Feature Comparison

Feature PostgreSQL MySQL/InnoDB Oracle SQL Server
Version Storage Heap tuples Undo logs Undo segments Version store (tempdb)
Visibility Info xmin/xmax in tuple Read view per transaction SCN-based Row versioning
Space Reclamation VACUUM Purge thread Automatic (with retention) Version cleanup
Hot Updates HOT updates Change buffer In-place with undo N/A
Performance Impact VACUUM overhead Undo log growth Undo management Tempdb contention

Performance Implications

Memory Usage Comparison:

Concurrency Patterns:

When to Choose Which

Choose PostgreSQL when:

Choose MySQL/InnoDB when:

Choose Oracle when:

Interactive Demo

🐳 Docker MVCC Demo:
# Clone demo repository
git clone https://github.com/oracleai/mvcc-demo.git
cd mvcc-demo

# Start databases
docker-compose up -d postgres mysql oracle

# Run concurrent transaction test
./scripts/test_mvcc.sh

# View results
cat results/mvcc_comparison.json

🚀 Run Demo Now

🔜 Coming Next: Foreign Keys

Next article: When to use foreign keys across databases, performance implications, and implementation differences.

← Back to Articles