Een van de uitdagingen bij het omgaan met een nieuw databaseontwerp is dat je niet weet hoe groot de tabellen zullen worden totdat ze daadwerkelijk met een behoorlijke hoeveelheid gegevens zijn gevuld. Maar als het ontwerp rekening moet houden met eventuele problemen met de schaalbaarheid, kunt u het niet inzetten om die gegevens te verkrijgen totdat de schatting is gemaakt. Een manier om dit te omzeilen is om dingen agressief te prototypen. Gebruik hiervoor staging-hardware waar nieuwe applicaties tijdelijk op kunnen voortleven en dit soort details op een rijtje zet. Je kunt er gewoon rekening mee houden dat je de app moet verplaatsen en mogelijk na een paar maanden opnieuw moet ontwerpen, wanneer je een beter idee hebt welke gegevens erin zullen verschijnen.
De andere manier om dit kip-ei-probleem te omzeilen, is door een gegevensgenerator te schrijven. Construeer voldoende voorbeeldgegevens met de hand om te zien hoe het eruit ziet, hoe dicht het is en hoe de waarden worden verdeeld. Schrijf dan iets dat die statistieken gebruikt en een grotere dataset produceert die er op lijkt. Je krijgt dat nooit perfect, maar dat hoeft ook niet. Het genereren van gigantische datasets, zelfs met enkele gebreken, is nog steeds de beste manier om een schatting van de databasegrootte te maken. Er zijn zoveel bronnen van overhead dat het moeilijk te verklaren is dat elke gemeten tabel- en indexgrootte, gebaseerd op zoiets als uw gegevens, veel nauwkeuriger zal zijn dan welke andere benadering dan ook. Er is een reden waarom ik uiteindelijk veel vragen over prestatiegerelateerde problemen beantwoord door pgbench te gebruiken om eerst een database van de juiste grootte te maken.
Het genereren van gegevens is echter niet eenvoudig. Vooral het genereren van realistische tijdstempels is altijd vervelend. En hoe efficiënt u ze ook denkt te hebben geschreven, het duurt meestal langer dan u verwacht, en zelfs langer om de resulterende gegevens in een database te krijgen en correct te indexeren.
En dat blijft het geval, hoe vaak je dit ook hebt gedaan, want zelfs als je alles goed doet, zal de wet van Murphy binnendringen om het werk hoe dan ook pijnlijk te maken. Mijn computers thuis zijn allemaal gebouwd met relatief goedkope pc-hardware. Niet de goedkoopste dingen die beschikbaar zijn - ik heb wel standaarden - maar gebruik zeker niet dezelfde kwaliteit die ik mensen zou aanraden in een server te zoeken. Het probleem met het genereren van gegevens van deze week herinnerde eraan waarom betere hardware waard is hoeveel het kost voor bedrijfskritisch werk.
Na een paar miljard rijen gegevens te hebben gegenereerd en die import 10 uur lang te hebben bekeken, was ik niet blij dat de hele taak op deze manier werd afgebroken:
psql:load.sql:10: ERROR: invalid input syntax for type timestamp: "201^Q-04-14 12:17:55"
CONTEXT: COPY testdata, line 181782001, column some_timestamp: "201^Q-04-14 12:17:55"
Het blijkt dat ergens in het midden van het schrijven van de 250 GB aan testgegevens die ik heb gegenereerd, een van de uitvoer van de regels beschadigd was. Twee bits zijn omgedraaid en de uitgeschreven gegevens waren verkeerd. Ik weet niet zeker waar dat is gebeurd.
Het geheugen is de meest waarschijnlijke verdachte. Echte servers gebruiken ECC RAM, en terecht. Als u een systeem met veel RAM bewaakt, kan het aantal fouten dat stil door ECC wordt gecorrigeerd, schokkend zijn. Het RAM-geheugen dat ik thuis gebruik is goed, maar de foutpercentages in elk geheugen zonder mogelijkheden voor foutdetectie/-correctie zullen hoger zijn dan je zou willen - en nooit gedetecteerd tenzij ze gebeuren in code die tot een systeemcrash leidt. Het genereren van gegevens is een goede manier om deze problemen aan het licht te brengen, omdat het doorgaans ten minste één CPU op uw server mogelijk dagen achtereen zwaar belast. Als er enige instabiliteit in uw systeem is, zal het systeem verergeren door het warm te maken en het lange tijd los te laten.
Een tweede beschermingslaag tegen dit soort corruptie is het plaatsen van controlesommen op gegevens die naar schijf worden geschreven, ter bescherming tegen fouten bij het schrijven en vervolgens opnieuw lezen van de gegevens. De blokcontrolesomming door het ZFS-bestandssysteem is een van de betere implementaties daarvan. In mijn geval heeft het misschien geen enkel verschil gemaakt of ik ZFS had gebruikt of niet. Als de bits werden omgedraaid voordat de blokcontrolesom plaatsvond, zou ik hoe dan ook ongewenste gegevens hebben weggeschreven - met een ongewenste controlesom om het te evenaren.
Mijn volgende stap was om de split . te gebruiken hulpprogramma om mijn gigantische bestand te nemen en het in meer hapklare stukjes te breken - nog een paar uur wachten tot dat klaar is. Dan kon ik beginnen met het laden van de goede bestanden terwijl ik de slechte repareerde.
Aangezien de resulterende bestanden elk 13 GB waren en mijn enige server 16 GB RAM heeft, hoewel ik deze typfout van één teken kon corrigeren met vi. Theoretisch zou dat het geval moeten zijn, maar ik begin mijn twijfels te krijgen, gezien hoe lang ik heb gewacht tot het bestand daarna weer wordt weggeschreven:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
21495 gsmith 20 0 8542m 8.3g 1544 R 98 53.0 419:56.70 vi datafile-ag
Dat is een solide 7 uur waarop ik heb gewacht, alleen maar tot deze typefout van één teken is opgelost, zodat ik het laden van de testgegevens kan voltooien. Zoals ik al zei, het genereren van serieuze gegevens is nooit gemakkelijk.