, bazı arka plan:Daha SQLite yolsuzluk algılama
Benim Android uygulaması dört sütunlu satırların bir sürü DB tablo vardır. Sunucuya istek gönderir ve sunucu yalnızca bu dört değerin tümü "geçerli" olduğunda yanıt verir. Binlerce kullanıcının bir kısmı kendileri için bir şeylerin işe yaramadığını bildirdi (bir süredir sunucudan sonuç alamıyorlardı) - sorunun nedenini anlamaya çalışıyordum ve bunun tek olası sebebi olduğu ortaya çıktı. Algılanmayan DB bozulması.
ACRA günlüklerinde SQL hatası olan bazı iletiler var, ancak bunlar bozuk olduğundan dolayı bu dosyayı açamayacaklardı. Bu bana bir ipucu verdi, ancak hala bu sorunun olduğuna ikna olmamıştım.
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'
sonuç bu şekilde "düzenleme" tablo veri tamamen mümkün olduğunu göstermiştir: Yani, SQLite bununla başa nasıl rastgele VT dosyasında bayt ve kontrolleri değiştiren çok basit Python komut yarattı
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
Bu bir sorgu yapmayı bütünlük çekle fark edilmemeye giden değişiklikler yarısını başarısız olduğunu görmek genelde ilginç, ama benim için en ilginç şey bir şey için başvurum gereksiz kılan benim DB rastgele bayt takas olabilmesidir Kullanıcılarımın bir parçası.
SQLite web sitesinde ve ayrıca StackOverflow üzerinde olası yolsuzluk nedenlerini okudum, örn. Uygulamayı kapatmak için zorlamak DB'ye zarar verebilir. Daha hızlı ve daha sağlam bir DB bütünlüğü kontrolü gerçekleştirmenin mümkün olup olmadığını bilmek isterim.
Başlangıçta (otomatik tamamlama için) tüm tablonun bir sütunundaki verileri okuyorum, bu yüzden bazı değerlerin tüm değerlerden hesaplanmasını düşünmüştüm - bazı karma işlevleri olduğu için bunun oldukça iyi olacağını düşünüyorum. Sadece doğruluk kontrolleri yapmak için tasarlandı, ama belki de daha basit, daha hızlı ve daha iyi bir çözüm var.
Bu sorunun yanıtında önerildiği gibi: http://stackoverflow.com/questions/11490250/does-sqlite-checksum-its-data Verilerinizi ileri hata düzeltmesi kullanarak kodlayabilirsiniz. Belki daha basit ya da daha hızlı değil (bir karma mantıklı ve basit bir çözüm gibi görünüyor), ama belki daha iyi. Hataları düzeltme şansınız var, sadece onları tespit etmek değil. – bsa
Bu soru biraz eski, ama [bu cevap] 'dan bahsetmek istedim (http://stackoverflow.com/questions/12418600/how-do-you-determine-if-an-sqlite-or-sqback-is- bozuk-in-java), veri (?) * üzerinde bir çeşit tarama * yapan PRAGMA quick_check; Yukarıdaki test çantasında bunun ne tür sonuçlar vereceğini merak ediyorum ama nasıl entegre edeceğinizden emin değilim. ** DÜZENLEME: [dökümantasyon] (http://www.sqlite.org/pragma.html#pragma_integrity_check) '' quick_check' '' identity_check''nın daha hızlı bir versiyonudur. ** Ah. –