diff --git a/server/lease/lessor.go b/server/lease/lessor.go index db738efcc..75a6834a7 100644 --- a/server/lease/lessor.go +++ b/server/lease/lessor.go @@ -281,10 +281,6 @@ func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) { // with longer TTL to reduce renew load. l := NewLease(id, ttl) - if l.ttl < le.minLeaseTTL { - l.ttl = le.minLeaseTTL - } - le.mu.Lock() defer le.mu.Unlock() @@ -292,6 +288,10 @@ func (le *lessor) Grant(id LeaseID, ttl int64) (*Lease, error) { return nil, ErrLeaseExists } + if l.ttl < le.minLeaseTTL { + l.ttl = le.minLeaseTTL + } + if le.isPrimary() { l.refresh(0) } else { @@ -322,11 +322,6 @@ func (le *lessor) Revoke(id LeaseID) error { return ErrLeaseNotFound } - // We shouldn't delete the lease inside the transaction lock, otherwise - // it may lead to deadlock with Grant or Checkpoint operations, which - // acquire the le.mu firstly and then the batchTx lock. - delete(le.leaseMap, id) - defer close(l.revokec) // unlock before doing external work le.mu.Unlock() @@ -345,6 +340,9 @@ func (le *lessor) Revoke(id LeaseID) error { txn.DeleteRange([]byte(key), nil) } + le.mu.Lock() + defer le.mu.Unlock() + delete(le.leaseMap, l.ID) // lease deletion needs to be in the same backend transaction with the // kv deletion. Or we might end up with not executing the revoke or not // deleting the keys if etcdserver fails in between.