SQL DBMS systemen zijn eerst en vooral multi-user systemen. Om zowel verschillende gebruikers te kunnen behandelen als nog steeds de ACID regels ondersteunen, is er een systeem nodig dat soms gebruikers “in wacht” zet. Stel je voor dat Jens en Jolien tegelijkertijd data lezen én updaten—in dezelfde tabel, hetzelfde record. Jens leest uit “de rekening staat op 100 EUR” en Jolien haalt er 10 EUR vanaf. Wie mag eerst? Kan dit tegelijkertijd? Jens krijgt te horen dat er 100 EUR op de rekening staat, terwijl in werkelijkheid dit 10 EUR minder is.
Heel simpel. Dit is het verkeer zonder transacties:
Dit met:
Om Atomicity, Consistency, Isolation, Durability te garanderen is er dus een transactie manager nodig die alles in goede banen leidt op het moment dat verschillende gebruikers data gaan raadplegen en/of manipuleren. Dit principe is ruwweg hetzelfde als task management van het vak Besturingssystemen en C—maar dan op database-applicatie niveau.
Een transactie is een set van database operaties (bij relationele databases dus een aantal SQL operaties), dat door één gebruiker of applicatie als één unit of work aanzien wordt. Bijvoorbeeld, Jens wilt geld overschrijven van zijn rekening naar die van Jolien. Dit gaat meestal in verschillende stappen:
€10
van balans van Jens;€10
op balans van Jolien.Dit is één transactie—het zou nooit mogen gebeuren dat er €10
verdwijnt van Jens’ account zonder dat Jolien dat geld ontvangt. Met andere woorden, er kan niets tussen stap 1 en stap 2 komen: geen systeem crash, geen andere gebruiker (bijvoorbeeld Marianne die Jens €20
voor zijn verjaardag stort op de rekening). Dit is één “unit of work”: als er iets misloopt zou alles teruggedraaid moeten worden. Dus, een transactie heeft als resultaat ofwel success, ofwel failure, maar niets tussenin. Indien dit succesvol wordt afgerond zou het DBMS systeem moeten garanderen dat het geld effectief op Jolien’s rekening staat. Indien het faalde zou het DBMS systeem moeten garanderen dat Jens zijn geld niet kwijt is.
In de praktijk worden veel verschillende transacties tegelijkertijd uitgevoerd—eventueel door verschillende gebruikers. Er moet dus iemand zijn die dit beheert, en dat is de transactie manager. Wie beslist of Jens eerst zijn geld mag afhalen, of dat Marianne eerst zijn verjaardagscadeau mag overmaken op de rekening? Wie beslist dat tussen stap 1 en 2 bij de transfer van het geld van Jens naar Jolien niemand mag tussenkomen? Juist: de transactie manager. Hier zijn verschillende strategieën voor, zoals we later zullen zien in Concurrency Control.
Formeel gezien wordt er een transactie afgelijnd door aan te kondigen wanneer een transactie begint en wanneer hij stopt, zodat de manager de juiste acties kan doorvoeren. De gebruiker kan met SQL ook zelf een transactie terugdraaien als er een programmafout voorkomt, bijvoorbeeld met een try { ... } catch(Exception ex) { rollback }
. Meer hierover in sectie failures/rollbacks.
De transactie manager, die afgelijnde transacties ontvangt, kan dit dan in een schedule zetten, om te beslissen welke (delen van) transacties wanneer moeten worden uitgevoerd, net zoals Round Robin CPU scheduling algoritmes. Uiteindelijk wordt er een status toegekend aan een transactie:
Indien er halverwege de abort data is gewijzigd moet dit worden teruggezet, of worden rollbacked. Vorige versies van data moet dus ook worden bijgehouden. Jens’ rekening kan bijvoorbeeld €90
zijn initieel, hij haalt er €10
af om over te maken wat dit tot €80
maakt, maar er loopt iets mis: de rollback triggert het terugdraaien van het getal 80
naar de originele 90
.
Dit is een pseudocode voorbeeld van bovenstaande afgelijnde transactie:
BEGIN TRANSACTION;
UPDATE account SET waarde = waarde - :over_te_maken_bedrag
WHERE eigenaar = 'Jens'
UPDATE account SET waarde = waarde + :over_te_maken_bedrag
WHERE eigenaar = 'Jolien'
COMMIT;
Transacties kosten CPU en RAM en zijn configureerbaar maar dus gelimiteerd in aantal. De manager kan worden ingesteld tot bijvoorbeeld ondersteunen van maximum 10 transacties tegelijkertijd.
Een voorbeeld van een transactie workflow (de nummers komen overeen met het schema):
Hoe werkt dat blokje “recovery manager” precies? Een DBMS systeem gebruikt achterliggend een logfile als belangrijk element om eventuele recoveries te kunnen doorvoeren. Een logfile bevat in principe redundante data: in het beste geval wordt dit nooit gebruikt. Maar in het geval dat er ook maar iets misloopt is het van groot belang dat de log entries kunnen worden gebruikt om de data terug te zetten.
Voor elke transactie en operatie wordt relevante informatie geregistreerd in de logfile als een log record. Deze bevat de volgende informatie:
Er wordt altijd eerst in de logfile geschreven: dit noemen we een write-ahead log strategy. Op die manier is de DBMS manager voorbereid op een mogelijke rollback. Alle updates worden dus eerst naar de logfile geschreven voordat er iets fysiek veranderd op de harde schijf. Merk op dat de “logFILE” ook (gedeeltelijk) in-memory kan zijn.
Wat kan er zoal misgaan? Failures worden in drie groepen opgedeeld:
Het is de moeite waard om even te kijken naar de laatste 2 groepen en hoe daar recovery processen precies werken.
Veronderstel dat er 5 transacties door de DBMS worden verwerkt. Tc
duidt een checkpoint aan van de data in de buffer. Er treedt een systeemfout op rechts bij Tf
:
We bekijken de 5 transacties afzonderlijk:
T1
—Aangezien deze succesvol werd gecommit voor de systeemfout én voor de snapshot Tc
, hoeft hier niets voor te gebeuren na een crash.T2
—Deze transactie is ook compleet voor Tf
, maar er zit nog data in de buffer van de snapshot Tc
die niet naar disk geschreven werd. Hier is dus een REDO
nodig.T3
—Deze transactie was nog bezig bij de crash van Tf
. We hebben niet alle data in de buffer: er is dus transactie data verloren gegaan: een UNDO
dus.T4
—Deze transactie is gelukt maar alle data is nog steeds pending to disk (bij T2
was dit een deel): REDO
.T5
—De DBMS scheduler had deze net ingepland toen het systeem crashte. Het is niet nodig om hier is van terug te draaien omdat er niks pending was (na de Tc
checkpoint).Wat doe jij als er een harde schijf gerashed is van je computer? Bidden voor een werkende backup? Indien fysieke files niet meer toegankelijk zijn is een “media recovery” afhenkelijk van data redundancy principes. Hopelijk heb je een backup strategie voorzien. Voor database systemen wordt dit streng toegepast en moeten we een recovery doorvoeren via een mirror op een andere HDD in RAID, op een cloud backup, een offline backup, …
Om de failover time te minimaliseren wordt dit vaak automatisch opgezet. Een harde schijf kan in een server in RAID-1
modus geplaatst worden: die functioneert als 100% clone van de andere. Indien er één van beide HDDs faalt, neemt onmiddellijk de andere het werk over, zodat gebruikers zo goed als geen last hebben van de media failure. Systemen als backup copies door iets te “archiveren” (een .tar.gz
of .zip
op bepaalde tijdstippen aan de kant zetten) vereist meestal meer werk om terug te zetten. Backups nemen betekent ook beslissen of het een full of incremental backup zal zijn, waarbij je (1) alle files apart zet, of (2) enkel de wijzigingen ten opzichte van vorige snapshots.
Een goede backup strategie—dit geldt zowel voor databases als voor je eigen data!!—volgt het 1-2-3 backup principe:
Dan hebben we het nog niet over security gehad…
UNDO
en REDO
recovery technieken?bol.com
een item bestellen waarvan maar één hoeveelheid in stock is? Wie trekt hier aan het korte eind? Hoe vangen grote webwinkels dit probleem op?