2012-05-01 2 views
2

Я хотел знать, какие лучшие практики для резервного копирования и восстановления SQLite DB на Android. В настоящее время я подхожу к проблеме, беря резервную копию базы данных и используя потоки ввода/вывода файлов, чтобы скопировать ее на SD-карту. Затем я использую обратный процесс, если я хочу восстановить и старую резервную копию.Sqlite DB Android Backup/Restore

Этот метод, похоже, работает и еще не испортил мои данные. Мне интересно, если это лучший подход или если есть более безопасный способ сделать это?

Thanks

ответ

4

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

Единственный способ, которым я мог это сделать, состоял бы в том, чтобы прочитать фактическое содержимое БД и сгенерировать файл, содержащий SQL, с которого он может быть восстановлен, это, очевидно, более сложный и не предложить все преимущества, чтобы оправдать эту сложность.

16

Просто FYI при резервном копировании базы данных. В настоящее время я делаю это в своем приложении так же, как вы объясняете выше. Будьте осторожны при создании резервных копий таким образом. Он работает отлично по большей части, но проблема в том, что созданная резервная копия не гарантируется совместимость со всеми устройствами и версиями Android. Я думал, это было странно в первый раз, когда я это услышал, но теперь я обнаружил, что это правда. В последнее время я получаю несколько сообщений о недостающих данных, исчезающих данных и тому подобных. Все это происходило, когда пользователь восстанавливал резервную копию либо с другого устройства, либо с другой версии Android или ROM. Некоторые из них напрямую связались со мной, что было здорово, поэтому я смог получить файлы резервных копий, чтобы проверить их и изучить. Когда я попытался восстановить их, я получаю следующую ошибку LogCat: android.database.sqlite.sqlitedatabasecorruptexception: образ диска базы данных уродлив

То, что я узнавал, что, в основном, некоторые HTC устройства и некоторые пользовательские roms (на любом устройстве) создавали эти резервные копии, которые не восстанавливались бы на других устройствах или ромах. Базы данных не были действительно повреждены, но Android думал, что они были. Я бы забрал их в браузер SQLite, и ни один из них не покажет там. Оказывается, что более новые версии SQLite имеют WAL (Write Ahead Logging) по умолчанию, и если он включен и создается резервная копия с этой базой данных, его нельзя восстановить в более старой версии SQLite или даже в той же версии (для по какой-то нечетной причине). Таким образом, я отключил WAL с помощью «PRAGMA journal_mode = DELETE», а затем я смог просмотреть базу данных в браузере и смог восстановить ее на своем тестовом устройстве. Другая проблема заключается в том, что, похоже, не существует способа поймать это исключение в коде, и Android автоматически удаляет базу данных, когда приходит это исключение (очень плохое управление на стороне Android, на мой взгляд).

Извините за длинный отклик, но я хотел объяснить, что я видел, происходящее с такой резервной копией. Я пытаюсь найти другой способ создания универсальной резервной копии на SD-карте. Создание csv-файлов и sql-скриптов, таких как @Kingamajick, может быть другим способом сделать это. Это больше кода и больше работы, но если он работает на любом устройстве, версии SQLite и ROM, то это того стоит. Ваши клиенты, теряющие данные, никогда не бывают хорошими.

+0

Можете ли вы указать, какие версии API вы обнаружили в. Thx –

+1

Это происходит на устройствах HTC, работающих под управлением Android 2.3. Я также видел это на CM7 и CM9 ромах. Однако это не все устройства HTC, особенно в серии Desire. По-видимому, эти устройства HTC и Cyanogemod имеют WAL по умолчанию в SQLite, и они плохо воспроизводятся с другими ромами, устройствами или версиями SQLite. Я думаю, что, когда все больше устройств получат ICS и более новую версию SQLite, эти старые резервные копии, созданные на устройствах до 4.0, начнут создавать проблемы при их восстановлении. Я не видел таких исключений, пока не было выпущено 2.3.3+, и больше устройств переместилось от FROYO. – ssuperz28

+0

Вы используете транзакции в Sqlite, чтобы убедиться, что все либо написаны или вообще написаны? –

0

Я бы добавил еще один комментарий к ответу Кингамаджика (форум не позволит мне добавить его в качестве фактического комментария там). В подходе, который просто копирует файл, если пользователь когда-либо восстанавливает БД, и в нем уже есть какие-либо данные, он будет перезаписан. Например, если пользователь обновляется до нового телефона, он некоторое время использует его, а затем восстанавливает БД со своего старого телефона, любые данные, уже имеющиеся на новом телефоне, будут потеряны.Это одно из преимуществ сложности чтения БД и записи его в файл (XML или CSV и т. Д.).

Я задал еще один вопрос (Android sqlite backup/restore without overwriting), в надежде, что у кого-то было лучшее решение, которое избегало этой проблемы, но пока кажется, что его нет. Между этим и проблемами ssuperz28 отметили, что кажется, что гораздо более безопасный способ резервного копирования вашей базы данных состоит в том, чтобы записать его в xml, а затем прочитать его и добавить обратно в восстановление.

Кроме того, https://stackoverflow.com/a/34477622/3108762 является лучшим из других предложений, которые я видел до сих пор, и обещает лучший способ приблизиться к этому запуску в Зефир.

Смежные вопросы