15

У меня были некоторые проблемы с оперативной памятью (несколько раз синий экран, Windows XP), и теперь мои базы данных Firefox повреждены. Firefox работает, но моя история исчезла, и он сообщает о нескольких несоответствиях и ошибках при выполнении pragma integrity_check на places.sqlite:

образ диска базы данных искажен

Теперь вопрос, как мне восстановить базы данных SQLite?

4 ответа4

22

Заметка

Поскольку для выполнения этой процедуры Firefox должен быть закрыт, обязательно откройте эту страницу в другом веб-браузере или распечатайте ее, прежде чем продолжить.


После нескольких часов работы, пытаясь восстановить базу данных Places, даже читая исходный код Firefox, мне удалось добиться успеха. Вот как я это сделал:

  • Загрузите последнюю версию оболочки SQLite и распакуйте ее в папку своего профиля. В Windows Vista и Windows 7 он находится в папке C:\Users\<username>\AppData\Roaming\Mozilla\Firefox\Profiles\<code>.default .
  • Закройте Firefox, если он запущен.
  • База данных Places находится в файле places.sqlite . Если файл был заменен из-за повреждения, используйте для восстановления файл places.sqlite.corrupt . Создайте резервную копию файла с именем places.sqlite.bak или places.sqlite.corrupt.bak .
  • Используйте оболочку SQLite, чтобы открыть файл базы данных (sqlite3 places.sqlite или sqlite3 places.sqlite.corrupt), затем введите:
.output dump.sql    -- sends output to file dump.sql
.dump               -- dumps database to file
  • Поскольку база данных повреждена, результирующий дамп базы данных не завершен, и не все восстановимые данные были получены. Чтобы определить, где произошла ошибка, найдите слово ERROR (все заглавные буквы) в комментарии SQL внутри файла дампа dump.sql (для этого я использовал Notepad++) и прочитайте над ним команду SQL INSERT чтобы определить нужную таблицу. , В моем случае поврежденная таблица - это moz_places . (Описание таблиц, найденных в базе данных Places, можно найти здесь ; довольно устаревшую диаграмму ER можно найти здесь . Я объясню, как восстановить дополнительные данные только из этой таблицы; следующая процедура, вероятно, неприменима для других таблиц, поэтому пропустите эти подэтапы, если используется таблица, отличная от moz_places .)

    • Каждая строка в таблице moz_places имеет идентификатор. Строки выгружаются из таблицы в следующем порядке. 1 ID - это первое значение после открывающей скобки в INSERT . Область, где база данных повреждена, вероятно, будет небольшим блоком строк в этой таблице; Идея в том, чтобы пропустить эту поврежденную область и восстановить как можно больше данных. Зона старта такого блока представлена на свалке в строке до появления ERROR комментария. Используя идентификатор этой строки, мы можем определить, где повреждена база данных. Мы делаем это, используя SELECT с идентификатором в качестве условия; этот процесс требует проб и ошибок. Например, если последний идентификатор перед ошибкой был 49999, а ошибка следует, поврежденный блок начинается с идентификатора 50000. Используйте заявления как:

    - подавить ненужный вывод - следующая команда для систем Windows - для Linux и других Unix и Unix-подобных систем используйте .output /dev /null .output NUL SELECT id ОТ moz_places WHERE id> = 50100;
    
    • Отрегулируйте значение, следуя id >= и повторяйте указанную выше команду SELECT пока не найдете наименьшее значение, которое не приводит к ошибке SQLite. Это идентификатор, который относится к строке, начиная с которой мы можем восстановить дополнительные данные. Давайте предположим, что этот идентификатор 50200. Чтобы вывести эти данные, введите:

    .output dump2.sql .mode insert SELECT * FROM moz_places WHERE id> = 50200; - восстановить нормальное поведение вывода .output stdout .mode list
    
    • Обратите внимание, что операторы INSERT в файле dump2.sql начинаются с INSERT INTO table VALUES , поэтому используйте функцию поиска и замены в текстовом редакторе, чтобы заменить все экземпляры этой строки на INSERT INTO moz_places VALUES .
    • Скопируйте все содержимое файла dump2.sql и вставьте его в файл dump.sql где появляется комментарий ERROR .
  • Заменить ROLLBACK; -- due to errors в конце файла с COMMIT; ,
  • Добавьте следующий код в начало файла dump.sql . Замените <version> на правильное значение, которое требуется для Firefox, чтобы определить версию схемы базы данных на основе версии Firefox, следующим образом (это можно найти в наборе инструментов исходного файла Firefox toolkit/components/places/Database.cpp):
    • Firefox 50: схема версии 33
    • Firefox 51: схема версии 34
    • Firefox 52: схема версии 35
    • Firefox 53: схема версии 36
    • Firefox 57: схема версии 39
    • Firefox 58: схема версии 41
    • Firefox 60: схема версии 43
    • Firefox 61: схема версии 47

PRAGMA page_size=4096;
PRAGMA user_version=<version>;
  • Выйдите из оболочки SQLite, удалите places.sqlite , затем запустите оболочку SQLite, создав пустую базу данных places.sqlite с помощью sqlite3 places.sqlite . Введите .read dump.sql чтобы загрузить дамп SQL в базу данных.
  • Запустите Firefox и убедитесь, что ваша история и адресная строка работают так, как задумано. Убедившись, что все в порядке, удалите файлы дампа базы данных и исполняемый файл оболочки SQLite из папки профиля.

Более актуальная информация может быть найдена на следующих страницах:


1 SQL обычно не гарантирует, что выходные данные базы данных будут передаваться в любом порядке, если вы не используете предложение ORDER BY . Однако ORDER BY , скорее всего, не сможет произвести какой-либо вывод в поврежденной базе данных (поскольку SQLite потребуется прочитать всю таблицу, прежде чем он сможет произвести какой-либо вывод). Насколько я знаю, Firefox всегда записывает записи таблицы moz_places с последовательными идентификаторами, поэтому мы можем предположить, что весь вывод упорядочен по идентификатору.

4

Ну, в зависимости от того, насколько он поврежден, ремонт может быть невозможен. Лучше всего попытаться сбросить базу данных с помощью sqlite , а затем посмотреть, что вы можете спасти.

Если это не удастся, вам, вероятно, придется восстановить из резервной копии.

Чтобы создать дамп и восстановить базу данных, используйте команду .dump:

sqlite places.sqlite .dump | sqlite places-new.sqlite
2

Как и всегда, выполняя подобное восстановление, я рекомендую сначала сделать хотя бы одну резервную копию файла place.sqlite, расположенного в каталоге вашего профиля. Наличие резервной копии позволяет вам попробовать различные способы устранения таких проблем, зная, что если попытка восстановления ухудшит ситуацию, вы всегда можете сделать еще одну копию резервной копии, чтобы повторить попытку.

В зависимости от того, что повреждено и насколько сильно оно повреждено, может быть возможно исправить проблемы с расширением Places Maintenance. Я несколько раз получал испорченный файл place.sqlite. Обслуживание мест было в состоянии решить проблему каждый раз, выполняя различные проверки / исправления, которые он предоставляет в качестве операций в своем диалоге параметров. Различные проверки и / или отчеты должны занимать от нескольких минут до нескольких минут.

Если это не сработает, то может потребоваться переход на путь ручного исправления таким образом, который описан выше в DragonLord.

1

Этот процесс, описанный в MDN, помог мне решить проблему, когда новые страницы, которые я посетил, не были записаны в истории браузера. У меня не было places.sqlite.corrupt (или places.sqlite-corrupt), но проверка целостности моего файла places.sqlite показала, что образ диска базы данных является ошибочной.

Выйдите из Firefox и сделайте резервную копию своего профиля Firefox, прежде чем идти дальше.

$ cd /Users/<username>/Library/Application\ Support/Firefox/Profiles/<profile_dir>/
$ cp places.sqlite places.sqlite.bak  # for safety

$ sqlite3 places.sqlite
sqlite> PRAGMA integrity_check;
*** in database main ***
On tree page 2 cell 131: Rowid 20884 out of order
...
Error: database disk image is malformed
sqlite> .clone places-clone.sqlite
moz_places... done
moz_historyvisits... done
... more output like above plus a few errors (which I ignored) like
sqlite_sequence... Error: object name reserved for internal use: sqlite_sequence
SQL: [CREATE TABLE sqlite_sequence(name,seq)]
done
...
sqlite> PRAGMA user_version;
43  <----- TAKE NOTE OF THIS VALUE it may be different for you
sqlite> .exit

$ sqlite3 places-clone.sqlite
sqlite> PRAGMA integrity_check;
ok
sqlite> PRAGMA user_version = 43;  -- use the number you got from PRAGMA user_version; above
sqlite> PRAGMA journal_mode = truncate;
truncate
sqlite> PRAGMA page_size = 32768;
sqlite> VACUUM;
sqlite> PRAGMA journal_mode = wal;
wal
sqlite> .exit

$ mv places-clone.sqlite places.sqlite

Запустите Firefox. История должна работать снова.

Я на Mac с Firefox 60.0.1. Возможно, вам придется настроить команды для вашей платформы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .