diff --git a/pkg/BUILD.bazel b/pkg/BUILD.bazel index c8320fc23196..d63cc3720e28 100644 --- a/pkg/BUILD.bazel +++ b/pkg/BUILD.bazel @@ -30,6 +30,7 @@ ALL_TESTS = [ "//pkg/ccl/changefeedccl:changefeedccl_test", "//pkg/ccl/cliccl:cliccl_test", "//pkg/ccl/cloudccl/amazon:amazon_test", + "//pkg/ccl/cloudccl/azure:azure_test", "//pkg/ccl/cloudccl/externalconn:externalconn_test", "//pkg/ccl/cloudccl/gcp:gcp_test", "//pkg/ccl/importerccl:importerccl_test", @@ -666,6 +667,7 @@ GO_TARGETS = [ "//pkg/ccl/cliccl:cliccl", "//pkg/ccl/cliccl:cliccl_test", "//pkg/ccl/cloudccl/amazon:amazon_test", + "//pkg/ccl/cloudccl/azure:azure_test", "//pkg/ccl/cloudccl/externalconn:externalconn_test", "//pkg/ccl/cloudccl/gcp:gcp_test", "//pkg/ccl/cmdccl/enc_utils:enc_utils", @@ -2092,6 +2094,7 @@ GET_X_DATA_TARGETS = [ "//pkg/ccl/cliccl:get_x_data", "//pkg/ccl/cliccl/cliflagsccl:get_x_data", "//pkg/ccl/cloudccl/amazon:get_x_data", + "//pkg/ccl/cloudccl/azure:get_x_data", "//pkg/ccl/cloudccl/externalconn:get_x_data", "//pkg/ccl/cloudccl/gcp:get_x_data", "//pkg/ccl/cmdccl/enc_utils:get_x_data", diff --git a/pkg/ccl/cloudccl/azure/BUILD.bazel b/pkg/ccl/cloudccl/azure/BUILD.bazel new file mode 100644 index 000000000000..7bf846553ccd --- /dev/null +++ b/pkg/ccl/cloudccl/azure/BUILD.bazel @@ -0,0 +1,32 @@ +load("//build/bazelutil/unused_checker:unused.bzl", "get_x_data") +load("@io_bazel_rules_go//go:def.bzl", "go_test") + +go_test( + name = "azure_test", + srcs = [ + "azure_connection_test.go", + "main_test.go", + ], + deps = [ + "//pkg/base", + "//pkg/ccl", + "//pkg/ccl/kvccl/kvtenantccl", + "//pkg/ccl/utilccl", + "//pkg/cloud/azure", + "//pkg/cloud/externalconn/providers", + "//pkg/security/securityassets", + "//pkg/security/securitytest", + "//pkg/server", + "//pkg/testutils", + "//pkg/testutils/serverutils", + "//pkg/testutils/skip", + "//pkg/testutils/sqlutils", + "//pkg/testutils/testcluster", + "//pkg/util/leaktest", + "//pkg/util/log", + "//pkg/util/randutil", + "@com_github_azure_go_autorest_autorest//azure", + ], +) + +get_x_data(name = "get_x_data") diff --git a/pkg/ccl/cloudccl/azure/azure_connection_test.go b/pkg/ccl/cloudccl/azure/azure_connection_test.go new file mode 100644 index 000000000000..fbf7887d93dd --- /dev/null +++ b/pkg/ccl/cloudccl/azure/azure_connection_test.go @@ -0,0 +1,103 @@ +// Copyright 2022 The Cockroach Authors. +// +// Licensed as a CockroachDB Enterprise file under the Cockroach Community +// License (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt + +package azure + +import ( + "context" + "errors" + "fmt" + "net/url" + "os" + "testing" + + az "github.com/Azure/go-autorest/autorest/azure" + "github.com/cockroachdb/cockroach/pkg/base" + _ "github.com/cockroachdb/cockroach/pkg/ccl" + "github.com/cockroachdb/cockroach/pkg/cloud/azure" + _ "github.com/cockroachdb/cockroach/pkg/cloud/externalconn/providers" // import External Connection providers. + "github.com/cockroachdb/cockroach/pkg/testutils" + "github.com/cockroachdb/cockroach/pkg/testutils/skip" + "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" + "github.com/cockroachdb/cockroach/pkg/testutils/testcluster" + "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/cockroach/pkg/util/log" +) + +func (a azureConfig) URI(file string) string { + return fmt.Sprintf("azure-storage://%s/%s?%s=%s&%s=%s&%s=%s", + a.bucket, file, + azure.AzureAccountKeyParam, url.QueryEscape(a.key), + azure.AzureAccountNameParam, url.QueryEscape(a.account), + azure.AzureEnvironmentKeyParam, url.QueryEscape(a.environment)) +} + +type azureConfig struct { + account, key, bucket, environment string +} + +func getAzureConfig() (azureConfig, error) { + cfg := azureConfig{ + account: os.Getenv("AZURE_ACCOUNT_NAME"), + key: os.Getenv("AZURE_ACCOUNT_KEY"), + bucket: os.Getenv("AZURE_CONTAINER"), + environment: az.PublicCloud.Name, + } + if cfg.account == "" || cfg.key == "" || cfg.bucket == "" { + return azureConfig{}, errors.New("AZURE_ACCOUNT_NAME, AZURE_ACCOUNT_KEY, AZURE_CONTAINER must all be set") + } + if v, ok := os.LookupEnv(azure.AzureEnvironmentKeyParam); ok { + cfg.environment = v + } + return cfg, nil +} + +func TestExternalConnections(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + + dir, dirCleanupFn := testutils.TempDir(t) + defer dirCleanupFn() + + params := base.TestClusterArgs{} + params.ServerArgs.ExternalIODir = dir + + tc := testcluster.StartTestCluster(t, 1, params) + defer tc.Stopper().Stop(context.Background()) + + tc.WaitForNodeLiveness(t) + sqlDB := sqlutils.MakeSQLRunner(tc.Conns[0]) + + // Setup some dummy data. + sqlDB.Exec(t, `CREATE DATABASE foo`) + sqlDB.Exec(t, `USE foo`) + sqlDB.Exec(t, `CREATE TABLE foo (id INT PRIMARY KEY)`) + sqlDB.Exec(t, `INSERT INTO foo VALUES (1), (2), (3)`) + + createExternalConnection := func(externalConnectionName, uri string) { + sqlDB.Exec(t, fmt.Sprintf(`CREATE EXTERNAL CONNECTION '%s' AS '%s'`, externalConnectionName, uri)) + } + backupAndRestoreFromExternalConnection := func(backupExternalConnectionName string) { + backupURI := fmt.Sprintf("external://%s", backupExternalConnectionName) + sqlDB.Exec(t, fmt.Sprintf(`BACKUP DATABASE foo INTO '%s'`, backupURI)) + sqlDB.Exec(t, fmt.Sprintf(`RESTORE DATABASE foo FROM LATEST IN '%s' WITH new_db_name = bar`, backupURI)) + sqlDB.CheckQueryResults(t, `SELECT * FROM bar.foo`, [][]string{{"1"}, {"2"}, {"3"}}) + sqlDB.CheckQueryResults(t, `SELECT * FROM crdb_internal.invalid_objects`, [][]string{}) + sqlDB.Exec(t, `DROP DATABASE bar CASCADE`) + } + + cfg, err := getAzureConfig() + if err != nil { + skip.IgnoreLint(t, "TestExternalConnections not configured for Azure") + return + } + + ecName := "azure-ec" + createExternalConnection(ecName, cfg.URI("backup-ec")) + backupAndRestoreFromExternalConnection(ecName) +} diff --git a/pkg/ccl/cloudccl/azure/main_test.go b/pkg/ccl/cloudccl/azure/main_test.go new file mode 100644 index 000000000000..7cdecb0242a8 --- /dev/null +++ b/pkg/ccl/cloudccl/azure/main_test.go @@ -0,0 +1,35 @@ +// Copyright 2022 The Cockroach Authors. +// +// Licensed as a CockroachDB Enterprise file under the Cockroach Community +// License (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt + +package azure_test + +import ( + "os" + "testing" + + _ "github.com/cockroachdb/cockroach/pkg/ccl/kvccl/kvtenantccl" + "github.com/cockroachdb/cockroach/pkg/ccl/utilccl" + "github.com/cockroachdb/cockroach/pkg/security/securityassets" + "github.com/cockroachdb/cockroach/pkg/security/securitytest" + "github.com/cockroachdb/cockroach/pkg/server" + "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" + "github.com/cockroachdb/cockroach/pkg/testutils/testcluster" + "github.com/cockroachdb/cockroach/pkg/util/randutil" +) + +func TestMain(m *testing.M) { + defer utilccl.TestingEnableEnterprise()() + + securityassets.SetLoader(securitytest.EmbeddedAssets) + randutil.SeedForTests() + serverutils.InitTestServerFactory(server.TestServerFactory) + serverutils.InitTestClusterFactory(testcluster.TestClusterFactory) + os.Exit(m.Run()) +} + +//go:generate ../../../util/leaktest/add-leaktest.sh *_test.go diff --git a/pkg/ccl/cloudccl/externalconn/testdata/create_drop_external_connection b/pkg/ccl/cloudccl/externalconn/testdata/create_drop_external_connection index c3ee1fa200f1..f67058cbd48d 100644 --- a/pkg/ccl/cloudccl/externalconn/testdata/create_drop_external_connection +++ b/pkg/ccl/cloudccl/externalconn/testdata/create_drop_external_connection @@ -302,3 +302,41 @@ enable-check-external-storage ---- subtest end + +subtest basic-azure + +disable-check-external-storage +---- + +exec-sql +CREATE EXTERNAL CONNECTION "foo-azure" AS 'azure-storage://bucket/path?AZURE_ACCOUNT_NAME=foo&AZURE_ACCOUNT_KEY=Zm9vCg==&AZURE_ENVIRONMENT=AzureUSGovernmentCloud' +---- + +# Reject invalid azure external connections. +exec-sql +CREATE EXTERNAL CONNECTION "invalid-param-azure" AS 'azure-storage://bucket/path?INVALIDPARAM=baz' +---- +pq: failed to construct External Connection details: failed to create azure external connection: unknown azure query parameters: INVALIDPARAM + +exec-sql +CREATE EXTERNAL CONNECTION "foo-azure" AS 'azure-storage://bucket/path?&AZURE_ACCOUNT_KEY=Zm9vCg==&AZURE_ENVIRONMENT=AzureUSGovernmentCloud' +---- +pq: failed to construct External Connection details: failed to create azure external connection: azure uri missing "AZURE_ACCOUNT_NAME" parameter + +exec-sql +CREATE EXTERNAL CONNECTION "foo-azure" AS 'azure-storage://bucket/path?&AZURE_ACCOUNT_NAME=foo&AZURE_ACCOUNT_KEY=Zm9vCg==&AZURE_ENVIRONMENT=random-env' +---- +pq: failed to construct External Connection details: failed to create azure external connection: azure environment: autorest/azure: There is no cloud environment matching the name "RANDOM-ENV" + +inspect-system-table +---- +foo-azure STORAGE {"provider": "azure_storage", "simpleUri": {"uri": "azure-storage://bucket/path?AZURE_ACCOUNT_NAME=foo&AZURE_ACCOUNT_KEY=Zm9vCg==&AZURE_ENVIRONMENT=AzureUSGovernmentCloud"}} + +exec-sql +DROP EXTERNAL CONNECTION "foo-azure"; +---- + +enable-check-external-storage +---- + +subtest end diff --git a/pkg/ccl/cloudccl/externalconn/testdata/multi-tenant/create_drop_external_connection b/pkg/ccl/cloudccl/externalconn/testdata/multi-tenant/create_drop_external_connection index 7141e55466ab..ef12be06ad06 100644 --- a/pkg/ccl/cloudccl/externalconn/testdata/multi-tenant/create_drop_external_connection +++ b/pkg/ccl/cloudccl/externalconn/testdata/multi-tenant/create_drop_external_connection @@ -261,3 +261,41 @@ DROP EXTERNAL CONNECTION "foo-userfile"; ---- subtest end + +subtest basic-azure + +disable-check-external-storage +---- + +exec-sql +CREATE EXTERNAL CONNECTION "foo-azure" AS 'azure-storage://bucket/path?AZURE_ACCOUNT_NAME=foo&AZURE_ACCOUNT_KEY=Zm9vCg==&AZURE_ENVIRONMENT=AzureUSGovernmentCloud' +---- + +# Reject invalid azure external connections. +exec-sql +CREATE EXTERNAL CONNECTION "invalid-param-azure" AS 'azure-storage://bucket/path?INVALIDPARAM=baz' +---- +pq: failed to construct External Connection details: failed to create azure external connection: unknown azure query parameters: INVALIDPARAM + +exec-sql +CREATE EXTERNAL CONNECTION "foo-azure" AS 'azure-storage://bucket/path?&AZURE_ACCOUNT_KEY=Zm9vCg==&AZURE_ENVIRONMENT=AzureUSGovernmentCloud' +---- +pq: failed to construct External Connection details: failed to create azure external connection: azure uri missing "AZURE_ACCOUNT_NAME" parameter + +exec-sql +CREATE EXTERNAL CONNECTION "foo-azure" AS 'azure-storage://bucket/path?&AZURE_ACCOUNT_NAME=foo&AZURE_ACCOUNT_KEY=Zm9vCg==&AZURE_ENVIRONMENT=random-env' +---- +pq: failed to construct External Connection details: failed to create azure external connection: azure environment: autorest/azure: There is no cloud environment matching the name "RANDOM-ENV" + +inspect-system-table +---- +foo-azure STORAGE {"provider": "azure_storage", "simpleUri": {"uri": "azure-storage://bucket/path?AZURE_ACCOUNT_NAME=foo&AZURE_ACCOUNT_KEY=Zm9vCg==&AZURE_ENVIRONMENT=AzureUSGovernmentCloud"}} + +exec-sql +DROP EXTERNAL CONNECTION "foo-azure"; +---- + +enable-check-external-storage +---- + +subtest end diff --git a/pkg/ccl/cloudccl/gcp/gcp_connection_test.go b/pkg/ccl/cloudccl/gcp/gcp_connection_test.go index 3f3821d8257f..3be3db05e299 100644 --- a/pkg/ccl/cloudccl/gcp/gcp_connection_test.go +++ b/pkg/ccl/cloudccl/gcp/gcp_connection_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 The Cockroach Authors. +// Copyright 2022 The Cockroach Authors. // // Licensed as a CockroachDB Enterprise file under the Cockroach Community // License (the "License"); you may not use this file except in compliance with diff --git a/pkg/cloud/azure/BUILD.bazel b/pkg/cloud/azure/BUILD.bazel index 6fe2ba864068..c0991eec6e02 100644 --- a/pkg/cloud/azure/BUILD.bazel +++ b/pkg/cloud/azure/BUILD.bazel @@ -3,13 +3,20 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "azure", - srcs = ["azure_storage.go"], + srcs = [ + "azure_connection.go", + "azure_storage.go", + ], importpath = "github.com/cockroachdb/cockroach/pkg/cloud/azure", visibility = ["//visibility:public"], deps = [ "//pkg/base", "//pkg/cloud", "//pkg/cloud/cloudpb", + "//pkg/cloud/externalconn", + "//pkg/cloud/externalconn/connectionpb", + "//pkg/cloud/externalconn/utils", + "//pkg/security/username", "//pkg/server/telemetry", "//pkg/settings/cluster", "//pkg/util/contextutil", diff --git a/pkg/cloud/azure/azure_connection.go b/pkg/cloud/azure/azure_connection.go new file mode 100644 index 000000000000..1a1b9a871b3a --- /dev/null +++ b/pkg/cloud/azure/azure_connection.go @@ -0,0 +1,47 @@ +// Copyright 2022 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.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/APL.txt. + +package azure + +import ( + "context" + "net/url" + + "github.com/cockroachdb/cockroach/pkg/cloud/externalconn" + "github.com/cockroachdb/cockroach/pkg/cloud/externalconn/connectionpb" + "github.com/cockroachdb/cockroach/pkg/cloud/externalconn/utils" + "github.com/cockroachdb/cockroach/pkg/security/username" + "github.com/cockroachdb/errors" +) + +func parseAndValidateAzureConnectionURI( + ctx context.Context, execCfg interface{}, user username.SQLUsername, uri *url.URL, +) (externalconn.ExternalConnection, error) { + if err := utils.CheckExternalStorageConnection(ctx, execCfg, user, uri.String()); err != nil { + return nil, errors.Wrap(err, "failed to create azure external connection") + } + + connDetails := connectionpb.ConnectionDetails{ + Provider: connectionpb.ConnectionProvider_azure_storage, + Details: &connectionpb.ConnectionDetails_SimpleURI{ + SimpleURI: &connectionpb.SimpleURI{ + URI: uri.String(), + }, + }, + } + return externalconn.NewExternalConnection(connDetails), nil +} + +func init() { + externalconn.RegisterConnectionDetailsFromURIFactory( + externalConnectionScheme, + parseAndValidateAzureConnectionURI, + ) +} diff --git a/pkg/cloud/azure/azure_storage.go b/pkg/cloud/azure/azure_storage.go index 3fd9ad1b7552..9322bd316d2a 100644 --- a/pkg/cloud/azure/azure_storage.go +++ b/pkg/cloud/azure/azure_storage.go @@ -39,20 +39,31 @@ const ( AzureAccountKeyParam = "AZURE_ACCOUNT_KEY" // AzureEnvironmentKeyParam is the query parameter for the environment name in an azure URI. AzureEnvironmentKeyParam = "AZURE_ENVIRONMENT" + + scheme = "azure" + externalConnectionScheme = "azure-storage" ) func parseAzureURL( _ cloud.ExternalStorageURIContext, uri *url.URL, ) (cloudpb.ExternalStorage, error) { + azureURL := cloud.ConsumeURL{URL: uri} conf := cloudpb.ExternalStorage{} conf.Provider = cloudpb.ExternalStorageProvider_azure conf.AzureConfig = &cloudpb.ExternalStorage_Azure{ Container: uri.Host, Prefix: uri.Path, - AccountName: uri.Query().Get(AzureAccountNameParam), - AccountKey: uri.Query().Get(AzureAccountKeyParam), - Environment: uri.Query().Get(AzureEnvironmentKeyParam), + AccountName: azureURL.ConsumeParam(AzureAccountNameParam), + AccountKey: azureURL.ConsumeParam(AzureAccountKeyParam), + Environment: azureURL.ConsumeParam(AzureEnvironmentKeyParam), + } + + // Validate that all the passed in parameters are supported. + if unknownParams := azureURL.RemainingQueryParams(); len(unknownParams) > 0 { + return cloudpb.ExternalStorage{}, errors.Errorf( + `unknown azure query parameters: %s`, strings.Join(unknownParams, ", ")) } + if conf.AzureConfig.AccountName == "" { return conf, errors.Errorf("azure uri missing %q parameter", AzureAccountNameParam) } @@ -256,5 +267,5 @@ func (s *azureStorage) Close() error { func init() { cloud.RegisterExternalStorageProvider(cloudpb.ExternalStorageProvider_azure, - parseAzureURL, makeAzureStorage, cloud.RedactedParams(AzureAccountKeyParam), "azure") + parseAzureURL, makeAzureStorage, cloud.RedactedParams(AzureAccountKeyParam), scheme, externalConnectionScheme) } diff --git a/pkg/cloud/azure/azure_storage_test.go b/pkg/cloud/azure/azure_storage_test.go index 7e6b99b51fd7..11182c729a6d 100644 --- a/pkg/cloud/azure/azure_storage_test.go +++ b/pkg/cloud/azure/azure_storage_test.go @@ -102,7 +102,7 @@ func TestParseAzureURL(t *testing.T) { }) t.Run("Can Override AZURE_ENVIRONMENT", func(t *testing.T) { - u, err := url.Parse("azure://container/path?AZURE_ACCOUNT_NAME=account&AZURE_ACCOUNT_KEY=key&AZURE_ENVIRONMENT=AzureUSGovernmentCloud") + u, err := url.Parse("azure-storage://container/path?AZURE_ACCOUNT_NAME=account&AZURE_ACCOUNT_KEY=key&AZURE_ENVIRONMENT=AzureUSGovernmentCloud") require.NoError(t, err) sut, err := parseAzureURL(cloud.ExternalStorageURIContext{}, u) diff --git a/pkg/cloud/externalconn/connectionpb/connection.go b/pkg/cloud/externalconn/connectionpb/connection.go index b680ec56cf31..cbbd3eca3f6a 100644 --- a/pkg/cloud/externalconn/connectionpb/connection.go +++ b/pkg/cloud/externalconn/connectionpb/connection.go @@ -15,7 +15,8 @@ import "github.com/cockroachdb/errors" // Type returns the ConnectionType of the receiver. func (d *ConnectionDetails) Type() ConnectionType { switch d.Provider { - case ConnectionProvider_nodelocal, ConnectionProvider_s3, ConnectionProvider_userfile, ConnectionProvider_gs: + case ConnectionProvider_nodelocal, ConnectionProvider_s3, ConnectionProvider_userfile, + ConnectionProvider_gs, ConnectionProvider_azure_storage: return TypeStorage case ConnectionProvider_gcp_kms: return TypeKMS diff --git a/pkg/cloud/externalconn/connectionpb/connection.proto b/pkg/cloud/externalconn/connectionpb/connection.proto index 23c7072738f7..b30819a398b2 100644 --- a/pkg/cloud/externalconn/connectionpb/connection.proto +++ b/pkg/cloud/externalconn/connectionpb/connection.proto @@ -22,6 +22,7 @@ enum ConnectionProvider { s3 = 4; userfile = 5; gs = 6; + azure_storage = 7; // KMS providers. gcp_kms = 2; diff --git a/pkg/cloud/externalconn/providers/BUILD.bazel b/pkg/cloud/externalconn/providers/BUILD.bazel index 2929e0b9e142..96b1db78808b 100644 --- a/pkg/cloud/externalconn/providers/BUILD.bazel +++ b/pkg/cloud/externalconn/providers/BUILD.bazel @@ -8,6 +8,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/cloud/amazon", + "//pkg/cloud/azure", "//pkg/cloud/gcp", "//pkg/cloud/nodelocal", "//pkg/cloud/userfile", diff --git a/pkg/cloud/externalconn/providers/registry.go b/pkg/cloud/externalconn/providers/registry.go index bdc03267c846..13617a509c4c 100644 --- a/pkg/cloud/externalconn/providers/registry.go +++ b/pkg/cloud/externalconn/providers/registry.go @@ -18,6 +18,7 @@ package providers import ( // import all the cloud provider packages to register them. _ "github.com/cockroachdb/cockroach/pkg/cloud/amazon" + _ "github.com/cockroachdb/cockroach/pkg/cloud/azure" _ "github.com/cockroachdb/cockroach/pkg/cloud/gcp" _ "github.com/cockroachdb/cockroach/pkg/cloud/nodelocal" _ "github.com/cockroachdb/cockroach/pkg/cloud/userfile" diff --git a/pkg/cmd/roachtest/tests/django.go b/pkg/cmd/roachtest/tests/django.go index 1162c4f38280..1d0b31abb731 100644 --- a/pkg/cmd/roachtest/tests/django.go +++ b/pkg/cmd/roachtest/tests/django.go @@ -27,8 +27,8 @@ import ( var djangoReleaseTagRegex = regexp.MustCompile(`^(?P\d+)\.(?P\d+)(\.(?P\d+))?$`) var djangoCockroachDBReleaseTagRegex = regexp.MustCompile(`^(?P\d+)\.(?P\d+)$`) -var djangoSupportedTag = "cockroach-4.0.x" -var djangoCockroachDBSupportedTag = "4.0.*" +var djangoSupportedTag = "cockroach-4.1.x" +var djangoCockroachDBSupportedTag = "4.1" func registerDjango(r registry.Registry) { runDjango := func( diff --git a/pkg/util/tracing/span.go b/pkg/util/tracing/span.go index 56ae26ff90f9..183bbd66bc8a 100644 --- a/pkg/util/tracing/span.go +++ b/pkg/util/tracing/span.go @@ -674,7 +674,7 @@ func (sp *Span) reset( recording: recordingState{ logs: makeSizeLimitedBuffer(maxLogBytesPerSpan, nil /* scratch */), structured: makeSizeLimitedBuffer(maxStructuredBytesPerSpan, h.structuredEventsAlloc[:]), - childrenMetadata: make(map[string]tracingpb.OperationMetadata), + childrenMetadata: h.childrenMetadataAlloc, }, tags: h.tagsAlloc[:0], } diff --git a/pkg/util/tracing/tracer.go b/pkg/util/tracing/tracer.go index f174a2bf263a..93e5d771bef4 100644 --- a/pkg/util/tracing/tracer.go +++ b/pkg/util/tracing/tracer.go @@ -599,6 +599,7 @@ func NewTracer() *Tracer { sp: sp, } sp.i.crdb = c + h.childrenMetadataAlloc = make(map[string]tracingpb.OperationMetadata) return h }, } @@ -944,6 +945,7 @@ type spanAllocHelper struct { tagsAlloc [3]attribute.KeyValue childrenAlloc [4]childRef structuredEventsAlloc [3]interface{} + childrenMetadataAlloc map[string]tracingpb.OperationMetadata } // newSpan allocates a span using the Tracer's sync.Pool. A span that was @@ -1015,6 +1017,9 @@ func (t *Tracer) releaseSpanToPool(sp *Span) { h.tagsAlloc = [3]attribute.KeyValue{} h.childrenAlloc = [4]childRef{} h.structuredEventsAlloc = [3]interface{}{} + for op := range h.childrenMetadataAlloc { + delete(h.childrenMetadataAlloc, op) + } release := true if fn := t.testing.ReleaseSpanToPool; fn != nil {