Tato stránka byla strojově přeložena. Přečtěte si anglický originál. English

Knihovna IBSurgeon

"Nemůže potvrdit index" aneb jak přečerpat data z částečně obnovené (nekonzistentní) databáze

Alexey Kovyazin, poslední aktualizace 30. března 2014

Po opravě poškození je časté vidět chybu “Cannot commit index” při kroku obnovy. Ve Firebirdu 2.0 a novějších se to zobrazí jako varování a databáze nebude uvedena do online stavu; ve Firebirdu 1.0-1.5 a InterBase se to projeví jako velmi nepříjemná chyba, která zastaví proces obnovy (je působivé vidět tuto chybu na konci obnovy 200GB databáze).

Důvod chyby “Cannot commit index..” je zřejmý: poškození ovlivňuje referenční integritu databáze a záznamy mizí magickým (z pohledu serveru) způsobem.

Například máte tabulku “Customers” a přidruženou tabulku “Orders” odkazovanou cizím klíčem. Bez poškození není možné porušit cizí klíč a smazat záznam z Customers bez předchozího smazání všech objednávek, které se vztahují k danému zákazníkovi. Poškození ovlivňuje databázový soubor na nízké úrovni a zabíjí záznamy přímo. Jaké příjemné překvapení pro server vidět nevyřešené odkazy na hlavní záznamy ze záznamů cizích klíčů.

Zde musím přidat tip o procesu obnovy: engine obnovuje všechny tabulky s neaktivovanými indexy (díky tomu je plnění tabulek záznamy mnohem rychlejší) a poté začne aktivovat (tj. vytvářet) indexy jeden po druhém. To znamená, že všechna data jsou již v databázi, když proces obnovy začne krok vytváření indexů, a vy vidíte chybu “Cannot commit index..”.

No, první přání, když vidíte chybu “Cannot commit index”, je odstranit příslušné omezení cizího klíče, aby bylo možné dokončit obnovu. Otázkou je, co uděláme s nekonzistentní, ale úspěšně obnovenou databází: odstraněný cizí klíč může být důležitou součástí obchodní logiky.

Existují 2 přístupy: znovuvytvoření chybějících dat nebo odstranění nekonzistentních dat. Podívejme se, co to znamená na příkladu Customers-Orders výše.

Znovuvytvoření chybějících dat

Takže jste se rozhodli, že potřebujete znovuvytvořit chybějící zákazníky pro nekonzistentní objednávky. Tímto způsobem musíte určit ztracená ID. Obvykle používám SQL dotaz jako tento (myslím, že bude snadné ho přizpůsobit):

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

Poté můžete ručně vložit záznamy se seznamem chybějících primárních klíčů a spustit zálohu/obnovu znovu.

Přečerpání konzistentních dat

Pokud si myslíte, že je přijatelné ztratit nekonzistentní záznamy, můžete přečerpat všechna data z částečně obnovené databáze do prázdné databáze a jednoduše přeskočit nekonzistentní záznamy pomocí následujícího přístupu:

  1. Stáhněte si bezplatný nástroj IBDataPump http://www.clevercomponents.com/demo/datapump/IBPump.zip

  2. Vytvořte pouze metadata databáze ze zálohy opravené databáze (po IBFirstAID) pomocí příkazu

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

  1. Spusťte IBDataPump a nastavte částečně opravenou databázi jako zdroj a čerstvou prázdnou databázi jako cíl

  2. Klikněte na další záložky, klikněte na příslušná tlačítka a na 3. záložce klikněte na “Pump”. Počkejte na dokončení (může to být dlouhý proces, pro představu můžete sledovat růst velikosti cílové databáze).

  3. Výsledkem bude databáze fresh.fdb s konzistentními vztahy cizích klíčů - je plně v pořádku.

Pokud má databáze smyčku s cizími klíči, IBDataPump vás upozorní a poskytne seznam takových omezení - jedno nebo více z nich by mělo být odstraněno, než bude přečerpání možné.

Samozřejmě existovaly případy, kdy přečerpání vyžadovalo speciální přístup, a pokud se s takovou situací setkáte, kontaktujte prosím naši podporu.