Android数据库损坏,但可以在SQLite Manager中打开。可恢复?

时间:2011-02-22 09:07:03

标签: android database sqlite corruption pragma

在最近的两周内,我没有发布我的应用程序的更新,我已经开始收到大量数据库损坏的报告。下面是堆栈跟踪。 Android无法打开数据库,我的计算机上的sqlite-manager程序也无法打开。但是,fireite的SQLite manager-addon可以打开它。运行命令“compact database”后,数据库已修复,我可以在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(“vacuum”)进行抽真空,它就无济于事。为什么是这样? :'(

3 个答案:

答案 0 :(得分:1)

恢复损坏数据库的规范好方法是将其作为SQL转储出来然后再将其读回新数据库。使用sqlite工具很容易:

sqlite in.db .dump | sqlite out.db

...但是,当然,你需要在代码中完成它,我真的不知道.dump是否可以在任何地方使用。

我建议您可能想要了解它是如何被破坏的 - 首先,SQLite对我来说一直坚如磐石,尽管我只在内部存储上使用它。你能检查一下FAT文件系统,看看它是否已损坏?我已经看过,例如,数码相机会以各种模糊的方式彻底破坏卡片上的文件系统......

答案 1 :(得分:1)

Android删除数据库确实是issue

我刚刚意识到解决方案可能是使用SQLJet而不是默认的Android SQLite实现 顾名思义,SQLJet是一个开源的Java SQLite客户端,它适用于Android。

答案 2 :(得分:0)

在您的应用中,您是否在退出活动之前关闭了数据库?观察logcat并检查运行应用程序时是否有任何错误或警告。