Multi-Version Concurrency Control (MVCC) — database’da qatorning bir nechta vaqtinchalik versiyasini saqlab, o‘quvchilar va yozuvchilar o‘rtasidagi bloklanishni kamaytiradigan concurrency usuli. Har transaction o‘z snapshotiga mos versiyalarni ko‘radi, shu sabab o‘qish ko‘pincha davom etayotgan yozishni kutmaydi.
Versiyalar va snapshot
Row yangilanganda engine eski qiymatni darhol yo‘qotmasdan yangi version yaratadi yoki undo ma’lumoti orqali oldingi ko‘rinishni tiklaydi. Har version transaction ID yoki timestamp bilan bog‘lanadi. Snapshot qaysi transactionlar commit bo‘lganini va qaysilari hali faol ekanini belgilaydi.
O‘quvchi snapshotiga ko‘ra ko‘rinadigan eng yangi versionni tanlaydi. Keyin boshlangan transaction commit qilsa ham, isolation darajasiga qarab mavjud snapshot uni ko‘rmasligi mumkin. Bu consistent read beradi.
Implementatsiya farqlari
PostgreSQL yangi row versionlarini asosiy heapda saqlaydi; eski dead tuple’larni VACUUM keyin tozalaydi. Oracle va InnoDB oldingi qiymatni undo segmentlar orqali taqdim etadi. SQL Server snapshot isolation uchun version store’dan foydalanishi mumkin. “MVCC bor” degan jumla storage, cleanup va isolation semantikasini to‘liq aytmaydi.
Har engine transaction ID wraparound, version retention va garbage collectionni o‘z usulida boshqaradi. Uzoq transaction eski versiyalarni ushlab, table bloat yoki undo storage o‘sishiga sabab bo‘ladi.
O‘qish va yozish
MVCC read–write conflictlarni kamaytiradi, lekin write–write conflict yo‘qolmaydi. Ikki transaction ayni rowni yangilasa biri lock kutishi, serialization xatosi olishi yoki isolationga qarab lost update xavfi tug‘ilishi mumkin. Application retry va atomic update ishlatadi.
SELECT ... FOR UPDATE ko‘rilgan satrlarni keyingi update uchun lock qiladi. Bu oddiy consistent read’dan boshqa semantika. Lockni keraksiz keng olish concurrency’ni kamaytiradi.
Isolation darajalari
Read Committed har statement uchun yangi snapshot olishi mumkin, shu sabab bir transaction ichida takroriy query boshqa committed holatni ko‘radi. Repeatable Read odatda transaction davomida barqaror snapshot beradi. Serializable isolation MVCCga qo‘shimcha conflict detection yoki locking orqali serial executionga teng natijani maqsad qiladi.
Snapshot isolation dirty read va non-repeatable readni cheklaydi, ammo write skew kabi anomalyga ruxsat berishi mumkin. Constraint bir qatorga emas, bir nechta satr predicatiga bog‘liq bo‘lsa serializable yoki explicit lock talab etiladi.
Cleanup
Eski version hech bir faol snapshotga kerak emasligi aniqlangach olib tashlanadi yoki joyi qayta ishlatiladi. Global xmin, undo retention yoki boshqa horizon eng eski kerakli versiyani ko‘rsatadi. Uzoq idle in transaction, prepared transaction va replication slot cleanupni to‘xtatishi mumkin.
Monitoring dead tuple, undo/version store, transaction age va cleanup lagni kuzatadi. Faqat query latency emas, version storage o‘sishi ham operatsion signal.
To‘g‘ri qo‘llash
MVCC application invariantlarini avtomatik himoya qilmaydi. Unique va check constraintlar database darajasida saqlanadi. Ko‘p qatorli biznes qoidasi transaction isolation va lock strategiyasi bilan test qilinadi. Retry qilinadigan transaction idempotent bo‘lishi kerak.
Concurrency testlar ikki yoki undan ko‘p sessionni aniq interleaving bilan ishlatadi. Faqat ketma-ket unit test lost update, write skew va serialization failure’ni ko‘rsatmaydi.
MVCC saqlash xarajatini ham keltiradi: uzoq tranzaksiya eski versiyalarni tozalashga to‘sqinlik qiladi. Shu sababli tizim eng eski faol snapshot, versiyalar hajmi va vacuum yoki compaction ortda qolishini kuzatadi.
Bog‘liq tushunchalar
Transaction isolation, Snapshot, Row version, VACUUM, Undo log, Write skew, Lost update, Serializable isolation