Kiekviena šiuolaikinė programėlė po savo „kapotu“ slepia nematomą, bet gyvybiškai svarbų variklį – duomenų bazių valdymo sistemą (DBVS). Nors kūrėjai ir analitikai kasdien rašo SQL užklausas, pati sistema jiems dažnai lieka mistinė „juodoji dėžė“. Tačiau siekiant aukščiausio našumo, būtina suprasti koncepciją, kurią inžinieriai vadina Life of a Query (užklausos gyvavimo ciklas). Tai kelionė nuo tinklo protokolo valdymo iki gilaus nusileidimo į diskinius posistemius.
Šiame straipsnyje, remdamiesi Berklio universiteto („Architecture of a Database System“) ir kitų autoritetingų šaltinių įžvalgomis, atskleisime 5 architektūrines paslaptis, kurios paaiškina, kas iš tikrųjų vyksta, kai DBVS vykdo jūsų komandas.
1. Duomenų bazė yra „mini operacinė sistema“ viduje
(LoQ etapas: Process Manager ir Admission Control)
Daugelis klaidingai mano, kad DBVS yra tiesiog paprasta programa, veikianti operacinėje sistemoje (OS). Iš tiesų, moderni DBVS veikia kaip itin specializuota „mini operacinė sistema“, kuri dažnai perima funkcijas iš pačios OS.
Svarbiausias šio etapo momentas – Admission Control (priėmimo kontrolė). Prieš užklausai pradedant darbą, Process Manager turi nuspręsti, ar sistemoje yra pakankamai resursų. Jei DBVS tiesiog aklai vykdytų visas užklausas, įvyktų sistemos „dusimas“ (thrashing), kai procesorius visą laiką praleidžia keisdamas atminties puslapius, o ne dirbdamas naudingą darbą. DBVS matuoja savo Working Set (darbinį rinkinį) ir nusprendžia, ar užklausą vykdyti dabar, ar ją atidėti.

Kodėl DBVS nepasitiki OS gijomis? Standartinės OS gijos (kernel threads) turi didelį Context Switch (konteksto perjungimo) viršsvorį. Todėl efektyvios sistemos dažnai naudoja lengvasvores DBMS threads (LWT), kurios valdomos vartotojo erdvėje (user-space). Tai leidžia sistemai pačiai planuoti užduotis be brangių kreipimųsi į OS branduolį, užtikrinant milžinišką lygiagretumą.
2. „Helovino problema“: kai atnaujinimas tampa begalinis
(LoQ etapas: Query Processor ir Plan Executor)
1974 m. spalio 31 d. „IBM System R“ kūrėjai atrado klaidą, kuri dabar žinoma kaip „Helovino problema“. Įsivaizduokite užklausą: „Pakelti algą 10 % visiems, uždirbantiems mažiau nei 20 000 eurų“.
Mechanizmas: Jei sistema naudoja indeksų skenavimą (index scan) pagal algos stulpelį, atnaujintas įrašas (su padidinta alga) fiziškai pajuda B+Tree indekso lapų mazguose (leaf nodes) į dešinę, nes jo vertė padidėjo. Jei skenavimas tęsiasi ta pačia kryptimi, tas pats darbuotojas vėl surandamas vėlesniame etape, jo alga vėl padidinama, ir jis vėl „pajuda“ toliau. Tai gali tęstis iki begalybės, kol darbuotojo alga viršys ribą.
Sprendimas: Šiuolaikinės DBVS taiko Materialization (materializacijos) metodą. Prieš pradedant modifikavimą, sistema sukuria snapshot’ą – surenka visus keistinus įrašų identifikatorius (RID) į laikiną sąrašą. Taip atskiriamas įrašų atradimo etapas nuo jų keitimo etapo, užtikrinant, kad užklausa „nematytų“ savo pačios atliekamų pakeitimų.
3. NoSQL nėra „be SQL“ – tai kompromisas tarp greičio ir teisybės
(LoQ etapas: Query Processor ir Storage Engine)
NoSQL nėra tiesiog „modernesnė“ SQL versija. Tai inžinerinis atsakas į CAP teoremą, teigiančią, kad paskirstytoje sistemoje neįmanoma vienu metu turėti visiško nuoseklumo (Consistency), pasiekiamumo (Availability) ir atsparumo tinklo skaidymuisi (Partition tolerance).
Dauguma NoSQL sistemų pasirenka „galutinį nuoseklumą“ (eventual consistency), kur kaina už horizontalų mastelį yra stale reads (pasenusių duomenų skaitymas). Tačiau ši riba nyksta – pavyzdžiui, „MongoDB“ dabar palaiko ACID transakcijas, o tai rodo sistemų konvergenciją.
| Savybė | Tradicinis ACID (RDBMS) | NoSQL (Spektras) |
| Duomenų modelis | Lentelės (Tabular) | Key-Value, Document, Graph, Wide-column |
| Schema | Griežta (Fixed) | Lanksti (Schema-less/Dynamic) |
| Santykių jungimas | SQL Joins (Optimizuoti) | Dažnai vengiama arba atliekama aplikacijoje |
| Nuoseklumas | Griežtas (Immediate) | Dažnai (Eventual) bet yra ACID išimčių, pvz., MongoDB |
| Mastelis | Dažniausiai Vertikalus | Horizontalus (Clusters/Sharding) |
4. Atminties kopijavimas yra naujasis „lėtas diskas“
(LoQ etapas: Buffer Manager ir Log Manager)
Šiuolaikinėse sistemose, kur I/O operacijos atliekamos greitais SSD/NVMe diskais, pagrindiniu stabdžiu tampa ne diskas, o CPU ir RAM duomenų kopijavimas. Viena didžiausių problemų – Double Buffering (dvigubas buferiavimas), kai duomenys kopijuojami ir OS faile, ir DBVS buferių telkinyje (Buffer Pool).

Čia kritiškai svarbi Temporal Control (laiko kontrolė). DBVS privalo kontroliuoti, kada duomenys pasiekia diską. Tai tiesiogiai susiję su Write Ahead Logging (WAL) protokolu: log’o įrašai privalo pasiekti diską anksčiau nei patys duomenys. Jei OS savavališkai perrikiuotų įrašus (o tai ji mėgsta daryti dėl optimizacijos), sistemos gedimo atveju duomenų bazė taptų korumpuota. DBVS naudoja tiesioginę prieigą prie disko (raw-mode access arba DIO/CIO), kad apeitų OS buferius ir užtikrintų ACID saugumą bei išvengtų nereikalingų CPU ciklų kopijavimui.
5. Duomenų bazės „šmėklos“ (Phantom Problem)
(LoQ etapas: Lock Manager)
Transakcijų izoliacija yra balansavimas tarp preciziškumo ir greičio. Phantom Problem (šmėklų problema) atsiranda tada, kai viena transakcija skaito įrašų diapazoną (pvz., visas sąskaitas > 1000 €), o kita transakcija tuo metu įterpia naują įrašą, atitinkantį tą kriterijų. Pirmoji transakcija, pakartojusi skaitymą, staiga pamato „šmėklą“ – įrašą, kurio prieš tai nebuvo.
Tobula izoliacija (Serializability) reikalauja, kad Lock Manager (užraktų valdytojas) užrakintų ne tik esamus įrašus, bet ir „skyles“ tarp jų (indeksų diapazonus). Tai itin brangu resursų prasme, todėl dauguma sistemų pagal nutylėjimą leidžia tam tikrą netvarką, kad el. prekybos sistemos veiktų greitai, o ne lauktų milžiniškose užraktų eilėse.
Išvados: Žvilgsnis į daugiabranduolinę ateitį
Duomenų bazė nėra tik pasyvi saugykla – tai sudėtingas orkestras, derinantis fizinę erdvę ir laiką. Supratimas apie Admission Control, WAL protokolą ar B+Tree mechaniką padeda rašyti kodą, kuris „nekovoja“ su sistema, o išnaudoja jos prigimtį.

Tačiau ateitis kelia naujus iššūkius. Mes judame link „many-core“ architektūrų su tūkstančiais branduolių viename luste. Pagrindinis butelio kaklelis persikelia iš I/O į koordinaciją atminties kelyje (bottleneck in the memory path). Ar mūsų dabartinė architektūra, sukurta dar aštuntajame dešimtmetyje, atlaikys pasaulį, kuriame procesoriaus branduolių koordinavimas kainuoja brangiau nei pats duomenų skaitymas? Tai klausimas, į kurį šiandien atsako naujos kartos duomenų architektūros ekspertai.
