Подтвердить что ты не робот

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

В последние две недели, не выпустив обновление для моего приложения, я начал получать кучу отчетов с поврежденными базами данных. Ниже находится стек. Android не может открыть базу данных, и ни одна программа sqlite-manager не будет работать на моем компьютере. Тем не менее SQLite manager-addon для 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 ( "вакуум" ), это не поможет. Почему это?: '(

4b9b3361

Ответ 1

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

sqlite in.db .dump | sqlite out.db

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

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

Ответ 2

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

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

Ответ 3

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