Naar de inhoud

Blog ·

De verhuisreservering wordt de plaatsing

Een machine tussen twee racks verplaatsen kent één gevaarlijk ogenblik: de bestemming is dan niet gereserveerd en niet bezet. Zo hebben we dat weggehaald.

Door Provibr

Een server van de ene rack-unit naar de andere verplaatsen is fysiek een kort klusje met een schroevendraaier en een tweede paar handen. De administratie eromheen is waar de interessante fout woont, en die woont in één ogenblik: het moment waarop de bestemming niet langer gereserveerd is en nog niet bezet.

Landt de schrijfactie van iemand anders in dat ogenblik, dan staan er twee machines in hetzelfde slot vastgelegd. In een database leest dat als een overtreding van een constraint waar je over kunt discussiëren. Op de vloer leest het als een technicus die voor een rack staat met een machine in zijn handen en nergens om hem te laten.

Het venster, en hoe je er geen hebt

De voor de hand liggende volgorde bestaat uit drie stappen. Geef de oude claim vrij, geef de verhuisreservering op de bestemming vrij, schrijf de nieuwe plaatsing. Binnen één transactie is dat venster onzichtbaar voor andere sessies, en juist daarom is het gemakkelijk om het te laten zitten: het komt door elke test die je schrijft. Het blijft een venster, want de instructie erna werkt op een slot dat de vorige instructie heeft vrijgegeven, en één verkeerde volgorde bij een latere herstructurering is genoeg.

Wij doen iets eenvoudigers. De verhuisreservering wordt bevorderd in plaats van vervangen. De regels die vastleggen welke units bezet zijn blijven precies staan waar ze staan; alleen de kopregel verandert van soort, van een verhuisreservering in een plaatsing, en zijn vervaltijdstip gaat in dezelfde update op null. De oude plaatsing sluit in dezelfde transactie. Er is geen moment waarop de bestemming vrij is, dus er is geen tweede kans om te botsen, en het geheel is één update en geen insert die moet slagen.

De claimidentificatie blijft door die bevordering heen ongewijzigd, en dat is de manier om te toetsen dat dit werkelijk gebeurd is en niet iets wat er van buitenaf alleen op lijkt.

Het vervaltijdstip op null zetten is geen netheid. Een check in de database weigert een plaatsing die er een draagt, want een plaatsing die op een dinsdag stilletjes ophoudt mee te tellen terwijl de machine er nog in vastgeschroefd zit, is een rack waarvan de software gelooft dat er een vrije unit in zit. Een verlopende reservering is een functie; een verlopende plaatsing is een leugen met een tijdklok erop.

De scheidsrechter is nog altijd één index

Niets van het bovenstaande is het ding dat een dubbele boeking voorkomt. Dat blijft een partiële unieke index op het rack, de zijde en het slot, beperkt tot regels die niet vrijgegeven zijn, en een verhuisreservering valt er net zo goed onder als een plaatsing.

Twee technici die op dezelfde seconde dezelfde unit kiezen zien hem allebei vrij in de planningsfunctie die vóór het schrijven draait, en precies een van de twee komt door de database heen. De schrijfactie van de ander loopt stuk op de index, en de enige weg die bezetting wegschrijft vangt die overtreding op en maakt er een leesbare weigering van die de botsende units noemt. Welke zin het wordt, bepaalt de naam van de constraint die afging, want "deze unit is bezet" en "deze machine staat al ergens anders" sturen iemand naar twee verschillende racks. Een rechtstreekse insert die deze weg overslaat krijgt in plaats daarvan de kale overtreding. Allebei gemeten, want redeneren over isolatieniveaus is geen bewijs.

De planningsfunctie is een melding en geen verdediging. De index is de verdediging. Die twee rollen uit elkaar houden is wat de melding behulpzaam laat zijn zonder dat iemand in de verleiding komt erop te vertrouwen.

Negen standen, en twee uitgangen die ophouden te bestaan

Een verhuizing heeft negen standen: concept, gepland, goedgekeurd, in uitvoering, wacht op verificatie, moet nagelopen worden, voltooid, geannuleerd en mislukt. Welke overgangen geldig zijn staat als een record over alle negen en niet als een switch. Een switch met een default laat een nieuw toegevoegde stand doorvallen naar toegestaan, en de gevaarlijke richting is hier precies die: een stand die iemand toevoegt omdat er iets ongewoons speelt zou de eerste stand zijn die alles mag.

De interessante regel is de regel die in_progress verlaat, want twee uitgangen die elke eerdere stand wél heeft ontbreken daar: er is geen weg terug naar goedgekeurd en geen weg naar geannuleerd. Iemand heeft de machine op dat moment in zijn handen, en de enige eerlijke uitgangen zijn "gemeld als klaar", "we weten het niet" en "het is mislukt". Annuleren is een beslissing die vooraf genomen wordt; nadat fysiek werk gemeld is, is een rollback in de database een bewering over de fysieke wereld die niemand geverifieerd heeft.

De drie eindstanden, voltooid, geannuleerd en mislukt, dragen lege lijsten en niet helemaal geen regel. Dat is het verschil tussen "hiervandaan gaat niets verder" en "hier heeft niemand over nagedacht", en alleen het eerste is een beslissing.

Een tweede tabel zegt per stand of de bestemming vastgehouden moet worden. De regel die verdediging verdient is needs_reconcile, die hem vasthoudt. Niemand weet op dat moment waar de machine is, dus de bestemming vrijgeven zou een tweede machine kunnen zetten op een unit die misschien al bezet is.

Verplaatsen is niet onderweg zijn

Apparaten dragen een processtand, en dit werk heeft moving toegevoegd naast het bestaande in_transit. Ze klinken als synoniemen en dat zijn ze niet. moving betekent dat de machine binnen dit datacenter verplaatst wordt en dat de ruimte op de bestemming gereserveerd is. in_transit betekent dat hij onderweg is tussen twee sites en dus nergens is. Allebei blokkeren ze levering aan een klant, maar ze beantwoorden verschillende vragen wanneer iemand vraagt waar een machine is, en ze samenvoegen zou het antwoord op de tweede vraag onjuist maken. De scheiding wordt afgedwongen en niet alleen beschreven: een check in de database eist dat de herkomstsite en de bestemmingssite van een verhuizing dezelfde zijn, dus een verhuizing is per constructie iets wat binnen één gebouw gebeurt, en de weg tussen twee sites is een ander proces met een ander woord ervoor.

Welke stand de machine vóór de verhuizing had wordt in de bevroren preflight opgeslagen en niet aangenomen. Hardware die net binnen is staat op staging, en achteraf alles terugzetten op normal zou elke verplaatste machine stilletjes uit de inname afmelden.

Twee uitwegen uit het niet weten, en geen van beide is een rollback

Is de fysieke uitkomst onzeker, dan gaat de verhuizing naar needs_reconcile en moet iemand gaan kijken. Er zijn twee antwoorden, en allebei worden ze vastgelegd als waarnemingen.

WaarnemingWat er met de verhuizing gebeurtWat er met de ruimte gebeurt
Gezien op de bestemmingVoltooidDe verhuisreservering wordt de plaatsing, zoals hierboven
Gezien op de herkomstMislukt, met een reden die zegt dat hij nooit is uitgevoerdDe verhuisreservering wordt vrijgegeven; de oorspronkelijke plaatsing blijft onaangeroerd

De tweede is met opzet mislukt en niet geannuleerd. Iemand heeft fysiek werk gedaan en de machine is niet verhuisd; dat is een uitkomst en geen keuze. En het is geen rollback: de database wordt niet teruggezet naar een toestand die doet alsof er niets gebeurd is. De locatiehistorie is uitsluitend aanvullend, correcties zijn nieuwe compenserende regels, en het verschil komt een maand later boven wanneer iemand vraagt waarom een machine een dag heeft stilgestaan. Een rollback laat niets achter. Een compenserende regel laat zien dat er een onzekerheid was en hoe die beslecht is.

Die historieregels dragen site- en rackidentificaties zonder foreign keys, met opzet. Een rack dat volgend jaar uit dienst gaat verandert niets aan wat er afgelopen maart in stond.

Twee kleine beslissingen die later gaan tellen

De verhuizing wijst naar zijn achtergrondbewerking met een verwijzing die op SET NULL staat wanneer die bewerking verwijderd wordt, en niet op CASCADE. Bewerkingen worden na negentig dagen opgeruimd. De hardwareadministratie niet, en een cascade zou betekenen dat het bewaarbeleid voor voortgangsbalken stilletjes het bewijs wist van waar een machine heen is gegaan.

En een partiële unieke index staat één openstaande verhuizing per apparaat toe. Zonder die index kunnen twee mensen twee verschillende bestemmingen plannen voor dezelfde machine, en op hun eigen scherm ziet het er allebei correct uit.

Wat we zouden opschrijven

  1. Bevorder, maak niet opnieuw aan. Hebben een reservering en een toewijzing dezelfde vorm, verander dan de soort in plaats van vrij te geven en te schrijven, en toets dat de identificatie het overleefd heeft.
  2. Houd de scheidsrechter in de database en de uitleg in de code. De index beslist wie wint; de planningsfunctie zegt welke units botsen.
  3. Schrijf de overgangstabel over elke stand. Een default-tak maakt van een nieuwe stand een toegestane.
  4. Draai na gemeld fysiek werk nooit terug. Voeg een stand toe die "onbekend" betekent en geef die twee gedocumenteerde uitgangen, allebei waarnemingen.
  5. Maak de historie uitsluitend aanvullend en laat correcties nieuwe regels zijn, want dat iets ooit onzeker was is op zichzelf informatie.
  6. Kijk waar je bewaarbeleid aan vastzit. Een cascade van een kortlevende tabel naar een langlevende is een gegevensverliesfout met een tijdschema.

Voor de duidelijkheid over wat dit is: het werk aan datacenterlogistiek zit achter een uitrolvlag die standaard uit staat, met daarbovenop een instelling per organisatie, dus niets ervan is vandaag te koop. Vier dingen zijn onbewezen. De live voortgangsgebeurtenis van een verhuizing is beproefd zonder zijn berichtenbus. Een verhuizing annuleren vanaf het beheerscherm is niet in een browser aangestuurd. Een verhuisreservering die werkelijk verlopen was is nooit waargenomen, en er is met opzet geen opruiming die er een wegruimt, want een verhuisreservering die zichzelf opruimt terwijl iemand bij het rack staat is precies de tegenspraak waarvoor de index bestaat. En diezelfde sitecontrole die hierboven beschreven staat is nooit werkelijk afgegaan, want er is geen tweede site gezaaid om hem mee te laten afgaan.

Uit het datacenterwerk aan Provibr. Waarom een partiële unieke index de enige echte grens op bezetting is staat in de enige echte grens op rackbezetting, en waarom de vijf capaciteitsvragen boven een rack niet bij elkaar op te tellen zijn staat in rackruimte is geen capaciteit.

Begin met één host en één agent

Maak een account aan, installeer de agent met één commando en koppel je eerste Proxmox-host. De proefperiode loopt 14 dagen en vraagt geen betaalgegevens.