Skip to content

Commit a139dd7

Browse files
committed
logical: fix tombstone lease expiration check
The tombstone updater has the wrong condition when checking for expired leases. It refreshes the descriptor when the hlc comes before the expiration, when it should referesh the descriptor if the hlc is equal to or after expiration. In theory this could lead to the tombstone updater using a stale descriptor. It's unlikely this can cause a problem in practice. LDR periodically releases leases whenever it processes a checkpoint and the tombstone updater refreshes the lease every time it is called. Fixes: #159860 Release note: none
1 parent 3fe4a23 commit a139dd7

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

pkg/crosscluster/logical/tombstone_updater.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,13 @@ func (tu *tombstoneUpdater) addToBatch(
153153
)
154154
}
155155

156+
func (tu *tombstoneUpdater) hasValidLease(ctx context.Context, now hlc.Timestamp) bool {
157+
return tu.leased.descriptor != nil && tu.leased.descriptor.Expiration(ctx).After(now)
158+
}
159+
156160
func (tu *tombstoneUpdater) getDeleter(ctx context.Context, txn *kv.Txn) (row.Deleter, error) {
157161
timestamp := txn.ProvisionalCommitTimestamp()
158-
if tu.leased.descriptor == nil || !timestamp.After(tu.leased.descriptor.Expiration(ctx)) {
162+
if !tu.hasValidLease(ctx, timestamp) {
159163
tu.ReleaseLeases(ctx)
160164

161165
var err error

pkg/crosscluster/logical/tombstone_updater_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,44 @@ import (
1616
"github.com/cockroachdb/cockroach/pkg/sql/catalog/lease"
1717
"github.com/cockroachdb/cockroach/pkg/sql/isql"
1818
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
19+
"github.com/cockroachdb/cockroach/pkg/util/hlc"
1920
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
2021
"github.com/cockroachdb/cockroach/pkg/util/log"
2122
"github.com/stretchr/testify/require"
2223
)
2324

25+
type fakeDescriptor struct {
26+
lease.LeasedDescriptor
27+
expiration hlc.Timestamp
28+
}
29+
30+
func (e *fakeDescriptor) Expiration(ctx context.Context) hlc.Timestamp {
31+
return e.expiration
32+
}
33+
34+
func TestTombstoneDescriptorLease(t *testing.T) {
35+
defer leaktest.AfterTest(t)()
36+
defer log.Scope(t).Close(t)
37+
38+
ctx := context.Background()
39+
clock := hlc.NewClockForTesting(nil)
40+
41+
before := clock.Now()
42+
expiration := before.Add(1, 0)
43+
after := expiration.Add(1, 0)
44+
45+
tu := &tombstoneUpdater{}
46+
require.False(t, tu.hasValidLease(ctx, before))
47+
48+
tu.leased.descriptor = &fakeDescriptor{
49+
expiration: expiration,
50+
}
51+
52+
require.True(t, tu.hasValidLease(ctx, before))
53+
require.False(t, tu.hasValidLease(ctx, expiration))
54+
require.False(t, tu.hasValidLease(ctx, after))
55+
}
56+
2457
func TestTombstoneUpdaterSetsOriginID(t *testing.T) {
2558
defer leaktest.AfterTest(t)()
2659
defer log.Scope(t).Close(t)

0 commit comments

Comments
 (0)