安卓出现数据库磁盘镜像格式错误(code 11)的错误提示

34
在我的应用程序中,一些用户会出现数据库磁盘镜像损坏的错误(code 11)。我通过谷歌搜索了解到,当数据库镜像损坏时,Android 会将其删除并重新创建新的数据库文件,这正是一些用户所遇到的情况。 问题是,在10个用户中,仅有2-3个用户的数据库被重新创建,而我无法复现此问题。我不知道为什么会发生这种情况。如果对于所有10个用户来说数据库都已损坏,则为什么Android不会为所有10个用户重新创建数据库?只有那些2-3个用户会重新创建?是否有人可以指点我如何处理这个问题? 更新:我仍然无法复现这个问题,但我能够得到一些日志。以下是它们:
08-28 08:35:44.847 E/SQLiteLog(15123): (11) database corruption at 
line 65088 of [00bb9c9ce4]
08-28 08:35:44.847 E/SQLiteLog(15123): (11) statement aborts at 67      
08-28 08:35:44.857 E/DefaultDatabaseErrorHandler(15123): Corruption 
reported by sqlite on database: 
/data/data/com.retail.posmaster/databases/GrofersRetail
08-28 08:35:45.377 D/dalvikvm(15123): GC_EXPLICIT freed 2639K, 62% 
free 7479K/19228K, paused 4ms+8ms, total 82ms
08-28 08:35:45.727 E/DefaultDatabaseErrorHandler(15123): !@ Delete old 
.mark file
08-28 08:35:45.737 E/DefaultDatabaseErrorHandler(15123): !@ DB 
Corruption has happened before this
08-28 08:35:45.757 E/DefaultDatabaseErrorHandler(15123): !@ DB 
Corruption has happened before this

你的数据库中有大量数据吗? - rakesh kashyap
是的,我的数据库大约有2-5 MB。 - Pramod Yadav
应该是正常的。有模式吗?同样的设备?同样的操作系统? - rakesh kashyap
到目前为止还没有,有时甚至更多达到10兆字节或更多。 - Pramod Yadav
这是一个众所周知的问题,你可以查看https://dev59.com/4m435IYBdhLWcg3wrSLN#5275022。 - Sagar Singh
我已经看过了,但是对我没有帮助。 - Pramod Yadav
2个回答

11

我看到很多用户已经点赞了这个问题,所以我认为许多其他人也在面临相同的问题。我们无法追踪到原因,现在在我们的组织中不再是一个有效的用例,因为由于产品路线图和业务逻辑的一些变化,我们已经放弃在Android应用程序中维护数据库。 我做了一些研究,找出了它发生的原因,并有一些见解。因此,如果您的数据库大小非常大,并且您正在尝试将其加载到内存中并且没有足够的内存,则数据库文件可能会损坏。 另一个原因可能是您正在维护多个数据库连接,并尝试在多个连接中访问数据库而没有正确关闭先前的连接。请尝试维护单个连接并使用内容提供程序。 Android系统的问题在于,如果由于任何原因DB文件格式错误或损坏,则它不会向您提供异常或其他任何手动处理方式。下一次当你尝试对数据库进行操作并尝试连接到数据库文件时,如果系统检测到文件已损坏,则Android系统会重新创建一个全新的文件,所有数据都将丢失。这是Android系统的默认行为。

因此,如果您的应用程序也遇到此问题,请尝试调试以了解为什么您的数据库文件会损坏,因为一旦您的数据库文件损坏,您将无法阻止此行为。另外,您可以尝试转移到其他数据库,如Realm。您可以探索一下,因为我们只在SQLite数据库上遇到了这个问题,对于Realm数据库的行为我不太清楚。

0

我有同样的问题。

应用程序兼容性WAL(预写式日志)

Android 9引入了一种名为“兼容性WAL(预写式日志)”的特殊模式的SQLiteDatabase,它允许数据库在保留每个数据库最多一个连接的行为的同时使用journal_mode=WAL。

你可以尝试这个...

public class YourSQLiteOpenHelper extends SQLiteOpenHelper {
...
@Override
public void onConfigure(SQLiteDatabase db) {
    super.onConfigure(db);
    // Disable WAL
    db.disableWriteAheadLogging();
    // Enable WAL
    // db.enableWriteAheadLogging();
}
...

1van,你能否重新制造这个问题并检查这些更改是否修复了问题吗? - chanakya
1van,你能否重新创建问题并检查这些更改是否修复了问题? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接