Optimizing Materialized View Refresh to Minimize Locks in PostgreSQL
This article explores an enhancement to a dual‑DB PostgreSQL setup that dramatically reduces lock contention by selectively using concurrent refresh on high‑dependency materialized views. We’ve also added architecture diagrams to clarify data flows and lock behavior.
1. Architectural Overview
Trans DB: Runs non‑concurrent refreshes on most MVs, leveraging local raw data where compute is fastest.
Cache DB: Defines FDW-based foreign tables on Trans DB’s MVs and refreshes its own MVs concurrently, ensuring UI queries never block.
2. Problem: Lock Explosion on High‑Dependency MV
When mvw_test
(which depends on ~90% of other MVs) refreshed non‑concurrently, PostgreSQL acquires exclusive locks on each base relation. This causes:
Consequences:
Widespread Contention: All other MVs and queries stall.
Connection Saturation: Waiting sessions accumulate, exhausting slots.
Memory Spikes: Queued locks consume RAM → OOM errors.
Service Restarts: Cache DBOOM crashes, interrupting UI.
3. Solution: Selective Concurrent Refresh
Only the high‑impact MV uses CONCURRENTLY
, dramatically reducing locking scope:
-- Step 1: Ensure unique index CREATE UNIQUE INDEX CONCURRENTLY idx_test_pk ON mvw_test (key_column); -- Step 2: Refresh concurrently REFRESH MATERIALIZED VIEW CONCURRENTLY mvw_test;
Why Concurrent?
Lightweight Locks: Shared locks only on the MV itself, not on its dependencies.
No Blocking: Other MVs and queries continue normally.
Scheduling:
- Run at off‑peak, e.g., 3 AM daily via cron:
0 3 * * * psql -c "REFRESH MATERIALIZED VIEW CONCURRENTLY mvw_test;"
- Monitor with:
SELECT pid, relation::regclass, mode, granted FROM pg_locks WHERE relation::regclass = 'mvw_test';
4. Before vs. After: Lock Footprint
5. Benefits
Reduced Contention: Dependencies remain unlocked.
Stable Connections: Fewer waiters preserve slots.
Better Memory Profile: No queue‑induced OOMs.
Higher Availability: Cache DB stays up, UI never blocks.
Focused Overhead: Only one MV pays the cost of concurrency.
6. Recommendations & Extensions
Index Health: Periodically
REINDEX CONCURRENTLY
the unique index.Expand to Others: Identify other MVs with >50% dependencies for similar treatment.
Advanced: Consider incremental MVs (
REFRESH MATERIALIZED VIEW ... WITH DATA
) or logical replicas for ultra‑low‑lock reporting.
Top comments (0)