Deze pagina is automatisch vertaald. Lees het Engelse origineel. English

IBSurgeon-bibliotheek

"Kan index niet committen" of hoe gegevens te pompen uit een gedeeltelijk herstelde (inconsistente) database

Alexey Kovyazin, laatste update 30-maart-2014

Na het herstellen van corrupties is het vaak zo dat je de foutmelding “Cannot commit index” tegenkomt tijdens de herstelstap. In Firebird 2.0 en later verschijnt dit als een waarschuwing en wordt de database niet online gebracht; in Firebird 1.0-1.5 en InterBase treedt dit op als een zeer vervelende fout die het herstelproces stopt (het is indrukwekkend om deze fout aan het einde van een herstel van een 200Gb database te zien).

De reden van de “Cannot commit index..” fout is duidelijk: corruptie tast de referentiële integriteit van de database aan, en records verdwijnen op een magische manier (vanuit het perspectief van de server).

Bijvoorbeeld, je hebt een tabel “Customers” en een bijbehorende tabel “Orders” die via een Foreign key wordt gerefereerd. Zonder corruptie is het niet mogelijk om de Foreign key te schenden en een record uit Customers te verwijderen zonder eerst alle orders te verwijderen die naar een bepaalde klant verwijzen. Corruptie tast het databasebestand op laag niveau aan en verwijdert records direct. Wat een leuke verrassing voor de server om onopgeloste verwijzingen naar masterrecords vanuit foreign key records te zien.

Hier moet ik een tip toevoegen over het herstelproces: de engine herstelt alle tabellen met niet-geactiveerde indexen (dit maakt het vullen van tabellen met records veel sneller), en daarna begint het met het activeren (d.w.z. opbouwen) van indexen één voor één. Dit betekent dat alle gegevens al in de database staan wanneer het herstelproces de stap van het aanmaken van indexen start en je de “Cannot commit index..” fout ziet.

Nou, de eerste wens wanneer je de “Cannot commit index” fout ziet, is om de betreffende Foreign key constraint te verwijderen om het herstel te laten voltooien. De vraag is wat we gaan doen met een inconsistente, maar succesvol herstelde database: een verwijderde foreign key kan een belangrijk onderdeel zijn van de bedrijfslogica.

Er zijn 2 benaderingen: ontbrekende gegevens opnieuw creëren of inconsistente gegevens verwijderen. Laten we eens kijken wat dit betekent voor het Customers-Orders voorbeeld hierboven.

Hercreatie van ontbrekende gegevens

Dus je hebt besloten dat je ontbrekende Customers voor inconsistente Orders opnieuw moet creëren. Op deze manier moet je verloren ID’s bepalen. Meestal gebruik ik een SQL-query zoals deze (ik denk dat het gemakkelijk aan te passen is):

SELECT O.Customer_ID FROM ORDERS O WHERE NOT EXISTS ( SELECT C.Customer_ID FROM CUSTOMERS C WHERE O.Customer_ID=C.Customer_ID)

Daarna kun je handmatig records invoegen met de lijst van ontbrekende primaire sleutels, en opnieuw een backup/restore uitvoeren.

Overpompen van consistente gegevens

Als je denkt dat het acceptabel is om inconsistente records te verliezen, kun je alle gegevens van de gedeeltelijk herstelde database naar een lege database pompen en gewoon inconsistente records overslaan, met behulp van de volgende aanpak:

  1. Download het gratis hulpmiddel IBDataPump http://www.clevercomponents.com/demo/datapump/IBPump.zip

  2. Maak alleen een metadata-database van de backup van de gerepareerde database (na IBFirstAID) met behulp van het commando

gbak -c -m -user SYSDBA -pass masterkey Disk:\Path\backup.fbk Disk:\Path\fresh.fdb

  1. Voer IBDataPump uit en stel de gedeeltelijk gerepareerde database in als Bron, en de verse lege database als doel

  2. Klik op de volgende tabbladen, klik op de juiste knoppen en op het 3e tabblad klik op “Pump”. Wacht tot het voltooid is (dit kan een lang proces zijn; om een idee te krijgen kun je de groeidynamiek van de doeldatabasegrootte controleren).

  3. Als resultaat heb je een fresh.fdb database met consistente foreign key-relaties - dat is volledig in orde.

Als de database een lus heeft met foreign keys, zal IBDataPump je waarschuwen en een lijst van dergelijke constraints geven - één of meer ervan moeten worden verwijderd voordat pompen mogelijk is.

Natuurlijk zijn er gevallen geweest waarin pompen een speciale aanpak vereiste, en als je zo’n situatie tegenkomt, neem dan contact op met onze ondersteuning.