Лучшее обнаружение коррупции SQLite

Во-первых, некоторый фон:

В моем Android- приложении есть таблица DB с множеством четырех столбцов. Он отправляет запросы на сервер, а сервер отвечает только тогда, когда все эти четыре значения являются «действительными». Несколько тысяч пользователей сообщили, что для них что-то не работает (с тех пор как они не получают результаты с сервера) – я пытался выяснить, что вызывает проблему, и оказалось, что единственной возможной причиной является Повреждение БД, которое не обнаружено.

В журналах ACRA у меня есть сообщения с ошибками SQL, но это касается того, что приложение не может открыть файл из-за его повреждения. Это дало мне некоторое представление, но я все еще не был уверен, что это проблема. Итак, я создал очень простой скрипт Python, который меняет случайные байты в файле DB и проверяет, как SQLite справится с этим:

import random import array import sqlite3 db = array.array('B') db.fromstring(open('db').read()) ta = [x for x in sqlite3.connect('db').execute('SELECT * FROM table ORDER BY _id')] results = [0,0,0,0] tries = 1000 for i in xrange(0,tries): work = db[:] while work == db: for j in xrange(0,random.randint(1,5)): work[random.randint(1,len(db))-1] = random.randint(0,255) work.tofile(open('outdb','w')) try: c = sqlite3.connect('outdb') results[0] += 1 for r in c.execute('PRAGMA integrity_check;'): results[1] += 1 if (r[0] == 'ok') else 0 except: continue try: results[3] += 1 if [x for x in c.execute('SELECT * FROM table ORDER BY _id')] != ta else 0 results[2] += 1 except: c.close() continue print 'Results for '+str(tries)+' tests:' print 'Creating connection failed '+str(tries-results[0])+ ' times' print 'Integrity check failed '+str(results[0]-results[1])+ ' times' print 'Running a SELECT * query failed '+str(results[1]-results[2])+ ' times' print 'Data was succesfully altered '+str(results[3])+ ' times' 

Результаты показали, что «редактирование» табличных данных таким образом вполне возможно:

 Results for 1000 tests: Creating connection failed 0 times Integrity check failed 503 times Running a SELECT * query failed 289 times Data was succesfully altered 193 times 

Как правило, интересно видеть, что выполнение запроса не удалось для половины изменений, которые не были обнаружены при проверке целостности, но самое интересное для меня – то, что что-то может заменить случайные байты в моей БД, что делает мое приложение бесполезным для части моих пользователей.

Я читал о возможных причинах коррупции на веб-сайте SQLite, а также в StackOverflow, я знаю, что, например, принудительное закрытие приложения может нанести вред БД. Я просто хотел бы знать, возможно ли реализовать быструю и надежную проверку целостности БД.

Я читаю данные из одного столбца всей таблицы при запуске (для автозаполнения), поэтому я подумал о вычислении некоторого хеша из всех значений – я думаю, что это будет работать неплохо, поскольку некоторые хеш-функции предназначены только для выполнения Проверки целостности, но, возможно, есть более простое, быстрое и лучшее решение. Поэтому я спрашиваю вас, знаете ли вы.

    Я не знаю какой-либо подобной функции SQLite, поэтому я бы сказал, что вычисление хэша – это самое простое решение, для начала MessageDigest классом MessageDigest .

    Intereting Posts
    Реализация onScrollListener для обнаружения конца прокрутки в ListView Как воспроизвести звук родной камеры на Android Доступ к Dex теперь невозможно, начиная с 1.4.0 Модификации и символьные символы в PATH Рамка загрузчика vs plain AsyncTask Воспроизведение m3u8 в Google VR для Android-образца Идентификатор Firebase генерируется каждый раз, когда новый BroadcastReceiver: не может создавать класс; Нет пустого конструктора Android Studio SVN 1.8 Этот клиент слишком стар, чтобы работать с рабочей копией Ошибка приложения при андроиде: тема привязана к определенной кнопке Запись видео с другим размером предварительного просмотра, чем полученный видеофайл Может ли фаза «Обновление библиотеки Android» как-то ускориться? Объединение ImageView в одно растровое изображение (Android) Отражение Java: реализовать интерфейс и перейти к другому классу Конкретный URL-адрес не загружается в WebView от Samsung Note2