fbrescue

I/O error during "read" operation for file

В Windows операция называется "ReadFile". Следом обычно идёт Error while trying to read from file, иногда с Reached the end of the file или ошибкой операционной системы.

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

Движок попросил у операционной системы страницу и не получил её. Возможны две причины:

Если сбоит диск, перестаньте им пользоваться: каждое чтение может сделать хуже. Сначала скопируйте файл на другой диск, при необходимости программой, которая пропускает нечитаемые сектора (ddrescue в Linux), и работайте с копией.

Если файл обрезан, страницы за концом потеряны, а с ними и строки на них. Всё, что до обрыва, можно спасти.

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

Остановите сервер 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 часто останавливается на первой же странице, которую не может прочитать, даже если большая часть базы цела.

Если 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 scan покажет страницы, на которые есть ссылки, но которых уже нет в файле, и таблицы, которым они принадлежат. Выгрузка читает все страницы, которые остались, и перечисляет строки и значения, которые прочитать не удалось. BLOB, чьи страницы пропали, записываются как NULL, остальная строка сохраняется.

См. также