-
Notifications
You must be signed in to change notification settings - Fork 477
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
ledger: report catchpoint writing only when it actually started #5413
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 |
---|---|---|
|
@@ -449,7 +449,7 @@ func (ct *catchpointTracker) produceCommittingTask(committedRound basics.Round, | |
ct.catchpointInterval, dcr.catchpointLookback) | ||
|
||
// if we're still writing the previous balances, we can't move forward yet. | ||
if ct.IsWritingCatchpointDataFile() { | ||
if ct.isWritingCatchpointDataFile() { | ||
// if we hit this path, it means that we're still writing a catchpoint. | ||
// see if the new delta range contains another catchpoint. | ||
if hasIntermediateFirstStageRound { | ||
|
@@ -469,16 +469,13 @@ func (ct *catchpointTracker) produceCommittingTask(committedRound basics.Round, | |
dcr.catchpointFirstStage = true | ||
|
||
if ct.enableGeneratingCatchpointFiles { | ||
// store non-zero ( all ones ) into the catchpointWriting atomic variable to indicate that a catchpoint is being written ( or, queued to be written ) | ||
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. the fix: moved to prepareCommit |
||
atomic.StoreInt32(&ct.catchpointDataWriting, int32(-1)) | ||
ct.catchpointDataSlowWriting = make(chan struct{}, 1) | ||
if hasMultipleIntermediateFirstStageRounds { | ||
close(ct.catchpointDataSlowWriting) | ||
} | ||
} | ||
} | ||
|
||
dcr.catchpointDataWriting = &ct.catchpointDataWriting | ||
dcr.enableGeneratingCatchpointFiles = ct.enableGeneratingCatchpointFiles | ||
|
||
rounds := ct.calculateCatchpointRounds(dcr) | ||
|
@@ -493,6 +490,11 @@ func (ct *catchpointTracker) prepareCommit(dcc *deferredCommitContext) error { | |
ct.catchpointsMu.RLock() | ||
defer ct.catchpointsMu.RUnlock() | ||
|
||
if ct.enableGeneratingCatchpointFiles && dcc.catchpointFirstStage { | ||
// store non-zero ( all ones ) into the catchpointWriting atomic variable to indicate that a catchpoint is being written | ||
atomic.StoreInt32(&ct.catchpointDataWriting, int32(-1)) | ||
} | ||
|
||
dcc.committedRoundDigests = make([]crypto.Digest, dcc.offset) | ||
copy(dcc.committedRoundDigests, ct.roundDigest[:dcc.offset]) | ||
|
||
|
@@ -926,10 +928,10 @@ func (ct *catchpointTracker) postCommitUnlocked(ctx context.Context, dcc *deferr | |
} | ||
} | ||
|
||
// handleUnorderedCommit is a special method for handling deferred commits that are out of order. | ||
// handleUnorderedCommitOrError is a special method for handling deferred commits that are out of order. | ||
// Tracker might update own state in this case. For example, account catchpoint tracker cancels | ||
// scheduled catchpoint writing that deferred commit. | ||
func (ct *catchpointTracker) handleUnorderedCommit(dcc *deferredCommitContext) { | ||
func (ct *catchpointTracker) handleUnorderedCommitOrError(dcc *deferredCommitContext) { | ||
// if the node is configured to generate catchpoint files, we might need to update the catchpointWriting variable. | ||
if ct.enableGeneratingCatchpointFiles { | ||
// determine if this was a catchpoint round | ||
|
@@ -1085,9 +1087,9 @@ func (ct *catchpointTracker) accountsUpdateBalances(accountsDeltas compactAccoun | |
return | ||
} | ||
|
||
// IsWritingCatchpointDataFile returns true iff a (first stage) catchpoint data file | ||
// isWritingCatchpointDataFile returns true iff a (first stage) catchpoint data file | ||
// is being generated. | ||
func (ct *catchpointTracker) IsWritingCatchpointDataFile() bool { | ||
func (ct *catchpointTracker) isWritingCatchpointDataFile() bool { | ||
return atomic.LoadInt32(&ct.catchpointDataWriting) != 0 | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,10 +118,11 @@ type ledgerTracker interface { | |
// An optional context is provided for long-running operations. | ||
postCommitUnlocked(context.Context, *deferredCommitContext) | ||
|
||
// handleUnorderedCommit is a special method for handling deferred commits that are out of order. | ||
// handleUnorderedCommitOrError is a special method for handling deferred commits that are out of order | ||
// or to handle errors reported by other trackers while committing a batch. | ||
// Tracker might update own state in this case. For example, account updates tracker cancels | ||
// scheduled catchpoint writing that deferred commit. | ||
handleUnorderedCommit(*deferredCommitContext) | ||
// scheduled catchpoint writing flag for this batch. | ||
handleUnorderedCommitOrError(*deferredCommitContext) | ||
|
||
// close terminates the tracker, reclaiming any resources | ||
// like open database connections or goroutines. close may | ||
|
@@ -214,12 +215,6 @@ type deferredCommitRange struct { | |
// a catchpoint data file, in this commit cycle iteration. | ||
catchpointFirstStage bool | ||
|
||
// catchpointDataWriting is a pointer to a variable with the same name in the | ||
// catchpointTracker. It's used in order to reset the catchpointDataWriting flag from | ||
// the acctupdates's prepareCommit/commitRound (which is called before the | ||
// corresponding catchpoint tracker method. | ||
catchpointDataWriting *int32 | ||
|
||
// enableGeneratingCatchpointFiles controls whether the node produces catchpoint files or not. | ||
enableGeneratingCatchpointFiles bool | ||
|
||
|
@@ -514,7 +509,7 @@ func (tr *trackerRegistry) commitRound(dcc *deferredCommitContext) error { | |
if tr.dbRound < dbRound || offset < uint64(tr.dbRound-dbRound) { | ||
tr.log.Warnf("out of order deferred commit: offset %d, dbRound %d but current tracker DB round is %d", offset, dbRound, tr.dbRound) | ||
for _, lt := range tr.trackers { | ||
lt.handleUnorderedCommit(dcc) | ||
lt.handleUnorderedCommitOrError(dcc) | ||
} | ||
tr.mu.RUnlock() | ||
return nil | ||
|
@@ -538,19 +533,27 @@ func (tr *trackerRegistry) commitRound(dcc *deferredCommitContext) error { | |
dcc.oldBase = dbRound | ||
dcc.flushTime = time.Now() | ||
|
||
var err error | ||
for _, lt := range tr.trackers { | ||
err := lt.prepareCommit(dcc) | ||
err = lt.prepareCommit(dcc) | ||
if err != nil { | ||
tr.log.Errorf(err.Error()) | ||
tr.mu.RUnlock() | ||
return err | ||
algorandskiy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
break | ||
} | ||
} | ||
if err != nil { | ||
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. if another tracker overwrites the err with nil it won't be passed to handleUnorderedCommitOrError? 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. maybe nest the error handling right inside the iteration, is this crazy? for _, lt := range tr.trackers {
err := lt.prepareCommit(dcc)
if err != nil {
tr.log.Errorf(err.Error())
for _, lt := range tr.trackers {
lt.handleUnorderedCommitOrError(dcc)
}
tr.mu.RUnlock()
return err
}
} 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 had this before and did not really liked so moved out of the outer loop 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. Current approach is pretty straightforward to follow now. |
||
for _, lt := range tr.trackers { | ||
lt.handleUnorderedCommitOrError(dcc) | ||
} | ||
tr.mu.RUnlock() | ||
return err | ||
} | ||
|
||
tr.mu.RUnlock() | ||
|
||
start := time.Now() | ||
ledgerCommitroundCount.Inc(nil) | ||
err := tr.dbs.Transaction(func(ctx context.Context, tx trackerdb.TransactionScope) (err error) { | ||
err = tr.dbs.Transaction(func(ctx context.Context, tx trackerdb.TransactionScope) (err error) { | ||
arw, err := tx.MakeAccountsReaderWriter() | ||
if err != nil { | ||
return err | ||
|
@@ -568,6 +571,9 @@ func (tr *trackerRegistry) commitRound(dcc *deferredCommitContext) error { | |
ledgerCommitroundMicros.AddMicrosecondsSince(start, nil) | ||
|
||
if err != nil { | ||
for _, lt := range tr.trackers { | ||
lt.handleUnorderedCommitOrError(dcc) | ||
} | ||
tr.log.Warnf("unable to advance tracker db snapshot (%d-%d): %v", dbRound, dbRound+basics.Round(offset), err) | ||
return err | ||
} | ||
|
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.
this code is the same as catchpointtracker's
handleUnorderedCommitOrError
and called after commitRound / prepareCommit for all trackers in case of errors.