는 몇 가지 배경 :더 나은 SQLite는 손상 감지
내 안드로이드 응용 프로그램은 네 개의 열 행의 많은 DB 테이블이 있습니다. 서버에 요청을 보내면 서버는이 네 가지 값 모두가 "유효"한 경우에만 응답합니다. 수천 명의 사용자 중 일부가 (서버에서 결과를 얻지 못해 잠시 동안) 문제가 발생했다는 것을 알았습니다. 문제의 원인을 파악하려고 시도했지만 가능한 유일한 원인은 DB 손상이 감지되지 않습니다.
ACRA 로그에서 SQL 오류가있는 메시지가 있지만 응용 프로그램이 손상되어 파일을 열 수 없습니다. 그것은 나에게 약간의 단서를 주었지만, 나는 여전히 이것이 문제라는 것을 확신하지 못했습니다.
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'
결과는 이런 식으로 "편집"테이블 데이터가 완전히 가능하다는 것을 보여 주었다 : 그래서, SQLite는 그 처리 방법 랜덤 DB 파일에 바이트 검사를 변경하는 매우 간단한 파이썬 스크립트를 생성
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
무결성 검사에서 발견되지 않은 수정의 절반에 대해 쿼리를 실행하는 데 실패했지만 일반적으로 흥미로운 점은 내 DB에서 임의의 바이트를 스왑하여 응용 프로그램을 쓸모 없게하는 것입니다. 내 사용자 중 일부.
SQLite 웹 사이트 및 StackOverflow에서 가능한 손상 원인에 대해 읽었습니다. 응용 프로그램을 강제 종료하면 DB에 손상을 줄 수 있습니다. 빠른 빠르고 강력한 DB 무결성 검사를 구현할 수 있는지 알고 싶습니다.
시작 (자동 완성)시 전체 테이블의 한 열에서 데이터를 읽으므로 모든 값에서 일부 해시를 계산할 것을 생각했습니다. 일부 해시 함수는 무결성 검사를 수행하기 위해 설계되었지만 더 간단하고 빠르며 더 나은 해결책이있을 수 있습니다.
이 질문에 대한 답변으로 제안 된대로 : http://stackoverflow.com/questions/11490250/does-sqlite-checksum-its-data 앞으로 오류 수정을 사용하여 데이터를 인코딩 할 수 있습니다. 어쩌면 더 간단하지 않거나 더 빠를 수도 있습니다 (해시가 합리적이고 간단한 솔루션처럼 보일 수도 있지만). 실제로 오류를 감지 할뿐만 아니라 오류를 수정할 기회가 있습니다. – bsa
이 질문은 좀 오래되었지만 [이 답변]에 대해 언급하고 싶었습니다. (http://stackoverflow.com/questions/12418600/how-do-you-determine-if-an-sqlite-or-sqback-is- corrupt-in-java)는 PRAGMA quick_check;를 사용하여 언급하고있다. 이는 데이터 (?) *에 대해 일종의 스캔 *을 수행한다. 위의 테스트 케이스에서 어떤 결과가 나오는지 궁금하지만, 어떻게 통합 할 지 확신하지 못합니다. ** 수정 : [문서] (http://www.sqlite.org/pragma.html#pragma_integrity_check)는'quick_check'가'identity_check'의 더 빠른 버전입니다. ** Ah. –