RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Small. Fast. Reliable.
Choose any three.
Восстановление данных из поврежденной базы данных SQLite

1. Восстановление данных из поврежденной базы данных SQLite

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

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

1.1. Ограничения

Иногда возможно отлично восстановить базу данных, которая повреждена, но это исключение. Обычно восстановленная база данных будет дефектной многими способами:

  • Некоторое содержание могло бы быть постоянно удалено и невосстанавливаемо. Это может произойти, например, если процесс жулика переписывает часть файла базы данных.

  • Ранее удаленное содержание могло бы вновь появиться. Обычно, когда SQLite делает операцию DELETE, он на самом деле не переписывает старое содержание, но вместо этого помнит, что место доступно для повторного использования во время следующего INSERT. Если такое удаленное содержание находится все еще в файле, когда восстановление предпринято, это могло бы быть извлечено и "возрождено".

  • Восстановленное содержание могло бы быть изменено. Например, значение в конкретной строке могло бы измениться от 48 до 49. Или это могло бы измениться от целого числа в последовательность или blob. Значение, которое было NULL, могло бы стать целым числом. Значение последовательности могло бы стать BLOB. И т. д.

  • Ограничения могут не быть действительными после восстановления. Ограничения CHECK, ограничения FOREIGN KEY, ограничения UNIQUE, типы на таблицах STRICT, любое из них могло бы быть нарушено в восстановленной базе данных.

  • Содержание может переместиться в другую таблицу.

API восстановления делает работу столь хорошо, как может при восстановлении базы данных, но результаты всегда будут сомнительными. Иногда (например, если повреждение ограничивается индексами) восстановление отлично восстановит содержание базы данных. Однако, в других случаях, восстановление будет несовершенно. Воздействие этого дефекта зависит от применения. База данных, которая держит список закладок, является все еще списком закладок после восстановления. Несколько закладок могли бы отсутствовать или измениться после восстановления, но список несовершенен изначально, так что добавление немного больше неуверенности не будет фатально для применения. Но если бухгалтерская база данных повреждена и впоследствии восстановлена, книги могли бы быть вне баланса.

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

2. Команда ".recover" в CLI

Самый легкий способ вручную починить базу данных использует CLI в SQLite. CLI это программа "sqlite3". Используйте ее, чтобы починить файл базы данных, используя команду, подобную следующей:

sqlite3 corrupt.db .recover >data.sql

Это произведет код на SQL в файле, названном "data.sql", который может использоваться, чтобы восстановить оригинальную базу данных:

sqlite3 recovered.db <data.sql

Опция ".recover" на самом деле команда, которая дается к CLI. Та команда может принять аргументы. Например:

sqlite3 corruptdb ".recover --ignore-freelist" >data.sql

Заметьте, что команда ".recover" и ее аргументы должны содержаться в кавычках. Следующие варианты поддерживаются:

--ignore-freelist

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

--lost-and-found TABLE

Если содержание найдено во время восстановления, которое не может быть связано с конкретной таблицей, это помещается в таблицу "lost_and_found". Используйте этот выбор, чтобы изменить название "lost_and_found" на "TABLE".

--no-rowids

Если эта возможность предоставляется, то rowid, которые не являются также INTEGER PRIMARY KEY, не извлечены из базы данных.

3. Встраивание восстановления API в применение

3.1. Файлы исходного кода

Если вы захотите встроить восстановление API в ваше приложение, необходимо будет добавить некоторые исходные файлы к вашей сборке вне обычных файлов "sqlite3.c" и "sqlite3.h". Вам будет нужно:

sqlite3recover.c Это главный исходный файл, который осуществляет восстановление API.
sqlite3recover.h Это заголовочный файл, который идет с sqlite3recover.h.
dbdata.c Этот файл осуществляет два виртуальных названия таблиц "sqlite_dbdata" и "sqlite_dbptr", которые нужны sqlite3recover.c.

Два исходных файла C выше должны быть связаны в ваше приложение таким же образом, как "sqlite3.c" связан. И заголовочный файл должен быть доступен для компилятора, когда файлы C собираются.

Кроме того, приложение, или более определенно sqlite3.c, связанный с приложением, должно быть собрано со следующим выбором:

-DSQLITE_ENABLE_DBPAGE_VTAB

3.2. Как осуществить восстановление

Это основные шаги, которые должны бы возвратить содержание поврежденной базы данных:

  1. Создайте дескриптор sqlite3_recover, вызвав sqlite3_recover_init() или sqlite3_recover_init_sql(). Используйте sqlite3_recover_init(), чтобы сохранить восстановленное содержание в отдельной базе данных и sqlite3_recover_init_sql(), чтобы произвести код на SQL, который восстановит базу данных.

  2. Сделайте ноль или больше обращений к sqlite3_recover_config(), чтобы установить варианты на новом дескрипторе sqlite3_recovery.

  3. Вызовите sqlite3_recover_step() неоднократно, пока он не возвратит что-то другое, чем SQLITE_OK. Если это возвращает SQLITE_DONE, то операция по восстановлению закончилась без ошибки. Если это возвращает некоторое другое значение, не SQLITE_OK, то ошибка произошла. sqlite3_recover_run() также доступен как обертка удобства, которая просто неоднократно вызывает sqlite3_recover_step() пока это не возвращает что-то другое, чем SQLITE_DONE.

  4. Получите любой код ошибки и английское языковое сообщение об ошибке, используя sqlite3_recover_errcode() и sqlite3_recover_errmsg(), соответственно.

  5. Вызовите sqlite3_recover_finish(), чтобы закрыть объект sqlite3_recover.

Детали интерфейса описаны в комментариях в файле заголовка sqlite3_recover.h.

3.3. Внедрения в качестве примера

Примеры того, как расширение восстановления используется самим SQLite, могут быть найдены в следующих ссылках: