From 5aaa2d5b2ccf13cb38ded87d8ef5c62b2ea65efc Mon Sep 17 00:00:00 2001 From: Adam Fraser Date: Mon, 30 Oct 2023 17:03:43 -0700 Subject: [PATCH] CBG-3578 [3.1.2 backport] Uptake cbgt fix for MB-59249 (#6563) --- base/dcp_test.go | 5 +- db/import_listener.go | 6 ++ go.mod | 12 ++-- go.sum | 24 +++---- rest/importtest/import_partition_test.go | 79 ++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 21 deletions(-) create mode 100644 rest/importtest/import_partition_test.go diff --git a/base/dcp_test.go b/base/dcp_test.go index 46127d806d..bff7fbd825 100644 --- a/base/dcp_test.go +++ b/base/dcp_test.go @@ -428,7 +428,7 @@ func TestConcurrentCBGTIndexCreation(t *testing.T) { spec := bucket.BucketSpec testDBName := "testDB" - // Use an bucket-backed cfg + // Use a bucket-backed cfg cfg, err := NewCfgSG(ctx, dataStore, "") require.NoError(t, err) @@ -460,8 +460,8 @@ func TestConcurrentCBGTIndexCreation(t *testing.T) { log.Printf("Starting manager for %s", managerUUID) startErr := context.StartManager(ctx, testDBName, configGroup, bucket, spec, "", nil, DefaultImportPartitions) assert.NoError(t, startErr) - managerWg.Done() + // ensure all goroutines start the manager before we start closing them select { case <-terminatorChan: @@ -474,7 +474,6 @@ func TestConcurrentCBGTIndexCreation(t *testing.T) { } managerWg.Wait() close(terminator) - } // Compare Atoi vs map lookup for partition conversion diff --git a/db/import_listener.go b/db/import_listener.go index e20a21ab68..cee16415ad 100644 --- a/db/import_listener.go +++ b/db/import_listener.go @@ -230,3 +230,9 @@ func (il *importListener) Stop() { close(il.terminator) } } + +func (db *DatabaseContext) PartitionCount() int { + il := db.ImportListener + _, pindexes := il.cbgtContext.Manager.CurrentMaps() + return len(pindexes) +} diff --git a/go.mod b/go.mod index f8967d3a8c..334cff728f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/bhoriuchi/graphql-go-tools v1.0.0 github.com/coreos/go-oidc v2.2.1+incompatible - github.com/couchbase/cbgt v1.3.7 + github.com/couchbase/cbgt v1.3.8 github.com/couchbase/clog v0.1.0 github.com/couchbase/go-blip v0.0.0-20221021161139-215cbac22bd7 github.com/couchbase/go-couchbase v0.1.1 @@ -31,9 +31,9 @@ require ( github.com/samuel/go-metrics v0.0.0-20150819231912-7ccf3e0e1fb1 github.com/shirou/gopsutil v3.21.11+incompatible github.com/stretchr/testify v1.8.4 - golang.org/x/crypto v0.11.0 + golang.org/x/crypto v0.14.0 golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb - golang.org/x/net v0.12.0 + golang.org/x/net v0.17.0 golang.org/x/oauth2 v0.9.0 gopkg.in/couchbaselabs/gocbconnstr.v1 v1.0.4 gopkg.in/square/go-jose.v2 v2.6.0 @@ -45,7 +45,7 @@ require ( github.com/aws/aws-sdk-go v1.44.299 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/couchbase/blance v0.1.3 // indirect + github.com/couchbase/blance v0.1.5 // indirect github.com/couchbase/cbauth v0.1.10 // indirect github.com/couchbase/tools-common/cloud v1.0.0 // indirect github.com/couchbase/tools-common/fs v1.0.0 // indirect @@ -72,8 +72,8 @@ require ( github.com/stretchr/objx v0.5.0 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.31.0 // indirect diff --git a/go.sum b/go.sum index ba2b03435f..f8f0734b65 100644 --- a/go.sum +++ b/go.sum @@ -61,12 +61,12 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/couchbase/blance v0.1.3 h1:CJCirD3+N02Z0w/ybZTqqSJa9XMbsCZO9jHxCEAPQqE= -github.com/couchbase/blance v0.1.3/go.mod h1:2Sa/nsJSieN/r3T9LsrUYWeQ015qDsuHybhz4F4JcHU= +github.com/couchbase/blance v0.1.5 h1:kNSAwhb8FXSJpicJ8R8Kk7+0V1+MyTcY1MOHIDbU79w= +github.com/couchbase/blance v0.1.5/go.mod h1:2Sa/nsJSieN/r3T9LsrUYWeQ015qDsuHybhz4F4JcHU= github.com/couchbase/cbauth v0.1.10 h1:ixJGG9mAgL1HnWKt2eKmJ8gJa0rkaUURtDPDak7Dcts= github.com/couchbase/cbauth v0.1.10/go.mod h1:YHG+5rUI6GoLLlIViT9IfD0nwqEebBcl66TQ4pDFDw4= -github.com/couchbase/cbgt v1.3.7 h1:ZDPMS1SlNsTdl8yRSbQ6B751q43TpMk3lBkIynWqCPY= -github.com/couchbase/cbgt v1.3.7/go.mod h1:xntLl+vFnPmI49TAaolG4a1O6oOZ5YFKdqtoTMvQLWw= +github.com/couchbase/cbgt v1.3.8 h1:DmIHNfbuGkmNi85lcWFxeDReoame9Xz2c7LjvbMuhZs= +github.com/couchbase/cbgt v1.3.8/go.mod h1:kkK2gk/2LTuw6A+a4W22m2Pcta7JHu1PiXS8sJ3ow9g= github.com/couchbase/clog v0.1.0 h1:4Kh/YHkhRjMCbdQuvRVsm39XZh4FtL1d8fAwJsHrEPY= github.com/couchbase/clog v0.1.0/go.mod h1:7tzUpEOsE+fgU81yfcjy5N1H6XtbVC8SgOz/3mCjmd4= github.com/couchbase/go-blip v0.0.0-20221021161139-215cbac22bd7 h1:/GTlMVovmGKrFAl5e7u9CXuhjTlR5a4911Ujou18Q4Q= @@ -345,8 +345,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -412,8 +412,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -477,8 +477,8 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -490,8 +490,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/rest/importtest/import_partition_test.go b/rest/importtest/import_partition_test.go new file mode 100644 index 0000000000..a1e50aaa14 --- /dev/null +++ b/rest/importtest/import_partition_test.go @@ -0,0 +1,79 @@ +// Copyright 2023-Present Couchbase, Inc. +// +// Use of this software is governed by the Business Source License included +// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified +// in that file, in accordance with the Business Source License, use of this +// software will be governed by the Apache License, Version 2.0, included in +// the file licenses/APL2.txt. + +package importtest + +import ( + "log" + "sync" + "testing" + + "github.com/couchbase/sync_gateway/base" + "github.com/couchbase/sync_gateway/rest" +) + +func TestImportPartitionsOnConcurrentStart(t *testing.T) { + if base.UnitTestUrlIsWalrus() { + t.Skip("This test only works against Couchbase Server") + } + + // Start multiple rest testers concurrently + numNodes := 4 + numImportPartitions := uint16(16) + expectedPartitions := 4 + restTesters := make([]*rest.RestTester, numNodes) + tb := base.GetTestBucket(t) + ctx := base.TestCtx(t) + defer tb.Close(ctx) + var wg sync.WaitGroup + for i := 0; i < numNodes; i++ { + wg.Add(1) + go func(i int) { + noCloseTB := tb.NoCloseClone() + rt := rest.NewRestTester(t, &rest.RestTesterConfig{ + CustomTestBucket: noCloseTB, + DatabaseConfig: &rest.DatabaseConfig{DbConfig: rest.DbConfig{ + AutoImport: true, + ImportPartitions: base.Uint16Ptr(numImportPartitions), + }}, + }) + restTesters[i] = rt + wg.Done() + }(i) + } + wg.Wait() + + defer func() { + for _, rt := range restTesters { + if rt != nil { + rt.Close() + } + } + }() + + rest.WaitAndAssertCondition(t, func() bool { + totalPartitions := uint16(0) + balancedPartitions := true + currentPartitions := make([]int, len(restTesters)) + for i, rt := range restTesters { + rtPartitions := rt.GetDatabase().PartitionCount() + currentPartitions[i] = rtPartitions + totalPartitions = totalPartitions + uint16(rtPartitions) + if rtPartitions != expectedPartitions { + balancedPartitions = false + } + } + if totalPartitions == numImportPartitions && balancedPartitions == true { + log.Printf("Partitions are balanced. Current total: %d, distribution: %v", totalPartitions, currentPartitions) + return true + } else { + log.Printf("Waiting for balanced partitions. Current total: %d, distribution: %v", totalPartitions, currentPartitions) + return false + } + }) +}