-
Notifications
You must be signed in to change notification settings - Fork 455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[dbnode] Fix index flush recovery when previous flush attempts have failed #1574
Changes from 7 commits
be23d38
a2ab438
2a89613
cb9ee54
9006daf
c9570d6
7c73166
0e48b0b
fc17ee1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,14 +73,27 @@ var ( | |
|
||
type fileOpener func(filePath string) (*os.File, error) | ||
|
||
// LazyEvalBool is a boolean is lazily evaluated. | ||
type LazyEvalBool uint8 | ||
|
||
const ( | ||
// EvalNone indicated the boolean has not been evaluated. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
EvalNone LazyEvalBool = iota | ||
// EvalTrue indicates the boolean has been evaluated to true. | ||
EvalTrue | ||
// EvalFalse indicates the boolean has been evaluated to false. | ||
EvalFalse | ||
) | ||
|
||
// FileSetFile represents a set of FileSet files for a given block start | ||
type FileSetFile struct { | ||
ID FileSetFileIdentifier | ||
AbsoluteFilepaths []string | ||
|
||
CachedSnapshotTime time.Time | ||
CachedSnapshotID uuid.UUID | ||
filePathPrefix string | ||
CachedSnapshotTime time.Time | ||
CachedSnapshotID uuid.UUID | ||
CachedHasCompleteCheckpointFile LazyEvalBool | ||
filePathPrefix string | ||
} | ||
|
||
// SnapshotTimeAndID returns the snapshot time and id for the given FileSetFile. | ||
|
@@ -89,9 +102,11 @@ func (f *FileSetFile) SnapshotTimeAndID() (time.Time, uuid.UUID, error) { | |
if f.IsZero() { | ||
return time.Time{}, nil, errSnapshotTimeAndIDZero | ||
} | ||
if len(f.AbsoluteFilepaths) > 0 && !strings.Contains(f.AbsoluteFilepaths[0], snapshotDirName) { | ||
if len(f.AbsoluteFilepaths) > 0 && | ||
!strings.Contains(f.AbsoluteFilepaths[0], snapshotDirName) { | ||
return time.Time{}, nil, fmt.Errorf( | ||
"tried to determine snapshot time and id of non-snapshot: %s", f.AbsoluteFilepaths[0]) | ||
"tried to determine snapshot time and id of non-snapshot: %s", | ||
f.AbsoluteFilepaths[0]) | ||
} | ||
|
||
if !f.CachedSnapshotTime.IsZero() || f.CachedSnapshotID != nil { | ||
|
@@ -115,16 +130,33 @@ func (f FileSetFile) IsZero() bool { | |
return len(f.AbsoluteFilepaths) == 0 | ||
} | ||
|
||
// HasCheckpointFile returns a bool indicating whether the given set of | ||
// HasCompleteCheckpointFile returns a bool indicating whether the given set of | ||
// fileset files has a checkpoint file. | ||
func (f FileSetFile) HasCheckpointFile() bool { | ||
func (f *FileSetFile) HasCompleteCheckpointFile() bool { | ||
switch f.CachedHasCompleteCheckpointFile { | ||
case EvalNone: | ||
f.CachedHasCompleteCheckpointFile = f.evalHasCompleteCheckpointFile() | ||
return f.HasCompleteCheckpointFile() | ||
case EvalTrue: | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
func (f *FileSetFile) evalHasCompleteCheckpointFile() LazyEvalBool { | ||
for _, fileName := range f.AbsoluteFilepaths { | ||
if strings.Contains(fileName, checkpointFileSuffix) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably don't need this line anymore since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True but that will cause an "Invariant error" to be allocated which I'd like to avoid in the case that we're scanning a lot of files. |
||
return true | ||
exists, err := CompleteCheckpointFileExists(fileName) | ||
if err != nil { | ||
continue | ||
} | ||
if exists { | ||
return EvalTrue | ||
} | ||
} | ||
} | ||
|
||
return false | ||
return EvalFalse | ||
} | ||
|
||
// FileSetFilesSlice is a slice of FileSetFile | ||
|
@@ -161,7 +193,7 @@ func (f FileSetFilesSlice) LatestVolumeForBlock(blockStart time.Time) (FileSetFi | |
break | ||
} | ||
|
||
if curr.HasCheckpointFile() && curr.ID.VolumeIndex >= bestSoFar.ID.VolumeIndex { | ||
if curr.HasCompleteCheckpointFile() && curr.ID.VolumeIndex >= bestSoFar.ID.VolumeIndex { | ||
bestSoFar = curr | ||
bestSoFarExists = true | ||
} | ||
|
@@ -812,7 +844,7 @@ func FileSetAt(filePathPrefix string, namespace ident.ID, shard uint32, blockSta | |
) | ||
} | ||
|
||
if !fileset.HasCheckpointFile() { | ||
if !fileset.HasCompleteCheckpointFile() { | ||
continue | ||
} | ||
|
||
|
@@ -841,7 +873,7 @@ func IndexFileSetsAt(filePathPrefix string, namespace ident.ID, blockStart time. | |
matches.sortByTimeAscending() | ||
for _, fileset := range matches { | ||
if fileset.ID.BlockStart.Equal(blockStart) { | ||
if !fileset.HasCheckpointFile() { | ||
if !fileset.HasCompleteCheckpointFile() { | ||
continue | ||
} | ||
filesets = append(filesets, fileset) | ||
|
@@ -1198,7 +1230,7 @@ func SnapshotFileSetExistsAt(prefix string, namespace ident.ID, shard uint32, bl | |
return false, nil | ||
} | ||
|
||
return latest.HasCheckpointFile(), nil | ||
return latest.HasCompleteCheckpointFile(), nil | ||
} | ||
|
||
// NextSnapshotMetadataFileIndex returns the next snapshot metadata file index. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
boolean that is