Восстановление строк базы данных из незафиксированной транзакции - PullRequest
2 голосов
/ 15 декабря 2010

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

В результате у нас есть два файла:

     Size             Time       Name
855117824 2010-12-14 15:27 db
  1665240 2010-12-14 15:27 db-journal

Файл базы данныхбольшой, но большая часть данных не передана, поэтому, когда мы выбираем из базы данных, мы получаем только несколько строк.Когда мы выполняем команду sql 'VACUUM', размер базы данных уменьшается до 3 МБ.

Есть ли способ вернуть данные?

1 Ответ

2 голосов
/ 18 декабря 2010

Я провел небольшое тестирование с помощью программы оболочки sqlite3.

Если предположить, что Python-модуль sqlite3 ведет себя таким же образом, похоже, что надежного * 1005 не существует* восстанавливать незафиксированные транзакции.

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

Для больших блоков транзакций данные записываются в файловую систему , но очищаются после закрытия соединения с БДили (в случае сбоя приложения) при следующем открытии БД.Проще говоря, новые страницы БД выделяются для незафиксированной транзакции, но если транзакция не зафиксирована, они считаются свободным пространством, поэтому VACUUM уменьшает размер БД.Эти страницы будут записаны (и их данные потеряны) при следующей записи в файл БД.Если они находятся в конце файла БД, файл просто усекается при очистке.

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

Это в значительной степени зависит от того, как программа неправильного поведения была прервана.Если вы позволили завершить его изящно, возможно, у него было время на очистку, что в этом случае нежелательно.Поскольку у вас есть журнал БД, я предполагаю, что он имеет более жестокий конец.

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

Если в файле БД были свободные страницы (например, из операторов DELETE), могут также быть фрагменты более старых транзакций, хотя они и интерпретируютсяэти фрагменты - другая история.

По моему мнению, вся операция будет слишком близка (если не будет прямым вводом) к областям компьютерной криминалистики и восстановления данных, наряду со всеми соответствующими проблемами.Если у вас нет действительно важных данных, которые вы не можете получить каким-либо другим способом, я сомневаюсь, что это будет достаточно просто, чтобы стоить того.

...