Questa pagina è stata tradotta automaticamente. Leggi l'originale in inglese. English

Libreria IBSurgeon

"Impossibile eseguire il commit dell'indice" o come estrarre dati da un database parzialmente ripristinato (incoerente)

Alexey Kovyazin, последнее обновление 30 марта 2014 г.

После исправления повреждений часто возникает ошибка “Cannot commit index” на этапе восстановления. В Firebird 2.0 и более поздних версиях это появляется как предупреждение, и база данных не будет переведена в онлайн-режим; в Firebird 1.0-1.5 и InterBase это происходит как очень неприятная ошибка, которая останавливает процесс восстановления (впечатляет увидеть эту ошибку в конце восстановления базы данных размером 200 ГБ).

Причина ошибки “Cannot commit index..” очевидна: повреждение затрагивает ссылочную целостность базы данных, и записи исчезают магическим (с точки зрения сервера) образом.

Например, у вас есть таблица “Customers” и связанная таблица “Orders”, ссылающаяся на внешний ключ. Без повреждений невозможно нарушить внешний ключ и удалить запись из Customers без предварительного удаления всех заказов, относящихся к конкретному клиенту. Повреждение затрагивает файл базы данных на низком уровне и удаляет записи напрямую. Каким приятным сюрпризом для сервера является обнаружение неразрешенных ссылок на главные записи из записей внешних ключей.

Здесь мне нужно добавить совет о процессе восстановления: движок восстанавливает все таблицы с неактивированными индексами (это делает заполнение таблиц записями намного быстрее), а затем начинает активировать (т.е. строить) индексы по одному. Это означает, что все данные уже находятся в базе данных, когда процесс восстановления начинает этап создания индексов, и вы видите ошибку “Cannot commit index..”.

Итак, первое желание при виде ошибки “Cannot commit index” - удалить соответствующее ограничение внешнего ключа, чтобы позволить восстановлению завершиться. Вопрос в том, что мы собираемся делать с несогласованной, но успешно восстановленной базой данных: удаленный внешний ключ может быть важной частью бизнес-логики.

Здесь есть 2 подхода: воссоздать отсутствующие данные или удалить несогласованные данные. Давайте посмотрим, что это означает на примере 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 предупредит вас и предоставит список таких ограничений - одно или несколько из них должны быть удалены, прежде чем перекачка станет доступной.

Конечно, были случаи, когда перекачка требовала особого подхода, и если вы столкнетесь с такой ситуацией, пожалуйста, свяжитесь с нашей поддержкой.