Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLiteDiskIOException in Android

Tags:

android

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)

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.

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

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.

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.

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

Guidance and solutions are much appreciated.

like image 563
Jason Shah Avatar asked Jul 10 '10 19:07

Jason Shah


1 Answers

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).

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.

like image 68
Bassel Kh Avatar answered Oct 22 '22 18:10

Bassel Kh