gbak: ERROR … gbak:Exiting before completion due to errors
Что это значит
gbak делает бэкап через движок Firebird, таблицу за таблицей и строку за строкой. Первая запись или страница, которую движок не может прочитать, останавливает весь бэкап. Сообщение перед Exiting before completion называет причину: часто это internal Firebird consistency check, неверный тип страницы или ошибка ввода-вывода. Всё, что идёт после этого места, в бэкап не попадает, даже если в файле оно цело.
Ключи, с которыми gbak проходит дальше
-g(без сборки мусора): бэкап не пытается вычищать старые версии записей и не трогает повреждённые записи, до которых иначе не дошёл бы.-ig(игнорировать контрольные суммы): не проверяет контрольные суммы страниц, которые пишут старые версии.gfix -mend -full -ignoreперед бэкапом помечает повреждённые записи, чтобыgbakих пропустил.-vпоказывает, какую таблицу 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 читает без движка, поэтому повреждённая запись или страница стоит только этой записи или страницы, а не всего остального бэкапа. Каждая таблица выгружается в свой файл, а в _errors.jsonl записано, что не попало в выгрузку и почему.