From 13880aa44db31e7f4ef46c3e6d9224dbe3233f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfonso=20Subiotto=20Marqu=C3=A9s?= Date: Mon, 20 May 2024 09:03:57 +0200 Subject: [PATCH] wal: correctly set nextTx on Truncate (#866) On Truncate(k), if k was logged to the WAL the behavior is unchanged. However, if k had not yet been logged to the WAL, the WAL performed a full reset of the WAL and set the next expected txn to k+1. This is incorrect, since the semantics of truncate are that k becomes the first entry in the WAL after truncation. --- wal/wal.go | 2 +- wal/wal_test.go | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/wal/wal.go b/wal/wal.go index 4bf72c959..2d373fe1b 100644 --- a/wal/wal.go +++ b/wal/wal.go @@ -410,7 +410,7 @@ func (w *FileWAL) process() { // last index are now 0. The underlying WAL will allow a // record with any index to be written, however we only // want to allow the next index to be logged. - w.protected.nextTx = truncateTx + 1 + w.protected.nextTx = truncateTx // Remove any records that have not yet been written and // are now below the nextTx. for w.protected.queue.Len() > 0 { diff --git a/wal/wal_test.go b/wal/wal_test.go index fd7311d8c..364e1a60c 100644 --- a/wal/wal_test.go +++ b/wal/wal_test.go @@ -246,14 +246,17 @@ func TestWALTruncate(t *testing.T) { // be observed on replay. require.NoError(t, w.Log(1, logRecord("should-not-be-logged"))) - // The only valid record to log is the one after truncateIdx. - require.NoError(t, w.Log(truncateIdx+1, logRecord("should-be-logged"))) + // The only valid record to log is truncateIdx. Note that Truncate + // semantics are that Truncate truncates up to but not including the + // truncateIdx. In other words, truncateIdx becomes the first entry in + // the WAL. + require.NoError(t, w.Log(truncateIdx, logRecord("should-be-logged"))) // Wait for record to be logged. require.Eventually(t, func() bool { first, _ := w.FirstIndex() last, _ := w.LastIndex() - return first == truncateIdx+1 && last == truncateIdx+1 + return first == truncateIdx && last == truncateIdx }, time.Second, 10*time.Millisecond) numRecords := 0 @@ -261,7 +264,7 @@ func TestWALTruncate(t *testing.T) { t, w.Replay(0, func(tx uint64, r *walpb.Record) error { numRecords++ - require.Equal(t, uint64(truncateIdx+1), tx) + require.Equal(t, uint64(truncateIdx), tx) require.Equal(t, []byte("should-be-logged"), r.Entry.GetWrite().Data) return nil }),