Part 04 · PostgreSQL & Redis · 4.1.02

MVCC, isolation và VACUUM

PostgreSQL cho readers và writers cùng tiến bằng tuple versions và snapshots. Đổi lại, hệ thống phải cleanup dead versions, bảo vệ transaction IDs và xử lý anomalies ở đúng isolation level.


ACID và phạm vi guarantee

Thuộc tínhÝ nghĩa thực tế
AtomicityCác thay đổi trong transaction cùng commit hoặc rollback.
ConsistencyDatabase constraints và invariants được biểu diễn đúng được giữ qua transaction; database không tự biết mọi business rule.
IsolationQuy định concurrent transactions được quan sát/interleave tới mức nào.
DurabilityCommitted data tồn tại theo WAL, flush, storage và replication guarantees đã cấu hình.

Không nói “NoSQL không có ACID”: nhiều NoSQL systems hỗ trợ atomicity/transactions trong scope và với trade-off riêng. Luôn hỏi guarantee áp dụng cho một key, document, shard hay multi-node transaction.

Tuple versions và snapshots

INSERT và UPDATE tạo tuple versions kèm transaction-visibility metadata; UPDATE thường tạo version mới và làm version cũ hết hiệu lực. Snapshot quyết định transaction IDs nào visible. Reader thông thường không khóa writer, nhưng dead tuples vẫn chiếm storage cho tới khi VACUUM có thể reclaim chúng.

Isolation levels trong PostgreSQL

LevelSnapshot behaviorĐiểm cần nhớ
Read CommittedMỗi statement lấy snapshot mới.Hai reads trong cùng transaction có thể thấy dữ liệu khác; read-modify-write cần atomic SQL hoặc lock/version.
Repeatable ReadMột snapshot cho transaction.PostgreSQL ngăn nonrepeatable read/phantom theo snapshot isolation, nhưng write skew/serialization anomaly vẫn có thể xảy ra.
SerializableSerializable Snapshot Isolation theo dõi dependency nguy hiểm.Database có thể abort transaction để giữ serializability; application phải retry toàn transaction.
English interview answer: “I choose isolation from the anomaly that can violate the business invariant. Higher isolation improves guarantees but can increase aborts, blocking or retry work. I verify the behavior of the specific database instead of relying only on SQL-standard level names.”

Lost update và write skew

Read-modify-write có thể lost update nếu không dùng atomic conditional SQL, optimistic version hoặc row lock. Write skew xảy ra khi nhiều transactions update các rows khác nhau nhưng cùng phá invariant tổng; Serializable, explicit locks hoặc redesign constraint/data model mới bảo vệ đúng.

Retry rule: serialization failure hoặc deadlock victim yêu cầu retry toàn use case với fresh snapshot, bounded attempts, backoff/jitter và idempotency. Không retry một câu SQL giữa transaction cũ.

VACUUM và ANALYZE

VACUUM đánh dấu space của dead tuples có thể tái sử dụng, cập nhật visibility map và freeze old transaction IDs. VACUUM thường không trả file space cho OS; VACUUM FULL rewrite table và giữ lock nặng. ANALYZE cập nhật statistics để planner ước lượng cardinality.

Autovacuum và cleanup blockers

Autovacuum launcher/workers chọn tables dựa trên thresholds và scale factors. Large hoặc hot tables thường cần per-table tuning. Long-running transaction, session idle in transaction, replication slot hoặc prepared transaction có thể giữ xmin, ngăn dead tuples được cleanup.

HOT update và write amplification

Nếu indexed columns không đổi và page còn chỗ, Heap-Only Tuple update tránh tạo thêm index entries. fillfactor thấp hơn có thể để room cho HOT trên hot-update tables. Update nhiều indexed fields tạo index churn, WAL và bloat lớn hơn.

Transaction ID wraparound

XID hữu hạn và visibility dùng modular arithmetic; freeze biến tuple đủ cũ thành trạng thái an toàn. Nếu vacuum không theo kịp, PostgreSQL có thể buộc aggressive vacuum hoặc cuối cùng từ chối writes để tránh mất dữ liệu do wraparound.

Operational red flag: autovacuum chạy không có nghĩa cleanup đang hiệu quả. Nếu old snapshots hoặc slots giữ xmin, workers vẫn không thể xóa versions cần thiết; phải sửa blocker trước khi chỉ tăng workers.
Nguồn tham khảo