Course contentsShow
← Databases & SQL
Lesson 1911 of 1,95318. Application Integration PatternsFree lesson

Handling Large Data Migrations

Perform background data migrations on tables with millions of rows to avoid table-locking issues.

In this lesson, you will learn how to execute large-scale data migrations on tables with millions of rows without triggering debilitating table-level locks.

When performing migrations—such as adding a new column with a default value or transforming existing data—executing a single ALTER TABLE or UPDATE statement on a massive table is dangerous. In many relational databases, this can trigger a metadata or write lock that halts all incoming application traffic, leading to site-wide outages.

The Chunking Strategy

To avoid locking, we break the migration into small, manageable batches. Instead of a single transaction, we process rows in increments (e.g., 1,000 to 5,000 rows at a time). By processing in chunks, you ensure that any necessary locks are held for milliseconds rather than minutes.

Consider this pseudo-code for a background migration:

-- Step 1: Identify boundaries
SELECT MIN(id), MAX(id) FROM users;

-- Step 2: Process in small batches
-- Run this in a loop in your background worker
UPDATE users 
SET status = 'active' 
WHERE id >= ? AND id < ? 
  AND status IS NULL;

Implementing "Sleep" and Throttle

While chunking prevents long-held locks, it can still spike CPU or I/O usage. A best practice is to introduce a short sleep period between batches. This "throttling" allows the database engine to perform autovacuuming or internal housekeeping, ensuring that your background migration doesn't compete with your primary application traffic for resources.

Why Not Large Transactions?

If you wrap a migration of millions of rows in a single BEGIN and COMMIT, the database must maintain a massive undo/redo log. If the transaction fails, the rollback time can be catastrophic. By using short-lived transactions, each batch commits independently. If a batch fails, you only need to retry that specific segment rather than the entire operation.

When integrating these into your architecture, ensure your migrations are idempotent, meaning they can be run multiple times safely without producing unintended side effects if a background job restarts.

Key Takeaway: Never run a single, massive DDL or DML operation on a high-traffic table; always use batching with controlled throttling to keep database locks brief and system performance stable.