InterBase- en Firebird-herstelgids
NOTITIE: Dit document is het hoofdstuk uit het boek “The InterBase World”, geschreven door Alexey Kovyazin en Serg Vostrikov.
Het hoofdstuk uit het boek “The InterBase World” is gewijd aan het repareren van databases.
1. De geschiedenis van deze handleiding
Het Russische boek “The InterBase World” werd in september 2002 gepubliceerd.
De oplage bedroeg 3000 exemplaren. Na 3 maanden was het uitverkocht en in april 2003 verscheen een tweede, verbeterde editie met een oplage van 5000 exemplaren.
Nu staat het bovenaan in de grootste Russische online-boekwinkels en we verwachten dat het zeer binnenkort uitverkocht zal zijn.
De auteurs van het boek zijn Alexey Kovyazin, ontwikkelaar van IBSurgeon en
bekend Russisch InterBase-specialist, en Serg Vostrikov, CEO van Devrace
company www.devrace.com
Het is grappig, er is geen enkel boek over InterBase in het Engels gepubliceerd!
Duizenden en duizenden ontwikkelaars gebruiken InterBase en Firebird, bespreken het
onderwerp in verschillende conferenties (kijk hier: Links).
De gemeenschap van InterBase-ontwikkelaars telt gemiddeld tienduizenden
mensen. De sterke vraag naar InterBase-boeken in verschillende landen bewijst dat de InterBase-gemeenschap echt groot is.
We durven te wedden om een krat bier dat een oplage van 10000 exemplaren binnen een maand van Amazon.com weggevaagd zou worden. Maar mensen in uitgeverijen
“weten alles” en zijn er zeker van dat niemand een boek over InterBase koopt. Dat is echt jammer.
Hier bieden we u graag het concept aan van een hoofdstuk uit dit boek, gewijd aan het herstel van InterBase/Firebird-databases.
2. Hoe een InterBase/Firebird-database te herstellen
2.1. Overzicht van de belangrijkste oorzaken van databasecorruptie
Helaas bestaat er altijd een kans dat een informatieopslag
beschadigd raakt en dat er informatie uit verloren gaat. Een database vormt geen uitzondering op deze regel. In dit hoofdstuk behandelen we de belangrijkste oorzaken die leiden tot corruptie van een InterBase-database, enkele methoden voor het repareren van databases en het extraheren van informatie daaruit. Ook maken we kennis met de aanbevelingen en voorzorgsmaatregelen die de kans op informatieverlies uit een database minimaliseren.
Allereerst moeten we, als we het over databasereparatie hebben, het begrip
“databasecorruptie” verduidelijken. Een database wordt doorgaans beschadigd genoemd als er bij het extraheren of wijzigen van informatie fouten optreden en/of de geëxtraheerde informatie verloren, onvolledig of helemaal niet correct blijkt te zijn. Er zijn gevallen waarin databasecorrupties verborgen zijn en alleen worden gevonden door te testen met speciale hulpmiddelen, maar er zijn ook echte databasecorrupties wanneer het onmogelijk is om verbinding te maken met de database, wanneer aangepaste clientprogramma’s vreemde fouten tonen (terwijl er geen manipulaties met de database zijn uitgevoerd), of wanneer het onmogelijk is om de database te herstellen vanaf een back-upkopie.
2.2. Belangrijkste oorzaken van databasecorruptie zijn:
- Abnormale beëindiging van de servercomputer, vooral onderbreking van de elektrische stroomvoorziening. Voor de IT-sector is dit een ware plaag en daarom hopen we dat het niet nodig is u er nogmaals aan te herinneren hoe noodzakelijk het is om een bron van ononderbroken stroomvoorziening op de server te hebben.
- Defecten en storingen van de servercomputer, vooral de HDD (harde schijf), schijfcontrollers, het hoofdgeheugen van de computer en het cachegeheugen van RAID-controllers.
- Een onjuiste verbindingsreeks met een multi-clientdatabase van een of meer gebruikers (in versies vóór 6.x). Bij verbinding via TCP/IP moet het pad naar de database worden opgegeven als servernaam: station:/pad/databasenaam /voor servers op UNIX-platform servernaam: /pad/databasenaam /, volgens het NETBEUI-protocol \\servernaam\station:\pad\databasenaam. Zelfs bij het verbinden met de database vanaf de computer waarop de database zich bevindt en de server draait, moet men dezelfde regel gebruiken en servernaam vervangen door localhost. Men kan geen toegewezen station in de verbindingsregel gebruiken. Als u een van deze regels overtreedt, beschouwt de server het alsof hij met verschillende databases werkt en is databasecorruptie gegarandeerd.
- Bestandskopie of andere bestandstoegang tot de database terwijl de server draait. Het uitvoeren van het commando “shut-down” of het op de gebruikelijke manier loskoppelen van de gebruikers is geen garantie dat de server niets met de database doet; als het sweep-interval niet op “0” is ingesteld, kan garbage collection worden uitgevoerd. Over het algemeen wordt garbage collection onmiddellijk uitgevoerd nadat de laatste gebruiker de verbinding met de database verbreekt. Meestal duurt dit enkele seconden, maar als er daarvoor veel DELETE- of UPDATE-bewerkingen zijn vastgelegd, kan het proces langer duren.
- Gebruik van instabiele InterBase-serverversies 5.1-5.5. Borland Company heeft officieel toegegeven dat er verschillende fouten in deze servers zaten en een stabiele upgrade 5.6 werd pas na de uitgave van gecertificeerde InterBase 6 in free-running modus voor alle klanten van servers 5.1-5.5 op de site geplaatst.
- Overschrijding van de groottebeperking van het databasebestand (niet van een database!). Voor versies vóór InterBase 6 en sommige InterBase 6-bèta’s is de limiet voor het databasebestand 4 Gb, voor InterBase 6.5 en alle releases van Firebird (1.0, 1.5, 2.0, 2.1) - 32 Tb. Wanneer de databasegrootte een grenswaarde nadert, moet een extra bestand worden aangemaakt.
- Uitputting van vrije schijfruimte bij het werken met de database.
- Voor Borland InterBase-servers van versies vóór 6.0.1.6 - overschrijding van de beperking op het aantal generators zoals gedefinieerd door Borland InterBase R & D op de volgende manier (zie tabel 1).
| Versie | Paginagrootte=1024 | Paginagrootte=2048 | Paginagrootte=4096 | Paginagrootte=8192 |
| Vóór 6 | 248 | 504 | 1016 | 2040 |
| 6.0.x | 124 | 257 | 508 | 102 |
Tabel 1: Kritiek aantal generators in vroege InterBase-versies
• Voor alle Borland InterBase-servers - overschrijding van het toegestane aantal
transacties zonder back-up/restore uit te voeren. Men kan het aantal
transacties dat in de database heeft plaatsgevonden sinds de laatste aanmaak te weten komen door het hulpprogramma gstat aan te roepen met de sleutel -h- parameter NEXT TRANSACTION ID zal de gewenste
hoeveelheid transacties zijn. Volgens Ann W. Harrison hangt het kritieke aantal
transacties af van de paginagrootte en heeft het de volgende waarden (zie tabel 2):
| Databasepaginagrootte | Kritiek aantal transacties |
| 1024 byte | 131 596 287 |
| 2048 byte | 265 814 016 |
| 4096 byte | 534 249 472 |
| 8192 byte | 1 071 120 384 |
Tabel 2: Kritiek aantal transacties in Borland InterBase-servers
De hierboven genoemde beperkingen van Borland InterBase-servers zijn niet van toepassing op
Firebird-servers, met uitzondering van de vroegste versies 0.x, waarvan het bestaan al geschiedenis is geworden. Als u de definitieve versie Firebird 1.0 of InterBase 6.5-7.x gebruikt, hoeft u zich geen zorgen te maken over de punten 5, 6, 8 en 9 en kunt u uw inspanningen concentreren op andere oorzaken. Nu zullen we de meest voorkomende daarvan in detail bekijken.
2.3. Stroomstoringsfalen
Wanneer de stroom op de server wordt uitgeschakeld, worden alle activiteiten van gegevensverwerking
onderbroken op de meest onverwachte en (volgens de wet van Murphy) gevaarlijke
plaatsen. Als gevolg daarvan kan de informatie in de database worden vervormd of verloren gaan. Het eenvoudigste geval is wanneer alle niet-vastgelegde gegevens van clienttoepassingen verloren zijn gegaan als gevolg van een noodafsluiting van de server. Na een herstart na een stroomstoring analyseert de server de gegevens, merkt onvolledige transacties op die bij geen van de clients horen en annuleert alle wijzigingen die binnen deze “dode” transacties zijn aangebracht. Dergelijk gedrag is eigenlijk normaal en vanaf het begin voorzien door de InterBase-ontwikkelaars.
Een onderbreking van de stroomvoorziening wordt echter niet altijd alleen door dergelijke onbeduidende
verliezen gevolgd. Als de server op het moment van de stroomonderbreking bezig was met database-uitbreiding, is er een grote kans op weespagina’s in het databasebestand (pagina’s die fysiek zijn toegewezen en geregistreerd op de page inventory page (PIP), waarop het schrijven van gegevens onmogelijk is). Als u meer wilt weten over weespagina’s, zie het hoofdstuk “De structuur van de InterBase-database”.
Alleen het reparatie- en wijzigingshulpmiddel gfix (dat we hieronder zullen behandelen) is in staat om weespagina’s in het databasebestand aan te pakken. Weespagina’s leiden feitelijk tot onnodig verbruik van schijfruimte en zijn als zodanig niet de oorzaak van gegevensverlies of corruptie.
Stroomuitval leidt tot ernstiger schade. Bijvoorbeeld, na het uitschakelen van de
stroom en het herstarten kan een grote hoeveelheid gegevens, inclusief vastgelegde, verloren gaan (na het toevoegen of wijzigen waarvan een commando “commit transaction” werd uitgevoerd). Dit gebeurt omdat bevestigde gegevens niet rechtstreeks naar het databasebestand op schijf worden geschreven. En de bestandscache van het besturingssysteem (OS) wordt voor dit doel gebruikt. Het serverproces gaf het commando voor het schrijven van gegevens aan het OS. Vervolgens verzekerde het OS de server dat alle gegevens op schijf waren opgeslagen, terwijl de gegevens in werkelijkheid in de bestandscache waren opgeslagen. Het OS heeft geen haast om deze gegevens naar schijf te spoelen, omdat het van mening is dat er nog veel hoofdgeheugen over is en stelt langzame schrijfbewerkingen naar schijf uit totdat het hoofdgeheugen vol is.
2.4. Forced writes - snijdt aan twee kanten
Om de situatie te beïnvloeden, is in InterBase 6 een instelling voor de gegevensschrijfmodus voorzien. Deze parameter heet forced writes (FW) en heeft 2 modi - ON (synchroon) en OFF (asynchroon). FW-modi bepalen hoe InterBase met de schijf communiceert. Als FW is ingeschakeld, wordt de instelling voor synchrone schrijfacties naar schijf ingeschakeld, waarbij bevestigde gegevens direct na het commando commit naar schijf worden geschreven; de server wacht op de voltooiing van het schrijven en gaat pas daarna verder met verwerken. Als FW is uitgeschakeld, heeft InterBase geen haast om gegevens na het commando van transactiecommit naar schijf te schrijven en delegeert deze taak aan een parallelle thread, terwijl de hoofdthread doorgaat met gegevensverwerking zonder te wachten tot de schrijfacties naar schijf zijn voltooid. De synchrone schrijfmodus is een van de meest zorgvuldige en minimaliseert mogelijk gegevensverlies, maar kan enig prestatieverlies veroorzaken. De asynchrone schrijfmodus vergroot de kans op verlies van een groot aantal gegevens. Om maximale prestaties te bereiken, wordt meestal de FW Off-modus ingesteld. Maar als gevolg van een stroomonderbreking gaat er tijdens asynchrone schrijfacties een veel groter aantal gegevens verloren dan bij synchrone. Bij het instellen van de schrijfmodus moet u beslissen of een paar procent prestaties belangrijker is dan een paar uur werk als er onverwacht een stroomonderbreking optreedt.
Heel vaak gaan gebruikers onzorgvuldig met InterBase om. Kleine organisaties besparen op elk kleinigheidje, vaak op de computerserver waarop de DBMS-server en verschillende serverprogramma’s (en niet alleen server) ook zijn geïnstalleerd. Als deze vastlopen, drukken mensen zonder lang na te denken op RESET (dit gebeurt meerdere keren per dag). Hoewel InterBase zeer stabiel is tegen dergelijke activiteiten in vergelijking met andere DBMS’en en het mogelijk maakt om direct na een noodherstart met de database te werken, is dergelijk gebruik niet gewenst. Het aantal weespagina’s neemt toe en gegevens verliezen hun onderlinge verbindingen als gevolg van foutieve herstarts.
Dit kan lange tijd doorgaan, maar vroeg of laat komt er een einde aan. Wanneer er beschadigde pagina’s verschijnen tussen PIP- of generatorpagina’s, of als de databaseheaderpagina beschadigd is, kan de database mogelijk nooit meer worden geopend en wordt het een groot stuk losse gegevens waaruit men geen enkele byte nuttige informatie kan extraheren.
2.5. Corruptie van de harde schijf
Corruptie van de harde schijf leidt tot het ontbreken van belangrijke systeempagina’s van de database en/of corruptie van koppelingen tussen de overgebleven pagina’s. Dergelijke corrupties behoren tot de moeilijkste gevallen, omdat ze bijna altijd laagniveau-ingrijpen vereisen om de database te herstellen.
2.6. Fouten in databaseontwerp
Het is noodzakelijk dat u op de hoogte bent van enkele fouten die door databaseontwikkelaars worden gemaakt
en die kunnen leiden tot de onmogelijkheid om de database te herstellen vanaf een back-upkopie (*.gbk-bestanden gemaakt door het programma gbak). Allereerst is dit een onzorgvuldig gebruik van constraints op databaseniveau. Een typisch voorbeeld is de constraint NOT NULL. Laten we aannemen dat we een tabel hebben die gevuld is met een aantal records. Nu voegen we aan deze tabel met behulp van het commando ALTER TABLE nog een kolom toe en geven aan dat deze geen niet-gedefinieerde waarden NULL mag bevatten. Zoiets als dit:
ALTER TABLE sometable Field/INTEGER NOT NULL
En in dit geval zal er geen serverfout optreden zoals men zou kunnen verwachten. Deze
metadata-wijziging wordt vastgelegd en we ontvangen geen fout- of waarschuwingsmelding, wat een illusie van normaliteit van deze situatie creëert.
Als we echter een back-up van de database maken en proberen deze vanaf een back-upkopie te herstellen, ontvangen we
een foutmelding tijdens de herstelfase (omdat NULL-waarden worden ingevoegd in de kolom die een NOT NULL-beperking heeft, en het herstelproces wordt onderbroken). (De belangrijke opmerking van Craig Stuntz - vanaf versie InterBase 7.1 worden beperkingen standaard genegeerd tijdens het herstellen (dit kan worden geregeld via een opdrachtregelschakelaar) en kan vrijwel elke niet-beschadigde back-up worden hersteld. Het is altijd een goed idee om een testherstel uit te voeren na het maken van een back-up, maar dit probleem zou grotendeels moeten verdwijnen in versie 7.1.) Deze back-upkopie kan niet worden hersteld. Als het herstellen werd gericht naar een bestand met dezelfde naam als de bestaande database (tijdens het herstellen werd het werkbestand van de bestaande database overschreven), verliezen we alle informatie.
Dit hangt samen met het feit dat NOT NULL-beperkingen worden geïmplementeerd door systeemtriggers die alleen binnenkomende gegevens controleren. Tijdens het herstellen worden de gegevens uit de back-upkopie ingevoegd in de lege, zojuist aangemaakte tabellen - hier kunnen we ontoelaatbare NULL-waarden aantreffen in de kolom met een NOT NULL-beperking.
Sommige ontwikkelaars beschouwen dergelijk InterBase-gedrag als onjuist, maar anders zou het onmogelijk zijn om een veld met een NOT NULL-beperking aan een databasetabel toe te voegen.
Een vraag over de vereiste standaardwaarde en het invullen daarmee op het moment van
aanmaken werd uitgebreid besproken door Firebird-architecten, maar werd niet aanvaard vanwege het feit dat de programmeur deze uiteraard zal invullen volgens het algoritme, dat nogal ingewikkeld en misschien iteratief is. Maar er is geen garantie of hij in staat zal zijn de records die door de vorige iteratie zijn genegeerd te onderscheiden van niet-ingevulde records of niet.
Een soortgelijk probleem kan worden veroorzaakt door een fout in de garbage collection vanwege het instellen van een onjuist pad naar de database (de oorzaak van corruptie 3) op het moment van verbinding en bestandstoegang tot databasebestanden wanneer de server ermee werkt (de oorzaak van corruptie 4), en records die volledig met NULL zijn gevuld kunnen in sommige tabellen verschijnen. Het is zeer moeilijk om deze records te detecteren, omdat ze niet overeenkomen met de beperkingen van integriteitscontrole, en de operator Select ziet ze gewoon niet, hoewel ze wel in de back-upkopie terechtkomen. Als het om deze reden onmogelijk is om te herstellen, moet men het programma gfix uitvoeren (zie hieronder), deze records vinden en verwijderen met behulp van niet-geïndexeerde velden als zoekvoorwaarden, en daarna opnieuw proberen een back-upkopie te maken en de database daaruit te herstellen. Tot slot kunnen we zeggen dat er een groot aantal oorzaken van databasecorruptie is en dat u altijd op het ergste voorbereid moet zijn - dat uw database om de een of andere reden beschadigd raakt. U moet ook klaar zijn om waardevolle informatie te herstellen en op te slaan. En nu zullen we de voorzorgsmaatregelen bekijken die de beveiliging van InterBase-databases garanderen, evenals methoden voor het repareren van beschadigde databases.
2.7. Voorzorgsmaatregelen tegen InterBase-databasecorruptie
Om databasecorruptie te voorkomen, moet men altijd back-upkopieën maken (als u meer wilt weten over back-ups, zie dan het hoofdstuk “Back-up en herstel”). Het is de meest betrouwbare manier tegen databasecorruptie. Alleen een back-up geeft 100% garantie op databasebeveiliging. Zoals hierboven beschreven, kunnen we als resultaat van een back-up een nutteloze kopie krijgen (een kopie die niet kan worden hersteld), daarom mag het herstellen van een database vanaf de kopie niet worden uitgevoerd door over het script te schrijven en moet de back-up volgens bepaalde regels worden gemaakt. Ten eerste moet de back-up zo vaak mogelijk worden uitgevoerd, ten tweede moet deze serieel zijn en ten derde moeten back-upkopieën worden gecontroleerd op herstelmogelijkheid.
Vaak betekent back-up dat het noodzakelijk is om vrij vaak een back-upkopie te maken, bijvoorbeeld eens per vierentwintig uur. Hoe korter de gegevensperiode tussen de databaseback-ups, hoe minder gegevens verloren gaan als gevolg van een storing. Opeenvolging van back-ups betekent dat het aantal back-ups moet toenemen en ten minste een week moet worden bewaard. Als er een mogelijkheid is, is het noodzakelijk om back-ups naar speciale apparaten zoals een streamer te schrijven, maar zo niet - kopieer ze dan gewoon naar de andere computer. De geschiedenis van back-upkopieën helpt verborgen corrupties te ontdekken en om te gaan met de fout die lang geleden is ontstaan en onverwacht opdook. Men moet controleren of het mogelijk is de ontvangen back-up zonder fouten te herstellen of niet. Het kan slechts op één manier worden gecontroleerd - via het testherstelproces. Er moet worden gezegd dat het herstelproces 3 keer meer tijd kost dan een back-up, en het is moeilijk om dagelijks herstelvalidatie uit te voeren voor grote databases, omdat het het werk van gebruikers voor een paar uur kan onderbreken (een nachtpauze is mogelijk niet voldoende).
Het zou beter zijn als grote organisaties niet op “lucifers” zouden bezuinigen en één computer voor deze doeleinden zouden reserveren.
In dit geval, als de server 24 uur per dag, 7 dagen per week met zware belasting moet werken, kunnen we het SHADOW-mechanisme gebruiken voor het maken van momentopnamen van de database en verdere back-upbewerkingen vanaf de onmiddellijke kopie. Het back-upproces en het herstellen van de database wordt in detail beschreven in het hoofdstuk “Back-up en herstel”. Bij het maken van een back-up en het vervolgens herstellen van de database daaruit, vindt hercreatie van alle gegevens in de database plaats. Dit proces (back-up/herstel of b/r) draagt bij aan de correctie van de meeste niet-fatale fouten in de database, verbonden met harde-schijfcorrupties, het detecteren van problemen met integriteit in de database, het opschonen van de database van afval (oude versies en fragmenten van records, onvolledige transacties), en het aanzienlijk verkleinen van de databasegrootte.
Regelmatige b/r is een garantie voor de beveiliging van InterBase-databases. Als de database werkt, wordt aanbevolen om elke week b/r uit te voeren. Eerlijk gezegd zijn er enkele voorbeelden van InterBase-databases die jarenlang intensief worden gebruikt zonder back-up/herstel.
Desalniettemin is het voor de zekerheid wenselijk om deze procedure uit te voeren, vooral omdat deze eenvoudig kan worden geautomatiseerd (zie hoofdstuk “Back-up”).
Als het om de een of andere reden onmogelijk is om vaak back-up/herstel uit te voeren, dan kan men de tool gfix gebruiken voor het controleren en herstellen van de database. gfix maakt het mogelijk om veel fouten te controleren en te verwijderen zonder b/r.
2.8. Opdrachtregeltool gfix
Opdrachtregeltool gfix wordt gebruikt voor het controleren en herstellen van de database. Bovendien kan gfix ook verschillende activiteiten van databasebeheer uitvoeren: het wijzigen van het databasedialect, het instellen en annuleren van de modus “alleen-lezen”, het instellen van de cachegrootte voor een concrete database en ook enkele belangrijke functies (u kunt erover lezen in InterBase 6 Operations Guide [4.) gfix wordt uitgevoerd in een opdrachtregelmodus en heeft de volgende syntaxis:
Gfix [ opties] db-naam
Opties - is een set opties voor het uitvoeren van gfix, db-naam is een naam van de database waarover bewerkingen zullen worden uitgevoerd, gedefinieerd door de set opties. Tabel 3 toont gfix-opties met betrekking tot databasereparatie:
| Optie | Beschrijving |
| -f[ull] | Deze optie wordt gebruikt in combinatie met -v en betekent dat het tijd is om alle fragmenten van records te controleren |
| -i[gnore] | Optie laat gfix checksumfouten negeren op het moment van validatie of databaseopschoning |
| -m[end] | Markeert beschadigde records als niet beschikbaar, als gevolg waarvan ze zullen worden verwijderd tijdens de volgende back-up/herstel. Optie wordt gebruikt op het moment van het voorbereiden van een beschadigde database op b/r. |
| -n[o_update] | Optie wordt gebruikt in combinatie met -v voor alleen-lezen databasevalidatie zonder het corrigeren van corrupties |
| -pas[sword] | Optie maakt het mogelijk het wachtwoord in te stellen bij het verbinden met de database. (Merk op dat dit de fout is in InterBase-documentatie -pa[ssword], maar de afkorting “-pa” zal niet werken - gebruik “-pas”) |
| -user | Optie maakt het mogelijk de gebruikersnaam in te stellen bij het verbinden met de database |
| -v[alidate] | Optie die databasevalidatie vooraf instelt op de manier waarop fouten worden ontdekt |
| -m[ode] | Optie die de schrijfmodus voor de database instelt - voor alleen-lezen of lezen/schrijven. Deze parameter kan 2 waarden accepteren - read write of read only. |
| -w[rite] {sync | async} | Optie die de modus synchroon/asynchroon geforceerd schrijven naar de database aan- en uitzet. sync - om synchroon schrijven aan te zetten (FW ON); async - om asynchroon schrijven aan te zetten (FW OFF); |
Tabel 1: gfix-toolopties voor databaseherstel
Er zijn enkele typische voorbeelden van het gebruik van gfix:
gfix -w sync -user SYSDBA -pass masterkey firstbase.gdb
In dit voorbeeld stellen we voor onze testdatabase firstbase.gdb de modus synchroon schrijven in (FW ON). (Natuurlijk is dit nuttig voordat de corruptie optreedt). En hieronder staat de eerste opdracht die u moet gebruiken om de database te controleren nadat de corruptie is opgetreden:
gfix -v -full -user SYSDBA -pass masterkey firstbase.gdb
In dit voorbeeld starten we het controleren van onze testdatabase (optie -v) en geven we aan dat fragmenten van records ook moeten worden gecontroleerd (optie -full). Natuurlijk is het handiger om verschillende opties voor het controle- en herstelproces in te stellen via een GUI, maar we zullen de functies van databaseherstel bekijken met behulp van opdrachtregeltools. Deze tools zijn inbegrepen bij InterBase en u kunt er zeker van zijn dat hun gedrag hetzelfde zal zijn op alle besturingssystemen waarop InterBase draait. Het is zeer belangrijk dat ze altijd in de buurt zijn.
Bovendien gebruiken de bestaande tools die het mogelijk maken databasebeheer vanaf een
clientcomputer uit te voeren hiervoor de Services API, die niet wordt ondersteund door de Classic-architectuur van de InterBase-server. Dat betekent dat u producten van derden kunt gebruiken met de SuperServer-architectuur van de server.
2.9. Het repareren van een beschadigde database
Laten we aannemen dat er enkele fouten in onze database zijn. Ten eerste moeten we het bestaan van deze fouten controleren; ten tweede moeten we proberen deze fouten te corrigeren. U dient de volgende instructies in acht te nemen.
U moet de InterBase-server stoppen als deze nog draait en een kopie maken van het bestand of de databasebestanden. Alle herstelactiviteiten mogen alleen worden uitgevoerd met een databasekopie, omdat de gekozen manier tot een ongelukkig resultaat kan leiden, en u zult een herstelprocedure opnieuw moeten starten (vanaf een beginpunt). Na het maken van een kopie voeren we de volledige databasevalidatie uit (controle van fragmenten van records).
We moeten hiervoor de volgende opdracht uitvoeren:
gfix -v - full corruptbase gdb -user SYSDBA - password
In dit geval is corruptbase.gdb - een kopie van de beschadigde database. Een opdracht zal
de database controleren op structurele corruptie en de lijst met onopgeloste problemen geven. Als dergelijke fouten worden gedetecteerd, moeten we de beschadigde gegevens verwijderen en ons voorbereiden op back-up/herstel met behulp van de volgende opdracht:
gfix -mend -user SYSDBA -password your_masterkey corruptbase gdb
Na het uitvoeren van een opdracht moet u controleren of er nog fouten in de database aanwezig zijn. U moet hiervoor gfix uitvoeren met de opties -v -full, en wanneer het proces is voltooid, een databaseback-up uitvoeren:
gbak -b -v -ig -user SYSDBA -password corruptbase.gdb corruptbase.gbk
Deze opdracht voert een databaseback-up uit (optie - b zegt dit) en we krijgen gedetailleerde informatie over de uitvoering van het back-upproces (optie -v). Fouten met betrekking tot checksums worden genegeerd (optie - ig). Als u meer informatie wilt over de opties van de opdrachtregeltool gbak, kunt u deze vinden in het hoofdstuk “Back-up en herstel”. Als er fouten zijn met de back-up, moet u deze in een andere configuratie starten:
gbak -b -v -ig -g -user SYSDBA -password corruptbase.gdb
corruptbase.gbk
Waarbij optie - g de garbage collection tijdens de back-up uitschakelt. Dit helpt vaak om een probleem met de back-up op te lossen.
Het kan ook mogelijk zijn om een back-up van de database te maken als we de database daarvoor in de alleen-lezenmodus zetten. Deze modus voorkomt het schrijven van wijzigingen naar de database en helpt soms om een back-up van een beschadigde database uit te voeren. Om de database in de alleen-lezenmodus te zetten, moet u de volgende opdracht gebruiken: gfix -m read _only
-user SYSDBA -password masterkey Disk:\Path\file.gdb
Probeer daarna opnieuw een databaseback-up te maken met de hierboven gegeven parameters.
Als de back-up succesvol is gemaakt, moet u de database herstellen vanaf de back-upkopie. Gebruik hiervoor de volgende opdracht:
gbak -c -user SYSDBA -password masterkey Disk:\Path\backup.gbk
Disk:\Path\newbase,gdb
Bij het herstellen van de database kunt u problemen tegenkomen, vooral bij het aanmaken van de indexen. In dat geval moeten de opties -inactive en -one_at_a_time aan de herstelopdracht worden toegevoegd. Deze opties deactiveren indexen bij het aanmaken vanuit de databaseback-up en bevestigen de gegevens per tabel.
2.10. Hoe u kunt proberen gegevens uit een beschadigde database te halen
Het is mogelijk dat de hierboven beschreven handelingen niet tot databaseherstel leiden. Dat betekent dat de database ernstig beschadigd is, of niet als één geheel kan worden hersteld, of dat er zeer veel inspanning nodig is voor het herstel. Men kan bijvoorbeeld systeemmetadata wijzigen, niet-gedocumenteerde functies gebruiken, enzovoort. Het is zeer zwaar, langdurig en ondankbaar werk met twijfelachtige slaagkansen. Probeer dit, indien mogelijk, te vermijden en gebruik andere methoden. Als een beschadigde database opent en het toestaat lees- en wijzigingsbewerkingen op sommige gegevens uit te voeren, moet u van deze mogelijkheid gebruikmaken en de gegevens redden door ze naar een nieuwe database te kopiëren, en voorgoed afscheid te nemen van de oude.
Voordat u de gegevens uit de oude database overzet, moet u dus eerst een doeldatabase aanmaken. Als de database lange tijd niet is gewijzigd, kunt u de oude back-up gebruiken, waaruit metadata kunnen worden gehaald voor het aanmaken van een doeldatabase. Op basis van deze metadata moet u een doelbestand aanmaken en beginnen met het kopiëren van de gegevens. De hoofdtaak is het extraheren van de gegevens uit een beschadigde database. Daarna moeten we de gegevens in een nieuwe database onderbrengen, maar dat is niet erg moeilijk, zelfs als we de databasestructuur uit het geheugen moeten herstellen. Bij het extraheren van gegevens uit tabellen moet u het volgende algoritme van handelingen gebruiken:
- Probeer eerst SELECT* FROM tabel N uit te voeren. Als dit normaal verloopt, kunt u de verkregen gegevens opslaan in een externe bron. Het is beter om gegevens op te slaan in een script (bijna alle GUI’s bieden deze functie), tenzij de tabel geen BLOB-velden bevat. Als er BLOB-velden in de tabel zitten, moeten de gegevens daaruit door een clientprogramma dat als tussenpersoon fungeert naar een andere database worden opgeslagen. Misschien moet u dit eenvoudige programma speciaal voor gegevensherstel schrijven.
- Als het niet lukt alle gegevens op te halen, moet u alle indexen verwijderen en het opnieuw proberen. Indexen kunnen eigenlijk vanaf het begin van het herstel uit alle tabellen worden verwijderd, omdat ze toch niet meer nodig zijn. Als u uiteraard geen metadatastructuur hebt die gelijk is aan de beschadigde, is het noodzakelijk een protocol bij te houden van alle handelingen die u op de beschadigde brondatabase uitvoert.
- Als u na het verwijderen van de indexen nog steeds niet alle gegevens uit de tabel kunt lezen, kunt u een bereikquery op de primaire sleutel proberen. Dat betekent een bepaald gegevensbereik selecteren. Bijvoorbeeld:
SELECT * FROM tabel N WHERE veld_PK >=0 and veld_PK <=10000 Veld_PK
is hier een primaire sleutel. InterBase heeft een paginagebaseerde gegevensorganisatie en daarom kan een bereikquery op waarden behoorlijk effectief zijn, hoewel het op iets als sjamanisme lijkt. Toch werkt het, omdat we gegevens uit de query van beschadigde pagina’s kunnen weren en gelukkig de andere kunnen lezen. U kunt zich onze stelling herinneren dat er geen vaste volgorde is voor het opslaan van records in SQL. Niemand garandeert echt dat een niet-geordende query bij herstarts de records in dezelfde volgorde teruggeeft, maar fysieke records worden binnen de database toch in een vaste interne volgorde opgeslagen. Het is duidelijk dat de server de records niet zomaar door elkaar gooit alleen om aan de SQL-standaard te voldoen. U kunt proberen deze interne volgorde te gebruiken bij het extraheren van gegevens uit een beschadigde database (als u meer wilt weten over gegevenspagina’s en hun onderlinge verbanden, zie dan het hoofdstuk “Structuur van InterBase-database”).
Vitaliy Barmin, een van de ervaren Russische InterBase-ontwikkelaars, meldde dat hij op deze manier tot 98% van de informatie uit een onherstelbare database wist te herstellen (er was een groot aantal beschadigde pagina’s). Gegevens uit een beschadigde database moeten dus worden verplaatst naar een nieuwe database of naar externe bronnen zoals SQL-scripts. Let bij het kopiëren van de gegevens op de generatorwaarden in de beschadigde database (deze moeten worden opgeslagen om correct werken in de nieuwe database te hervatten). Als u geen volledige kopie van de metadata hebt, moet u de teksten van stored procedures, triggers, constraints en indexdefinities extraheren.
2.11. Herstel van een hopeloze database
Over het algemeen kan het herstellen van een database zeer lastig en moeilijk zijn en daarom is het beter een back-upkopie van de database te maken dan beschadigde gegevens te herstellen, en wat er ook gebeurt, u moet niet wanhopen, want in de moeilijkste situaties kan een oplossing worden gevonden. En nu bekijken we 2 gevallen.
Het eerste geval (een klassiek probleem). Een back-up die niet kan worden hersteld vanwege NULL-waarden in de kolom met NOT NULL-constraints (het herstelproces werd uitgevoerd over het werkbestand). Het werkbestand werd gewist en het herstelproces werd onderbroken vanwege een fout. En als gevolg van ondoordachte handelingen kregen we een grote hoeveelheid nutteloze gegevens (die niet kunnen worden hersteld) in plaats van een back-upkopie. Maar de oplossing werd gevonden. De programmeur wist zich te herinneren welke tabel en welke kolom NOT NULL-constraints hadden. Het back-upbestand werd in een hexadecimale editor geladen. En daar werd door te zoeken een combinatie van bytes gevonden die overeenkwam met de definitie van deze kolom. Na talloze experimenten bleek dat de NOT NULL-constraint ergens nabij de kolomnaam een 1 toevoegt. In de HEX-editor werd deze “1” gecorrigeerd naar “0” en de back-upkopie werd hersteld. Na dat geval onthield de programmeur voor eens en altijd hoe het back-up- en herstelproces moet worden uitgevoerd.
Het tweede geval. De situatie was catastrofaal. De database raakte beschadigd tijdens de uitbreidingsfase vanwege een gebrek aan schijfruimte. Bij het vergroten van de database maakt de server een reeks kritiek belangrijke pagina’s aan (bijvoorbeeld de transactie-inventarispagina en de pagina-inventarispagina, extra pagina’s voor de RDB$Pages-relatie) en schrijft deze naar het einde van de database. Als gevolg daarvan opende de database niet, noch met beheerhulpmiddelen, noch met het hulpprogramma GBAK. En wanneer we probeerden verbinding te maken met de database, verscheen er een foutmelding (“Unexpected end of file”).
Toen we het hulpprogramma gfix uitvoerden, gebeurden er vreemde dingen: het programma werkte in een eindeloze lus. Terwijl gfix draaide, schreef de server met hoge snelheid fouten naar het logboek (bestand InterBase log) (ongeveer 100 Kb per seconde). Als gevolg daarvan vulde het logbestand zeer snel alle vrije schijfruimte. We moesten zelfs een programma schrijven dat dit logboek met een timer wiste. Dit proces duurde lang - gfix draaide meer dan 16 uur zonder enig resultaat. Het logboek vulde zich met fouten van de volgende vorm: “Page XXX doubly allocated”. In de InterBase-broncode (in bestand val.#) staat een korte beschrijving van deze fout. Er staat dat deze fout optreedt wanneer dezelfde gegevenspagina twee keer wordt gebruikt. Het is duidelijk dat deze fout het gevolg is van beschadiging van kritiek belangrijke pagina’s.
Na enkele dagen van mislukte experimenten werden de pogingen om de gegevens op standaardmanieren te herstellen uiteindelijk gestaakt. Daarom moesten we gebruikmaken van laagniveau-analyse van de gegevens die in de beschadigde database waren opgeslagen.
Alexander Kozelskiy, hoofd van de afdeling Informatietechnologie van East View Publications Inc, is de bedenker van het idee hoe informatie uit dergelijke onherstelbare databases kan worden gehaald.
De herstelmethode die we als resultaat van onderzoek verkregen, was gebaseerd op het feit dat de database een paginastructuur heeft en gegevens uit elke tabel per gegevenspagina worden verzameld. Elke gegevenspagina bevat een identificatie van de tabel waarvoor deze gegevens opslaat. Het was vooral belangrijk om gegevens uit enkele kritieke tabellen te herstellen. Er waren gegevens uit vergelijkbare tabellen, afkomstig van een oude back-upkopie die perfect werkte en als patroon kon dienen. De patroondatabase werd in een editor voor hexadecimale bronnen geladen en vervolgens zochten we naar de patronen van de gegevens die ons interesseerden. Deze gegevens werden in hexadecimaal formaat naar een buffer gekopieerd en daarna werden de resten van de beschadigde database in de editor geladen. Een bytereeks die overeenkwam met het patroon werd in de beschadigde database gevonden, en de pagina (waarop deze reeks werd gevonden) werd geanalyseerd.
Eerst bepaalden we de beginpagina, maar dat was niet moeilijk omdat de grootte van het databasebestand deelbaar is door de grootte van de gegevenspagina. Het nummer van de huidige byte gedeeld door de paginagrootte - 8192 bytes - wordt afgerond naar een geheel getal (en zo kregen we het nummer van de huidige pagina). Vervolgens vermenigvuldigden we het nummer van de huidige pagina met de paginagrootte en kregen we het bytenummer dat overeenkwam met het begin van de huidige pagina. Na analyse van de header bepaalden we het type van de pagina (voor pagina’s met gegevens is het type 5 - zie bestand ods.h uit de set InterBase-broncode en ook het hoofdstuk “De structuur van InterBase Database”) evenals de identificatie van de benodigde tabel.
Daarna werd een programma geschreven dat de hele database analyseerde, alle pagina’s voor de benodigde tabel in één geheel verzamelde en naar een bestand verplaatste.
Toen we zo de gegevens hadden die we in eerste instantie nodig hadden, begonnen we de inhoud van de geselecteerde pagina’s te analyseren. InterBase maakt op grote schaal gebruik van gegevenscompressie om ruimte te besparen. Een string zoals VARCHAR met de string “ABC” wordt bijvoorbeeld opgeslagen als een reeks van de volgende waarden: stringlengte (2 bytes), in ons geval 0003, en dan de symbolen zelf en dan een controlesom. We moesten een analyser voor strings en andere databasetypen schrijven die gegevens van hexadecimaal formaat naar een gewone weergave omzet. We slaagden erin tot 80% van de informatie uit enkele kritieke tabellen te extraheren met behulp van een “handmatige” methode voor het analyseren van de database-inhoud. Later ontwikkelden Oleg Kulkov en Alexey Kovyazin, een van de auteurs van dit boek, op basis van deze ervaring het hulpprogramma InterBase Surgeon dat directe toegang tot de database uitvoert, de InterBase-engine omzeilt en het mogelijk maakt de gegevens in een InterBase-database op de juiste manier direct te lezen en te interpreteren.
Met InterBase Surgeon lukt het ons om oorzaken van beschadiging te detecteren en tot 90% te herstellen van absoluut onherstelbare databases die niet door InterBase kunnen worden geopend en niet met standaardmethoden kunnen worden hersteld.
U kunt dit programma downloaden van de officiële programmasite www.ib-aid.com.
3. Dankwoord
Ik wil graag iedereen bedanken die mij heeft geholpen bij het maken van deze handleiding:
Craig Stuntz, Alexander Nevsky, Konstantin Sipachev, Tatjana Sipacheva en alle andere vriendelijke en deskundige mensen uit de InterBase- en Firebird-gemeenschap.
Als u suggesties of vragen over dit hoofdstuk hebt, kunt u gerust een e-mail sturen.
© 2002 AIexey Kovyazin, Serge Vostrikov.
Copyright © 2004 IBSurgeon Team. Alle rechten voorbehouden.