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ế |
|---|---|
| Atomicity | Các thay đổi trong transaction cùng commit hoặc rollback. |
| Consistency | Database constraints và invariants được biểu diễn đúng được giữ qua transaction; database không tự biết mọi business rule. |
| Isolation | Quy định concurrent transactions được quan sát/interleave tới mức nào. |
| Durability | Committed 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
| Level | Snapshot behavior | Điểm cần nhớ |
|---|---|---|
| Read Committed | Mỗ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 Read | Mộ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. |
| Serializable | Serializable Snapshot Isolation theo dõi dependency nguy hiểm. | Database có thể abort transaction để giữ serializability; application phải retry toàn transaction. |
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.
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.
- Theo dõi dead tuples và thời điểm last vacuum/analyze.
- Xem vacuum progress và blockers giữ old snapshot.
- Theo dõi
age(relfrozenxid)và transaction age. - Tune threshold/scale factor theo churn, table size và maintenance capacity.
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.