diff --git a/server/lease/lessor.go b/server/lease/lessor.go index f4902d275ce..f82fe5cc133 100644 --- a/server/lease/lessor.go +++ b/server/lease/lessor.go @@ -351,6 +351,7 @@ func (le *lessor) Checkpoint(id LeaseID, remainingTTL int64) error { if l, ok := le.leaseMap[id]; ok { // when checkpointing, we only update the remainingTTL, Promote is responsible for applying this to lease expiry l.remainingTTL = remainingTTL + l.persistTo(le.b) if le.isPrimary() { // schedule the next checkpoint as needed le.scheduleCheckpointIfNeeded(l) @@ -784,9 +785,10 @@ func (le *lessor) initAndRecover() { ttl: lpb.TTL, // itemSet will be filled in when recover key-value pairs // set expiry to forever, refresh when promoted - itemSet: make(map[LeaseItem]struct{}), - expiry: forever, - revokec: make(chan struct{}), + itemSet: make(map[LeaseItem]struct{}), + expiry: forever, + revokec: make(chan struct{}), + remainingTTL: lpb.RemainingTTL, } } le.leaseExpiredNotifier.Init() diff --git a/tests/integration/v3_lease_test.go b/tests/integration/v3_lease_test.go index 0e649fd803e..240e6bcbaf8 100644 --- a/tests/integration/v3_lease_test.go +++ b/tests/integration/v3_lease_test.go @@ -236,6 +236,7 @@ func TestV3LeaseCheckpoint(t *testing.T) { ttl time.Duration checkpointingInterval time.Duration leaderChanges int + clusterSize int expectTTLIsGT time.Duration expectTTLIsLT time.Duration }{ @@ -243,6 +244,7 @@ func TestV3LeaseCheckpoint(t *testing.T) { name: "Checkpointing disabled, lease TTL is reset", ttl: 300 * time.Second, leaderChanges: 1, + clusterSize: 3, expectTTLIsGT: 298 * time.Second, }, { @@ -251,6 +253,16 @@ func TestV3LeaseCheckpoint(t *testing.T) { checkpointingEnabled: true, checkpointingInterval: 10 * time.Second, leaderChanges: 1, + clusterSize: 3, + expectTTLIsLT: 290 * time.Second, + }, + { + name: "Checkpointing enabled 10s, lease TTL is preserved after cluster restart", + ttl: 300 * time.Second, + checkpointingEnabled: true, + checkpointingInterval: 10 * time.Second, + leaderChanges: 1, + clusterSize: 1, expectTTLIsLT: 290 * time.Second, }, { @@ -260,6 +272,7 @@ func TestV3LeaseCheckpoint(t *testing.T) { checkpointingEnabled: true, checkpointingInterval: 10 * time.Second, leaderChanges: 2, + clusterSize: 3, expectTTLIsLT: 280 * time.Second, }, } @@ -267,7 +280,7 @@ func TestV3LeaseCheckpoint(t *testing.T) { t.Run(tc.name, func(t *testing.T) { integration.BeforeTest(t) config := &integration.ClusterConfig{ - Size: 3, + Size: tc.clusterSize, EnableLeaseCheckpoint: tc.checkpointingEnabled, LeaseCheckpointInterval: tc.checkpointingInterval, }