Skip to content

Commit 809103b

Browse files
committed
Simplify compact loop error handling
Rather than restarting the outer loop on unhandled error, simmply break out of the inner loop on any error. We always want to update the compact and target rev, and do post-compact operations - so the only thing we really need to check the error for is logging and metrics. Signed-off-by: Brad Davidson <[email protected]>
1 parent 281174c commit 809103b

File tree

1 file changed

+54
-26
lines changed
  • pkg/logstructured/sqllog

1 file changed

+54
-26
lines changed

Diff for: pkg/logstructured/sqllog/sql.go

+54-26
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ func (s *SQLLog) compactor(interval time.Duration) {
113113
targetCompactRev, _ := s.CurrentRevision(s.ctx)
114114
logrus.Tracef("COMPACT starting compactRev=%d targetCompactRev=%d", compactRev, targetCompactRev)
115115

116-
outer:
117116
for {
118117
select {
119118
case <-s.ctx.Done():
@@ -127,14 +126,20 @@ outer:
127126
// (several hundred ms) just for the database to execute the subquery to select the revisions to delete.
128127

129128
var (
129+
resultLabel string
130130
iterCompactRev int64
131+
iterStart time.Time
132+
iterCount int64
131133
compactedRev int64
132134
currentRev int64
133135
err error
134136
)
135137

138+
resultLabel = metrics.ResultSuccess
136139
iterCompactRev = compactRev
137140
compactedRev = compactRev
141+
iterStart = time.Now()
142+
iterCount = 0
138143

139144
for iterCompactRev < targetCompactRev {
140145
// Set move iteration target compactBatchSize revisions forward, or
@@ -145,54 +150,74 @@ outer:
145150
iterCompactRev = targetCompactRev
146151
}
147152

148-
compactedRev, currentRev, err = s.compact(compactedRev, iterCompactRev)
149-
if err != nil {
150-
// ErrCompacted indicates that no further work is necessary - either compactRev changed since the
151-
// last iteration because another client has compacted, or the requested revision has already been compacted.
152-
if err == server.ErrCompacted {
153-
break
154-
}
155-
logrus.Errorf("Compact failed: %v", err)
156-
metrics.CompactTotal.WithLabelValues(metrics.ResultError).Inc()
157-
continue outer
153+
// only update the compacted and current revisions if they are valid,
154+
// but break out of the inner loop on any error.
155+
compacted, current, cerr := s.compact(compactedRev, iterCompactRev)
156+
if compacted != 0 && current != 0 {
157+
compactedRev = compacted
158+
currentRev = current
158159
}
160+
if cerr != nil {
161+
err = cerr
162+
break
163+
}
164+
iterCount++
159165
}
160166

161-
if err := s.postCompact(); err != nil {
162-
logrus.Errorf("Post-compact operations failed: %v", err)
167+
if iterCount > 0 {
168+
logrus.Infof("COMPACT compacted from %d to %d in %d transactions over %s", compactRev, compactedRev, iterCount, time.Now().Sub(iterStart).Round(time.Millisecond))
169+
170+
// post-compact operation errors are not critical, but should be reported
171+
if perr := s.postCompact(); perr != nil {
172+
logrus.Errorf("Post-compact operations failed: %v", perr)
173+
}
163174
}
164175

165-
// Record the final results for the outer loop
176+
// Store the final results for this compact interval.
177+
// Note that one or more of the small-batch compact transactions
178+
// may have succeeded and moved the compact revision forward, even if err is non-nil.
166179
compactRev = compactedRev
167180
targetCompactRev = currentRev
168181

169-
metrics.CompactTotal.WithLabelValues(metrics.ResultSuccess).Inc()
182+
// ErrCompacted indicates that no further work is necessary - either compactRev changed since the
183+
// last iteration because another client has compacted, or the requested revision has already been compacted.
184+
if err != nil && err != server.ErrCompacted {
185+
logrus.Errorf("Compact failed: %v", err)
186+
resultLabel = metrics.ResultError
187+
}
188+
metrics.CompactTotal.WithLabelValues(resultLabel).Inc()
170189
}
171190
}
172191

173-
// compact removes deleted or replaced rows from the database. compactRev is the revision that was last compacted to.
174-
// If this changes between compactions, we know that someone else has compacted and we don't need to do it.
175-
// targetCompactRev is the revision that we should try to compact to. Upon success, the function returns the revision
176-
// compacted to, and the revision that we should try to compact to next time (the current revision).
177-
// This logic is directly cribbed from k8s.io/apiserver/pkg/storage/etcd3/compact.go
192+
// compact removes deleted or replaced rows from the database, and updates the compact rev key.
193+
// compactRev is the current compact revision; targetCompactRev is the revision to compact to.
194+
// If compactRev does not match what's in the database, we know that someone else has compacted and we don't need to do it.
195+
// Deletion of rows and update of the compact rev key is done within a single transaction. The transaction is rolled back on any error.
196+
//
197+
// On success, the function returns the revision compacted to, and the revision that we should try to compact to next time (the current revision).
198+
// ErrCompacted is returned if the current revision is stale, or the target revision has already been compacted.
199+
// In this case the compact and current revisions from the database are returned.
200+
// On any other error, the returned compact and current revisions should not be used.
201+
//
202+
// This logic is cribbed from k8s.io/apiserver/pkg/storage/etcd3/compact.go
178203
func (s *SQLLog) compact(compactRev int64, targetCompactRev int64) (int64, int64, error) {
179204
ctx, cancel := context.WithTimeout(s.ctx, compactTimeout)
180205
defer cancel()
181206

182207
t, err := s.d.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable})
183208
if err != nil {
184-
return compactRev, targetCompactRev, errors.Wrap(err, "failed to begin transaction")
209+
return 0, 0, errors.Wrap(err, "failed to begin transaction")
185210
}
186211
defer t.MustRollback()
187212

188213
currentRev, err := t.CurrentRevision(s.ctx)
189214
if err != nil {
190-
return compactRev, targetCompactRev, errors.Wrap(err, "failed to get current revision")
215+
return 0, 0, errors.Wrap(err, "failed to get current revision")
191216
}
192217

193218
dbCompactRev, err := t.GetCompactRevision(s.ctx)
194219
if err != nil {
195-
return compactRev, targetCompactRev, errors.Wrap(err, "failed to get compact revision")
220+
return 0, 0, errors.Wrap(err, "failed to get compact revision")
196221
}
197222

198223
// Check to see if another node already compacted. This is normal on a multi-server cluster.
@@ -206,7 +231,7 @@ func (s *SQLLog) compact(compactRev int64, targetCompactRev int64) (int64, int64
206231

207232
// Don't bother compacting to a revision that has already been compacted
208233
if targetCompactRev <= compactRev {
209-
logrus.Infof("COMPACT revision %d has already been compacted", targetCompactRev)
234+
logrus.Tracef("COMPACT revision %d has already been compacted", targetCompactRev)
210235
return dbCompactRev, currentRev, server.ErrCompacted
211236
}
212237

@@ -215,13 +240,16 @@ func (s *SQLLog) compact(compactRev int64, targetCompactRev int64) (int64, int64
215240
start := time.Now()
216241
deletedRows, err := t.Compact(s.ctx, targetCompactRev)
217242
if err != nil {
218-
return compactRev, targetCompactRev, errors.Wrapf(err, "failed to compact to revision %d", targetCompactRev)
243+
return 0, 0, errors.Wrapf(err, "failed to compact to revision %d", targetCompactRev)
219244
}
220245

221246
if err := t.SetCompactRevision(s.ctx, targetCompactRev); err != nil {
222-
return compactRev, targetCompactRev, errors.Wrap(err, "failed to record compact revision")
247+
return 0, 0, errors.Wrap(err, "failed to record compact revision")
223248
}
224249

250+
// only commit the transaction if we make it all the way through deleting and
251+
// updating the compact revision without any errors. The deferred rollback
252+
// becomes a no-op if the transaction is committed.
225253
t.MustCommit()
226254
logrus.Infof("COMPACT deleted %d rows from %d revisions in %s - compacted to %d/%d", deletedRows, (targetCompactRev - compactRev), time.Since(start), targetCompactRev, currentRev)
227255

0 commit comments

Comments
 (0)