Skip to content

Commit 616456a

Browse files
craig[bot]pav-kv
andcommitted
Merge #145423
145423: logstore: fix log durability bug r=tbg,arulajmani a=pav-kv See the added comment in code for explanation. We weren't hitting this bug only because the `overwriting` flag, as of today, can be true only if `m.MustSync()` is true, because every time raft appends to a log, it also adds a `MsgAppResp` message. So we, whether intentionally or not, relied on a subtle implementation detail in raft. This commit makes the log storage more robust and independent of this detail. Epic: CRDB-46488 Co-authored-by: Pavel Kalinnikov <[email protected]>
2 parents 81377d1 + 05efa5c commit 616456a

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

pkg/kv/kvserver/logstore/logstore.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,17 @@ func (s *LogStore) storeEntriesAndCommitBatch(
239239
// (Replica), so this comment might need to move.
240240
stats.PebbleBegin = crtime.NowMono()
241241
stats.PebbleBytes = int64(batch.Len())
242-
wantsSync := m.MustSync()
242+
// We want a timely sync in two cases:
243+
// 1. Raft has requested one, with MustSync(). This usually means there are
244+
// messages to send to the proposer (MsgVoteResp/MsgAppResp, etc.) conditional
245+
// on this write being durable. These messages are on the critical path for
246+
// raft to make progress, e.g. elect/fortify leader or commit entries.
247+
// 2. The log append overwrites a suffix of the log. There can be sideloaded
248+
// entry files to remove as a result, so we sync Pebble before doing that. The
249+
// sync is blocking for convenience, but we could instead wait for sync
250+
// elsewhere, and remove the files asynchronously. There are some limitations
251+
// today preventing this, see #136416.
252+
wantsSync := m.MustSync() || overwriting
243253
willSync := wantsSync && !DisableSyncRaftLog.Get(&s.Settings.SV)
244254
// Use the non-blocking log sync path if we are performing a log sync ...
245255
nonBlockingSync := willSync &&
@@ -248,7 +258,7 @@ func (s *LogStore) storeEntriesAndCommitBatch(
248258
// and we are not overwriting any previous log entries. If we are
249259
// overwriting, we may need to purge the sideloaded SSTables associated with
250260
// overwritten entries. This must be performed after the corresponding
251-
// entries are durably replaced and it's easier to do ensure proper ordering
261+
// entries are durably replaced and it's easier to ensure proper ordering
252262
// using a blocking log sync. This is a rare case, so it's not worth
253263
// optimizing for.
254264
!overwriting &&

0 commit comments

Comments
 (0)