Fix uncleanable size=0 orphans with volume.fsck -forcePurging (#7783)
This is a follow-up fix to PR #7332 which partially addressed the issue. The problem is that size=0 needles are in a gray area: - IsValid() returns false for size=0 (because size must be > 0) - IsDeleted() returns false for size=0 (because size must be < 0 or == TombstoneFileSize) PR #7332 only fixed 2 places, but several other places still had the same bug: 1. needle_map_memory.go:doLoading - line 43 still used oldSize.IsValid() 2. needle_map_memory.go:DoOffsetLoading - used during vacuum and incremental loading 3. needle_map_leveldb.go:generateLevelDbFile - used when generating LevelDB needle maps 4. needle_map_leveldb.go:DoOffsetLoading - used during incremental loading for LevelDB 5. needle_map/compact_map.go:delete - couldn't delete size=0 entries because: - The condition 'size > 0' failed for size=0 - Even if it passed, negating 0 gives 0 (not marking as deleted) Changes: - Changed size.IsValid() to !size.IsDeleted() in doLoading and DoOffsetLoading functions - Fixed compact_map delete to use TombstoneFileSize for size=0 entries Fixes #7293
This commit is contained in:
@@ -122,7 +122,7 @@ func generateLevelDbFile(dbFileName string, indexFile *os.File) error {
|
||||
glog.V(0).Infof("generateLevelDbFile %s, watermark %d, num of entries:%d", dbFileName, watermark, (uint64(stat.Size())-watermark*NeedleMapEntrySize)/NeedleMapEntrySize)
|
||||
}
|
||||
return idx.WalkIndexFile(indexFile, watermark, func(key NeedleId, offset Offset, size Size) error {
|
||||
if !offset.IsZero() && size.IsValid() {
|
||||
if !offset.IsZero() && !size.IsDeleted() {
|
||||
levelDbWrite(db, key, offset, size, false, 0)
|
||||
} else {
|
||||
levelDbDelete(db, key)
|
||||
@@ -380,10 +380,10 @@ func (m *LevelDbNeedleMap) DoOffsetLoading(v *Volume, indexFile *os.File, startF
|
||||
// needle is found
|
||||
oldSize := BytesToSize(data[OffsetSize : OffsetSize+SizeSize])
|
||||
oldOffset := BytesToOffset(data[0:OffsetSize])
|
||||
if !offset.IsZero() && size.IsValid() {
|
||||
if !offset.IsZero() && !size.IsDeleted() {
|
||||
// updated needle
|
||||
m.mapMetric.FileByteCounter += uint64(size)
|
||||
if !oldOffset.IsZero() && oldSize.IsValid() {
|
||||
if !oldOffset.IsZero() && !oldSize.IsDeleted() {
|
||||
m.mapMetric.DeletionCounter++
|
||||
m.mapMetric.DeletionByteCounter += uint64(oldSize)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user