SQLiteDiskIOException dans Android

Que nous obtenons un grand nombre de SQLiteDiskIOException des erreurs dans notre application Android, avec des traces de pile semblable à la suivante:

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)

Récemment de départ qui se passe il y a quelques semaines, mais pas d'importantes modifications de base de données a eu lieu dans la version exacte dans laquelle les rapports de cette question ont commencé. Malgré le fait d'avoir (je crois) des indices appropriés, cette exception a été signalé plus que nous sommes à l'aise sur cursor.moveToFirst() des appels une fois la requête terminée, comme vous pouvez le voir à partir de la trace de la pile. Jusqu'à présent, nous avons été totalement incapables de se reproduire.

La requête est un peu compliqué, avec trois de gauche rejoint. Ci-dessous est un représentant de la requête, avec quelques identifiant les colonnes changés pour protéger les innocents.

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

D'autres sources ont suggéré que nous essayons de tirer trop de données, mais ce n'est tout simplement pas le cas. L'utilisateur trois cas où nous avons été en mesure d'obtenir la pleine base de données rowcounts montrer:
le cst avec < 2000 entrées,
emed avec <150 entrées, et
pré avec 0 ou 7 entrées.
Par ailleurs, "d'expliquer le plan d'une requête' sur la requête indique toutes les jointures sont faites à l'encontre des colonnes indexées.

Dans tous les cas, nous l'avons vu, l'utilisateur est équipé d'Android 2.1 sur une variété de dispositifs (DROID, Héros, EVO, peut-être d'autres). Notamment, nous n'avons pas vu cela sur un couple G1 appareils nous avons, même lorsqu'ils sont chargés vers le bas avec d'autres applications.

Enfin, la désinstallation et la réinstallation s'est avérée efficace dans le nettoyage de la question, mais peut-être que temporairement.

Je crains que ce problème est une conséquence de la corruption des données dans Android 2.1.
Quelqu'un aurait-il des suggestions de ce qu'il faut rechercher?
Cela pourrait-il être lié à cette Android bug sur SQLiteDatabaseCorruptException

L'orientation et les solutions sont très appréciées.

Pouvez-vous faire une petite application qui reproduit le problème? Si oui, je le télécharger code.google.com/p/android/issues/list
J'ai essayé de reproduire le problème pour un certain temps maintenant, par le biais de notre application. Je n'ai pas essayé un petit programme, en particulier sur 2.1. Que pourrait être le prochain chemin si les modifications les plus récentes ne permettent pas de résoudre le problème. Merci.
J'imagine que les gens ont acheté de merde que les cartes SD qui souffrent de la corruption.

OriginalL'auteur Jason Shah | 2010-07-10