Столкнулся с битым кешем. Восстановить с ходу не удалось, пришлось разбираться с логикой работы утилит. Это конспект опыта, соображений и найденных в работе утилит баго-фич.
Простой кейс: файл 616.316.sdb.bad
~200М, тип ошибки: "обнулился" конец базы - последние ~10% файла сплошные нули (файл по просьбе могу выложить, но такую ситуацию можно смоделировать и на меньшем файле).
Достаточно большая часть тайлов из этой базы читаются в SAS планете, и даже частично экспортируются, но периодически происходит "завис" на битых тайлах. Выделив большую область смог экспортировать
~77М тайлов, т.е. выделяя маленькие участки и экспортируя их в тайловый кеш, следуя логике повреждения, можно восстановить предположительно до
90% тайлов).
Итоги восстановления с помощью sdb_util_1.3Выбирается вариант восстановления .bad файлов (Restore broken files from *.bad [cmd: db_dump && db_load]) поочередно тестировал все 3 возможных варианта восстановления.
а) по дефолту (без дополнительных ключей в настройках).
Процесс происходит без ошибок. Казалось бы можно радоваться, но... размер файла 616.316.sdb =
11,486 М! (<6% от исходного)
Это, похоже, читает и восстанавливает базу
только до первой ошибки.
Более того, файл *.sdb.bad после восстановления
НАСОВСЕМ УДАЛЯЕТСЯ (
особо цинично при этом читается рекомендация из шапки выкладывать .bad файлы после рекавери "если что то не работает" ).
Нельзя же так по дефолту совершать деструктивные действия, даже в SAS планете из таких бэдов можно вытянуть в разы больше тайлов!
Еще отмечу (это касается и следующего пункта рекавери), что создавать дамп - неправильно, т.к. db_dump и db_load прекрасно работают с потоками.
В итоге этот пункт стоит реализовывать следующим образом (в итоге не будем зря гонять диск, дополнительно записывая и потом считывая огромный дамп):
db_dump.exe 616.316.sdb.bad | db_load 616.316.sdb
б) salvage data (-r) спотыкается на этапе дампа:
Ошибка db_dump.exe: пямять не может быть read
Да, уже говорилось, что в версии утилит 5.1 "db_dump -r" нерабочий. Чтобы это обойти, достаточно взять db_dump.exe и libdb53.dll из версии 5.3 (можно 6.1, но не 6.3). Поскольку остальные утилиты и SAS жестко завязаны на libdb51.dll, такой финт никаких конфликтов не создаст.
Но это не помогает: видно, что создается файл 616.316.sdb.dump, но дальше происходит затык и дамп просто удаляеся! Почему не срабатывает db_load? Запись в логах:
- Код: Выделить всё
db_dump.exe: 616.316.sdb.bad: DB_VERIFY_BAD: Database verification failed
<< ExitCode = 1
наталкивает на мысль, что получив ExitCode = 1 sdb_info просто прерывает восстановление, в то время как
согласно документации"If you are dumping a database known to be corrupt, you can safely ignore a DB_VERIFY_BAD error return."
Еще полученный дамп не имеет в заголовке "правильной" строчки db_pagesize=1024, однако его можно грузить без редактирования заголовка задав pagesize вручную. Итого правильно было бы так:
- Код: Выделить всё
db_dump.exe -r 616.316.sdb.bad | db_load -c db_pagesize=1024 616.316.sdb
В некоторых случаях так удается создать более менее рабочую базу (на которую все равно ругается SAS), но в этот раз получился файл ~180МБ, с которым SAS не смогла работать (сыпятся ошибки и все зависает):
- Код: Выделить всё
BerkeleyDB: путь\616.316.sdb: multiple databases specified but not supported by file [root path: "путь к папке с кешем"]
в) Aggressively salvage data (-R)та же ошибка ошибочного завершения создания дампа по "ложному" коду ошибки. Но даже ее игнорирование помогло бы:
- Код: Выделить всё
db_load -f 616.316.sdb.dump 616.316.sdb
db_load.exe: line 1: unexpected format
ибо при дампе с ключем -R в заголовке дампа будут лишние две строчки, из-за которых db_load не сможет воссоздать из дампа базу. Т.о. без дополнительных утилит этот пункт в принципе невозможно сделать работоспособным.
Получающаяся база, если поменять заголовок и загрузить дамп db_load, ведет себя аналогично предыдущему пункту.
Вывод: sdb_util идеально подходит для устранения мелких ошибок, но если после проверки образовались .bad файлы,
нельзя использовать штатное рекавери *.bad файлов: опции, способные максимально полностью восстановить данные, не функциональны, а единственная работающая дефолтная опция чревата большой потерей данных!
Поскольку ниже найден оптимальный метод восстановления базы, рекомендуется включить его и использовать по умолчанию в sdb_util (а также добавить опцию "удалять *.bad файлы после восстановления"). Пока же рекомендуется использовать описанную ниже методику восстановления .bad файлов.