База данных Android повреждена, но может открываться в SQLite Manager. Восстанавливаемый?

В последние две недели, не выпуская обновления для своего приложения, я начал получать кучу отчетов с поврежденными базами данных. Ниже приведена трассировка стека. Android не может открыть базу данных, как и программа sqlite-manager на моем компьютере. Однако аддон-менеджер SQLite для firefox может его открыть. После выполнения команды «компактная база данных» база данных была исправлена, и я смог открыть ее в Android. Есть ли способ сделать что-то подобное в моем приложении? Большая проблема заключается в том, что я не могу даже попытаться открыть базу данных, потому что более новые версии Android немедленно удалят и заменят базу данных, как вы можете видеть в трассировке стека ниже. Можно ли как-то выполнить операторы PRAGMA без открытия базы данных?

С уважением,

02-22 09:55:20.245: ERROR/Database(5382): CREATE TABLE android_metadata failed
02-22 09:55:20.245: ERROR/Database(5382): Failed to setLocale() when constructing, closing the database
02-22 09:55:20.245: ERROR/Database(5382): android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1950)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1818)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
02-22 09:55:20.245: ERROR/Database(5382):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
02-22 09:55:20.245: ERROR/Database(5382):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)

02-22 09:55:20.245: ERROR/Database(5382): Deleting and re-creating corrupt database /mnt/sdcard/myapp/backup.sqlite
02-22 09:55:20.245: ERROR/Database(5382): android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.native_setLocale(Native Method)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.setLocale(SQLiteDatabase.java:1950)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1818)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
02-22 09:55:20.245: ERROR/Database(5382):     at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
02-22 09:55:20.245: ERROR/Database(5382):     at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
02-22 09:55:20.245: ERROR/Database(5382):     at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)

Изменить: я менеджер, чтобы открыть базу данных следующим образом:

db = SQLiteDatabase.openDatabase(database, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);

Но когда я запускаю это:

String sqlQuery = "pragma integrity_check";
db.execSQL(sqlQuery);

Я получаю это:

ERROR/AndroidRuntime(9144): Caused by: android.database.sqlite.SQLiteDatabaseCorruptException: database disk image is malformed: pragma integrity_check

Edit2: я понял, что очистка базы данных решает проблему. Но если я очищаю изнутри своего приложения с помощью exeSQL («вакуум»), это не помогает. Почему это? :'(


person pgsandstrom    schedule 22.02.2011    source источник


Ответы (3)


Канонический хороший способ восстановить поврежденную базу данных — это выгрузить ее как SQL, а затем прочитать обратно в новую базу данных. Это очень просто с помощью инструмента sqlite:

sqlite in.db .dump | sqlite out.db

... но, конечно, вам нужно сделать это в коде, и я действительно не знаю, доступен ли где-либо .dump.

Я бы посоветовал вам, возможно, захотеть сначала посмотреть, как он повреждается — SQLite всегда был для меня надежным, хотя я когда-либо использовал его только во внутренней памяти. Можете ли вы проверить файловую систему FAT, чтобы убедиться, что она повреждена? Я видел, например, цифровые камеры, которые всячески коверкали файловую систему на картах разными непонятными способами...

person David Given    schedule 28.02.2011

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

Я только что понял, что решением может быть использование SQLJet вместо реализации Android SQLite по умолчанию.
Поскольку его название не соответствует Предположим, SQLJet — это клиент Java SQLite с открытым исходным кодом, который работает на Android.

person Nicolas Raoul    schedule 14.10.2011
comment
Спасибо, на самом деле выглядит довольно интересно! - person pgsandstrom; 14.10.2011
comment
@Nicolas Raoul Не могли бы вы объяснить, как SQLJet решит проблему OP / предотвратит ее? Мне любопытно, так как у меня те же проблемы, что и у ОП :) - person AgentKnopf; 17.12.2012
comment
SQLite просто не имеет этой ошибки - person Nicolas Raoul; 17.12.2012
comment
SQLJet — это просто API для использования базы данных SQLite. Это довольно хорошо, но, в конце концов, у вас нет гарантии, что база данных не будет повреждена. - person Simon; 07.06.2018

В вашем приложении вы закрываете базу данных перед выходом из активности? Посмотрите logcat и проверьте, есть ли какие-либо ошибки или предупреждения при запуске вашего приложения.

person sh0rtshift    schedule 07.03.2011