From a3a60f0d9054687c0cf671d4f9da30379f9b0878 Mon Sep 17 00:00:00 2001 From: Chao Chen Date: Fri, 22 Oct 2021 16:36:37 -0700 Subject: [PATCH] Backport: non mutating requests pass through quotaKVServer when NOSPACE This is a backport of https://github.com/etcd-io/etcd/pull/13435 and is part of the work for 3.4.20 https://github.com/etcd-io/etcd/issues/14232. The original change had a second commit that modifies a changelog file. The 3.4 branch does not include any changelog file, so that part was not cherry-picked. Local Testing: - `make build` - `make test` Both succeed. --- etcdserver/quota.go | 8 +++++++- integration/v3_alarm_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/etcdserver/quota.go b/etcdserver/quota.go index 6d70430e73cb..a26c66a6aba5 100644 --- a/etcdserver/quota.go +++ b/etcdserver/quota.go @@ -135,8 +135,14 @@ func NewBackendQuota(s *EtcdServer, name string) Quota { } func (b *backendQuota) Available(v interface{}) bool { + cost := b.Cost(v) + // if there are no mutating requests, it's safe to pass through + if cost == 0 { + return true + } + // TODO: maybe optimize backend.Size() - return b.s.Backend().Size()+int64(b.Cost(v)) < b.maxBackendBytes + return b.s.Backend().Size()+int64(cost) < b.maxBackendBytes } func (b *backendQuota) Cost(v interface{}) int { diff --git a/integration/v3_alarm_test.go b/integration/v3_alarm_test.go index 9a71f87f26d3..cee34ddff52a 100644 --- a/integration/v3_alarm_test.go +++ b/integration/v3_alarm_test.go @@ -92,6 +92,30 @@ func TestV3StorageQuotaApply(t *testing.T) { } } + // txn with non-mutating Ops should go through when NOSPACE alarm is raised + _, err = kvc0.Txn(context.TODO(), &pb.TxnRequest{ + Compare: []*pb.Compare{ + { + Key: key, + Result: pb.Compare_EQUAL, + Target: pb.Compare_CREATE, + TargetUnion: &pb.Compare_CreateRevision{CreateRevision: 0}, + }, + }, + Success: []*pb.RequestOp{ + { + Request: &pb.RequestOp_RequestDeleteRange{ + RequestDeleteRange: &pb.DeleteRangeRequest{ + Key: key, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithTimeout(context.TODO(), RequestWaitTimeout) defer cancel()