fbrescue

internal Firebird consistency check (wrong record length (183))

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

Каждая запись хранит номер своего формата, то есть раскладки таблицы на момент записи, и распаковывается ровно в длину этого формата. wrong record length значит, что запись распаковалась в другую длину. Повреждены её байты, заголовок или один из фрагментов. Как и decompression overran buffer, это повреждение отдельных записей, и оператор, который читает такую запись, падает каждый раз.

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

Остановите сервер 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 читает каждую запись в том формате, который она указывает. Запись, которая короче своего формата, попадает в _errors.jsonl со страницей и строкой. Остальные записи таблицы выгружаются. Таблицы, которые много раз меняли через ALTER, не проблема: каждая запись читается в той раскладке, с которой её записали.

См. также