Ова страница је машински преведена. Прочитајте енглески оригинал. English

IBSurgeon библиотека

„Cannot commit index“ или како препумпати податке из делимично обновљене (неконзистентне) базе података

Alexey Kovyazin, последње ажурирање 30-март-2014

Након поправљања оштећења, често се јавља грешка „Cannot commit index" при кораку враћања. У Firebird 2.0 и новијим верзијама ово долази као упозорење и база података неће бити стављена на мрежу; у Firebird 1.0-1.5 и InterBase ово се јавља као веома непријатна грешка која зауставља процес враћања (импресивно је видети ову грешку на крају враћања базе од 200Gb).

Разлог грешке „Cannot commit index.." је очигледан: оштећење утиче на референцијални интегритет базе података, и записи нестају на магичан (са становишта сервера) начин.

На пример, имате табелу „Customers" и повезану табелу „Orders" референцирану страним кључем. Без оштећења није могуће прекршити страни кључ и обрисати запис из Customers без претходног брисања свих поруџбина које се односе на одређеног купца. Оштећење утиче на датотеку базе на ниском нивоу и директно убија записе. Какво лепо изненађење за сервер да види нерешене везе ка главним записима из записа са страним кључем.

Овде морам да додам савет о процесу враћања: мотор враћа све табеле са неактивираним индексима (то чини попуњавање табела записима много бржим), а затим почиње да активира (тј. гради) индексе један по један. То значи да су сви подаци већ у бази када процес враћања почне корак креирања индекса и видите грешку „Cannot commit index..".

Па, прва жеља када видите грешку „Cannot commit index" је да уклоните одговарајуће ограничење страног кључа како бисте омогућили да се враћање заврши. Питање је шта ћемо урадити са неконзистентном, али успешно враћеном базом: уклоњени страни кључ може бити важан део пословне логике.

Постоје 2 приступа овде: поново креирати недостајуће податке или уклонити неконзистентне податке. Погледајмо шта то значи на примеру Customers-Orders изнад.

Поновно креирање недостајућих података

Дакле, одлучили сте да треба поново да креирате недостајуће Customers за неконзистентне Orders. На овај начин треба да одредите изгубљене ID-јеве. Обично користим SQL упит као што је овај (мислим да ће бити лако прилагодити га одговарајућем):

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

Након тога можете ручно уметнути записе са списком недостајућих примарних кључева, и поново покренути резервну копију/враћање.

Препумпавање конзистентних података

Ако мислите да је прихватљиво изгубити неконзистентне записе, можете препумпати све податке из делимично враћене базе у празну базу и једноставно прескочити неконзистентне записе, користећи следећи приступ:

  1. Преузмите бесплатни алат IBDataPump http://www.clevercomponents.com/demo/datapump/IBPump.zip

  2. Креирајте само метаподатке базе из резервне копије поправљене базе (након IBFirstAID) користећи команду

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

  1. Покрените IBDataPump и поставите делимично поправљену базу као извор, а свежу празну базу као циљ

  2. Кликните на следеће картице, кликните одговарајућа дугмад и на 3. картици кликните „Pump". Сачекајте да се заврши (може бити дуг процес, да бисте стекли представу можете проверити динамику раста величине циљне базе).

  3. Као резултат имаћете fresh.fdb базу са конзистентним односима страних кључева - потпуно је исправна.

Ако база има петљу са страним кључевима, IBDataPump ће вас упозорити и дати листу таквих ограничења - једно или више њих треба уклонити пре него што препумпавање буде доступно.

Наравно, било је случајева када је препумпавање захтевало посебан приступ, и ако се суочите са таквом ситуацијом, молимо контактирајте нашу подршку.