Во время сбоя питания SQLite выполняет откат моей БД до точки НАЧАТЬ - PullRequest
0 голосов
/ 26 сентября 2019

У меня есть база данных SQLite в моем приложении.Каждый раз, когда приложение изменяет / добавляет строку в БД, приложение явно запускает транзакцию SQLite, вводя команду BEING TRANSACTION.После обновления / добавления данных в моей базе данных, я выдаю команду COMMIT или ROLLBACK, если обновление не удалось.Обычные вещи (https://www.sqlite.org/lang_transaction.html). Все работает отлично, пока я не отключаю питание.

Проблема в том, что каждый раз, когда я выполняю отключение питания после того, как приложение выполнит COMMIT, запустит устройство и в конечном итоге запуститприложение, SQLITE сохраняет данные, как если бы BEGIN и COMMIT вообще никогда не происходило! Почему?

Я также проверил файл базы данных в своем каталоге приложений, он содержит правильные данные. Я также заметил дополнительныефайл <mydatabasefilename>-journal в каталоге моего приложения. После проверки это временный файл , используемый SQLite для поддержки отката незавершенной транзакции, особенно во время потери питания.

Опять мой COMMIT произошелдо потери питания. Файл моей базы данных (как проверено в каталоге моего приложения) содержит правильные данные. Но почему <mydatabasefilename>-journal содержит более старые данные? Я их вообще не получаю. Я что-то здесь упускаю?

1 Ответ

0 голосов
/ 26 сентября 2019

Какие настройки для PRAGMA synchronous и PRAGMA journal_mode использует ваша база данных?Они могут использоваться для управления точным поведением sqlite по отношению к этим вещам.

Поведение файла <mydatabasefilename>-journal, содержащего старое содержимое, похоже на описанный здесь журнал отката: https://www.sqlite.org/lockingv3.html#rollback

Когда процесс хочет изменить файл базы данных (и он не находится в режиме WAL), он сначала записывает исходное неизмененное содержимое базы данных в журнал отката.Журнал отката - это обычный файл на диске, который всегда находится в том же каталоге или папке, что и файл базы данных, и имеет то же имя, что и файл базы данных, с добавлением суффикса -journal.[...]

[...]

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

Различные режимы журнала, которые можно установить, описаны здесь: https://www.sqlite.org/pragma.html#pragma_journal_mode

Режим журналирования DELETE - это нормальное поведение.В режиме DELETE журнал отката удаляется при завершении каждой транзакции.Действительно, операция удаления - это действие, которое вызывает транзакцию для фиксации.(Дополнительные сведения см. В документе под названием Атомная фиксация в SQLite .)

Можно попробовать установить другие настройки для PRAGMA synchronous, см. Следующие настройки: https://www.sqlite.org/pragma.html#pragma_synchronous

  • EXTRA (3)

    EXTRA синхронный аналогичен ПОЛНОМУ с добавлением, что каталог, содержащий журнал отката, синхронизируется после того, как этот журнал отключен для фиксации транзакции в режиме УДАЛИТЬ.EXTRA обеспечивает дополнительную долговечность, если за фиксацией тесно следует потеря мощности.

  • FULL (2)

    Когда синхронный режим имеет значение FULL (2), ядро ​​базы данных SQLite будетиспользуйте метод xSync VFS, чтобы убедиться, что весь контент безопасно записан на поверхность диска перед продолжением.Это гарантирует, что сбой операционной системы или сбой питания не повредит базу данных.Полный синхронный режим очень безопасен, но он также медленнее.FULL - наиболее часто используемая синхронная настройка, когда она не в режиме WAL.

Так что в вашем случае настройка PRAGMA synchronous = EXTRA; может делать то, что вы хотите, но это можетЭто может стоить производительности.

Вы также можете попробовать поэкспериментировать с PRAGMA journal_mode = WAL;, описанным в https://www.sqlite.org/wal.html,, в случае, если это лучше для вас при потере мощности, с менее тяжелыми настройками PRAGMA synchronous.

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