-
Notifications
You must be signed in to change notification settings - Fork 11
Add function to fsync all segments until the current one #998
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
Changes from all commits
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 |
---|---|---|
|
@@ -1046,3 +1046,36 @@ func (r *segmentBufReader) Read(b []byte) (n int, err error) { | |
func (w *WL) Size() (int64, error) { | ||
return fileutil.DirSize(w.Dir()) | ||
} | ||
|
||
// FsyncSegmentsUntilCurrent ensures all segments up to and including the current segment are fsynced. | ||
// There may be more entries appended to the log after fsyncing completes and before FsyncSegmentsUntilCurrent returns. Those entries may not be fsynced. | ||
func (w *WL) FsyncSegmentsUntilCurrent() error { | ||
w.mtx.Lock() | ||
|
||
if w.closed { | ||
w.mtx.Unlock() | ||
return errors.New("unable to fsync segments: write log is closed") | ||
} | ||
|
||
done := make(chan struct{}) | ||
// All previous segments before w.segment should either have been fsynced and closed or still in the actorc channel. | ||
// The function we are adding below will only execute when all previous segments have been fsynced. | ||
if w.segment != nil { | ||
currSegment := w.segment | ||
w.actorc <- func() { | ||
if err := w.fsync(currSegment); err != nil { | ||
w.logger.Error("unable to fsync current segment", "err", err) | ||
} | ||
close(done) | ||
} | ||
} else { | ||
w.actorc <- func() { | ||
close(done) | ||
} | ||
} | ||
|
||
w.mtx.Unlock() | ||
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. i'm not sure about where we acquire and release the lock. The potential problems i can think of right now are
i don't think it's possible to solve both. From reading the only other place which uses actorc and the places which do operations on the WL while holding the lock, I think that 2. is assumed to never happen. So I think we should release the lock only after getting 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. something i forgot - if you end up taking a copy of w.segment, then you should do that while holding a lock inside the actor func instead of before creating the actor closure - this will help avoid races |
||
|
||
<-done | ||
return nil | ||
} |
Uh oh!
There was an error while loading. Please reload this page.