fbrescue

internal Firebird consistency check (cannot find tip page (165))

Что это значит

На страницах TIP (transaction inventory) по два бита на транзакцию записано её состояние: подтверждена, отменена или ещё активна. Каждая версия строки хранит номер транзакции, которая её записала, и по этому номеру движок решает, какую версию видит запрос. Если страница TIP пропала, обнулена или затёрта, решить он не может и отказывается работать. Часто база вообще не открывается, и gbak не запускается.

Сами данные при этом обычно не тронуты: потерян только учёт транзакций.

Сначала: сделайте копию и работайте только с ней

Остановите сервер Firebird или хотя бы убедитесь, что к базе никто не подключён. Скопируйте файл вместе с .delta-файлом рядом с ним, если он есть (блокировка nbackup), и вторичными файлами многофайловой базы. Копия, снятая во время записи, несогласованна, а любая попытка починки меняет файл, с которым работает. Если сбоит сам диск, первым делом перенесите файл на другой диск.

Затем: попробуйте штатные средства Firebird

Они есть в каждой установке Firebird и часто возвращают базу целиком — с индексами, триггерами и пользователями. На копии:

gfix -v -full -n copy.fdb            # проверка, только отчёт
gfix -mend -full -ignore copy.fdb    # gbak пропустит битые записи
gbak -b -v -ig -g copy.fdb copy.fbk  # бэкап без контр. сумм и GC
gbak -c -v copy.fbk restored.fdb     # восстановление в новую базу

Добавьте -user SYSDBA -password ..., если этого требует сервер. Если gbak -b завершился, результат — восстановленная база: сверьте число строк в важных таблицах. gfix -mend выбрасывает записи, которые не может прочитать, поэтому сравните результат с оригиналом, прежде чем на него полагаться.

Если gbak всё равно не проходит: выгрузите данные через fbrescue

fbrescue читает файл базы напрямую, без движка Firebird, и выгружает все строки, которые удаётся прочитать. Он не останавливается на первой повреждённой записи или странице и никогда не пишет в файл. Скачайте бинарник для своей системы на странице Releases: Windows, Linux, macOS, устанавливать ничего не нужно.

fbrescue scan copy.fdb                               # что повреждено, по таблицам
fbrescue export copy.fdb --out rescued --format sql  # schema.sql + INSERT'ы по таблицам

Есть также --format csv и --format jsonl. Строки, которые не удалось прочитать, перечислены в rescued/_errors.jsonl со страницей и причиной; если что-то не выгрузилось, код выхода — 2. Загрузить результат в новую базу:

isql -ch UTF8 -i rescued/schema.sql new.fdb
isql -ch UTF8 -i rescued/CUSTOMERS.sql new.fdb  # и так для каждой таблицы

Нужна помощь — откройте issue и приложите вывод fbrescue report copy.fdb. Отчёт описывает повреждения без ваших данных, имена таблиц и колонок в нём заменены номерами.

При этой ошибке fbrescue всё равно выгружает все таблицы. Транзакции старше OIT (oldest interesting transaction из заголовка) по определению подтверждены. Для более новых транзакций, чьё состояние потеряно, fbrescue берёт самую новую версию строки. Для подтверждённых транзакций, а это почти все, это правильная версия. Выгрузка сообщает, для скольких строк пришлось так решать: среди них могут оказаться и отменённые изменения. Если страницы TIP просто лежат не на своём месте, fbrescue находит их сканированием файла.

См. также