|
|
@@ -252,12 +252,7 @@ func (s *DbStore) collectGarbage(ratio float32) {
|
|
|
// actual gc
|
|
|
for i := 0; i < gcnt; i++ {
|
|
|
if s.gcArray[i].value <= cutval {
|
|
|
- batch := new(leveldb.Batch)
|
|
|
- batch.Delete(s.gcArray[i].idxKey)
|
|
|
- batch.Delete(getDataKey(s.gcArray[i].idx))
|
|
|
- s.entryCnt--
|
|
|
- batch.Put(keyEntryCnt, U64ToBytes(s.entryCnt))
|
|
|
- s.db.Write(batch)
|
|
|
+ s.delete(s.gcArray[i].idx, s.gcArray[i].idxKey)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -266,6 +261,52 @@ func (s *DbStore) collectGarbage(ratio float32) {
|
|
|
s.db.Put(keyGCPos, s.gcPos)
|
|
|
}
|
|
|
|
|
|
+func (s *DbStore) Cleanup() {
|
|
|
+ //Iterates over the database and checks that there are no faulty chunks
|
|
|
+ it := s.db.NewIterator()
|
|
|
+ startPosition := []byte{kpIndex}
|
|
|
+ it.Seek(startPosition)
|
|
|
+ var key []byte
|
|
|
+ var errorsFound, total int
|
|
|
+ for it.Valid() {
|
|
|
+ key = it.Key()
|
|
|
+ if (key == nil) || (key[0] != kpIndex) {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ total++
|
|
|
+ var index dpaDBIndex
|
|
|
+ decodeIndex(it.Value(), &index)
|
|
|
+
|
|
|
+ data, err := s.db.Get(getDataKey(index.Idx))
|
|
|
+ if err != nil {
|
|
|
+ glog.V(logger.Warn).Infof("Chunk %x found but could not be accessed: %v", key[:], err)
|
|
|
+ s.delete(index.Idx, getIndexKey(key[1:]))
|
|
|
+ errorsFound++
|
|
|
+ } else {
|
|
|
+ hasher := s.hashfunc()
|
|
|
+ hasher.Write(data)
|
|
|
+ hash := hasher.Sum(nil)
|
|
|
+ if !bytes.Equal(hash, key[1:]) {
|
|
|
+ glog.V(logger.Warn).Infof("Found invalid chunk. Hash mismatch. hash=%x, key=%x", hash, key[:])
|
|
|
+ s.delete(index.Idx, getIndexKey(key[1:]))
|
|
|
+ errorsFound++
|
|
|
+ }
|
|
|
+ }
|
|
|
+ it.Next()
|
|
|
+ }
|
|
|
+ it.Release()
|
|
|
+ glog.V(logger.Warn).Infof("Found %v errors out of %v entries", errorsFound, total)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *DbStore) delete(idx uint64, idxKey []byte) {
|
|
|
+ batch := new(leveldb.Batch)
|
|
|
+ batch.Delete(idxKey)
|
|
|
+ batch.Delete(getDataKey(idx))
|
|
|
+ s.entryCnt--
|
|
|
+ batch.Put(keyEntryCnt, U64ToBytes(s.entryCnt))
|
|
|
+ s.db.Write(batch)
|
|
|
+}
|
|
|
+
|
|
|
func (s *DbStore) Counter() uint64 {
|
|
|
s.lock.Lock()
|
|
|
defer s.lock.Unlock()
|
|
|
@@ -283,6 +324,7 @@ func (s *DbStore) Put(chunk *Chunk) {
|
|
|
if chunk.dbStored != nil {
|
|
|
close(chunk.dbStored)
|
|
|
}
|
|
|
+ glog.V(logger.Detail).Infof("Storing to DB: chunk already exists, only update access")
|
|
|
return // already exists, only update access
|
|
|
}
|
|
|
|
|
|
@@ -348,6 +390,8 @@ func (s *DbStore) Get(key Key) (chunk *Chunk, err error) {
|
|
|
var data []byte
|
|
|
data, err = s.db.Get(getDataKey(index.Idx))
|
|
|
if err != nil {
|
|
|
+ glog.V(logger.Detail).Infof("DBStore: Chunk %v found but could not be accessed: %v", key.Log(), err)
|
|
|
+ s.delete(index.Idx, getIndexKey(key))
|
|
|
return
|
|
|
}
|
|
|
|
|
|
@@ -355,9 +399,8 @@ func (s *DbStore) Get(key Key) (chunk *Chunk, err error) {
|
|
|
hasher.Write(data)
|
|
|
hash := hasher.Sum(nil)
|
|
|
if !bytes.Equal(hash, key) {
|
|
|
- s.db.Delete(getDataKey(index.Idx))
|
|
|
- err = fmt.Errorf("invalid chunk. hash=%x, key=%v", hash, key[:])
|
|
|
- return
|
|
|
+ s.delete(index.Idx, getIndexKey(key))
|
|
|
+ panic("Invalid Chunk in Database. Please repair with command: 'swarm cleandb'")
|
|
|
}
|
|
|
|
|
|
chunk = &Chunk{
|