SQLiteDiskIOException Android中SQLiteDiskIOException、Android

2023-09-05 08:04:47 作者:年少不轻狂!

我们已经看到了大量的 SQLiteDiskIOException 在我们的Andr​​oid应用程序错误,与堆栈跟踪类似以下内容:

We are getting a large number of SQLiteDiskIOException errors in our Android app, with stack traces similar to the following:

E/AndroidRuntime( 2252): Caused by: android.database.sqlite.SQLiteDiskIOException: disk I/O error
E/AndroidRuntime( 2252): at android.database.sqlite.SQLiteQuery.native_fill_window(Native Method)
E/AndroidRuntime( 2252): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:75)
E/AndroidRuntime( 2252): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:288)
E/AndroidRuntime( 2252): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:269)
E/AndroidRuntime( 2252): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:171)
E/AndroidRuntime( 2252): at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:248)
E/AndroidRuntime( 2252): at com.company.android.CActivity$QueryTask.doInBackground(CActivity.java:1660)

这起最近发生在几个星期前,但没有显著数据库的变化发生在该报告对这个问题开始了确切的发布。尽管有(我相信)适当的指数,这个例外有报道比我们更熟悉的 cursor.moveToFirst()来电查询完成后,你可以从看堆栈跟踪。到目前为止,我们已经完全无法重现。

This recently starting happening a few weeks ago, but no significant database changes took place in the exact release in which reporting of this issue started. Despite having (I believe) appropriate indices, this exception has been reported more than we are comfortable with on cursor.moveToFirst() calls after the query completes, as you can see from the stack trace. So far, we have been completely unable to reproduce.

查询有些复杂,有三个左连接。下面是一个重新presentative查询,以确定一些列变化,以保护无辜的。

The query is somewhat complicated, with three left joins. Below is a representative query, with some identifying columns changed to protect the innocent.

select distinct c._id as _id,c.type as type,c.name as name,c.slug as slug,c.description as description,c.extra1 as extra1,c.extra2 as extra2,c.extra3 as extra3,c.extra4 as extra4,c.extra5,c.extra6 as extra6,c.extra7 as extra7,c.extra8 as extra8, c.extra9 as extra9,c.sslug as sslug,
  c2.name as sname,
  p.type as prel,
  em.dS as dS,em.eS as eS 
from cse as c 
left join cse as c2 on c.sslug=c2.slug 
left join emed as em on c.slug=em.slug 
left join pre as p on c.sslug=p.slug 
where c.pslug='slug' AND c.user='user' AND c.csource='csource' 
order by c.type asc, c.extra6 desc, c.sortorder asc

其他消息来源表明,我们正在试图拉出太多的数据,但是这完全不是这么回事。这三个用户的情况下,我们已经能够得到完整的数据库rowcounts显示: CSE以< 2000项, EMED以< 150项,并且 pre与0或7项。 此外解释查询计划的查询显示所有连接都对索引列完成。

Other sources have suggested that we are trying to pull out too much data, but this is simply not the case. The three user cases where we have been able to get full database rowcounts show: cse with < 2000 entries, emed with <150 entries, and pre with either 0 or 7 entries. Furthermore 'explain query plan' on the query indicates all joins are done against indexed columns.

在任何情况下,我们已经看到了这一点,用户在各种设备上的(DROID,英雄,EVO,可能还有其他)运行Android 2.1。值得注意的是,我们还没有看到这对我们有几个G1的设备,即使它们装下去与其他应用程序。

In every case we have seen this, the user was running Android 2.1 on a variety of devices (DROID, Hero, EVO, possibly others). Notably, we have not seen this on a couple G1 devices we have, even when they are loaded down with other apps.

最后,卸载并重新安装已被证明成功的清理问题,虽然可能只是暂时的。

Finally, uninstalling and reinstalling has proven successful in cleaning up the issue, though possibly only temporarily.

我担心这个问题是Android 2.1的数据损坏的结果。 有没有人有什么建议可以寻找到? 难道这是关系到这个Android的错误的SQLiteDatabaseCorruptException

I fear this problem is a result of data corruption in Android 2.1. Does anyone have possible suggestions of what to look into? Could this be related to this Android bug on SQLiteDatabaseCorruptException

指导和解决方案是多少AP preciated。

Guidance and solutions are much appreciated.

推荐答案

看来你具备多线程问题,一个线程试图获得,而另外一个或多个正在试图插入一些数据到表中的数据,因为异常是从方法抛出(getCount将)。

It seems that you have multi threading issue, one thread tries to get the data while another one or more than one are trying to insert some data into your tables,because the exception is thrown from method (getCount).

另外不要忘了; SQLite的光标是不是内部同步,因此,如果您使用此光标从多个线程,你应该执行自己的同步机制。

Also don't forget; SQLite cursor is not internally synchronized, so if you use this cursor from multiple threads you should perform your own sync mechanism.