Мы получаем большое количество SQLiteDiskIOException
ошибок в нашем приложении для Android со следами стека, похожими на следующие:
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()
после завершения запроса, как вы можете видеть из трассировки стека. До сих пор мы не смогли полностью воспроизвести.
Запрос несколько сложный, с тремя левыми соединениями. Ниже приведен репрезентативный запрос, в котором некоторые идентифицирующие столбцы изменены для защиты невинных.
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
Другие источники предположили, что мы пытаемся извлечь слишком много данных, но это просто не тот случай. Три пользовательских случая, когда нам удалось получить полные счетчики строк базы данных, показывают:
cse с <2000 записей,
с <150 записями, и
предварительно с 0 или 7 записей.
Более того, «объяснение плана запроса» в запросе указывает, что все объединения выполняются с индексированными столбцами. </p>
В каждом случае, который мы видели, пользователь запускал Android 2.1 на различных устройствах (DROID, Hero, EVO, возможно, на других). Примечательно, что мы не видели этого на паре устройств G1, которые у нас есть, даже когда они загружены другими приложениями.
Наконец, удаление и повторная установка оказались успешными в устранении проблемы, хотя, возможно, только временно.
Боюсь, что эта проблема является результатом повреждения данных в Android 2.1.
У кого-нибудь есть возможные предложения, на что посмотреть?
Может ли это быть связано с этой ошибкой Android в SQLiteDatabaseCorruptException
Руководство и решения очень ценятся.