Skip to content

Commit f770100

Browse files
craig[bot]fqazispilchenRaduBerinde
committed
156487: catalog: add support reading metadata for leased descriptors and add logic test config r=fqazi a=fqazi We recently added an option for using leased descriptors for pg_catalog / crdb_internal tables. While this option can fetch descriptor data, we presently have no way of reading metadata for leased descriptors, such as zone configs and comments. This patch introduces a new option to support reading metadata along with leased descriptors when using the GetAll.* APIs. This patch also adds a new logic test config for testing out using leased descriptors for pg_catalog / crdb_internal logic tests. Fixes: #156404 Release note: None 156688: bulkutil: add utiliy to manage and reuse ExternalStorage instances r=spilchen a=spilchen Adds a new ExternalStorageMux utility that manages and caches cloud.ExternalStorage instances keyed by their base URI (e.g. nodelocal://1/, s3://bucket/). The mux provides a lightweight layer that allows the processors for distribute merge to reuse existing storage connections instead of creating a new ExternalStorage for every file operation. Each ExternalStorageMux maintains a per-processor cache of open storage handles. If a request is made for a URI with a previously seen base prefix, the mux returns the cached handle; otherwise, it lazily creates and tracks a new one. The ExternalStorageMux struct is not thread safe. It doesn't use mutex to control state. It's expected that the consumer won't be using this across multiple goroutines. Closes #156587 Epic: CRDB-48845 Release notes: none 156747: go.mod: bump Pebble to 951fae603dfe r=RaduBerinde a=RaduBerinde Update code to use the new metrics. EnvStats now includes the blob file count (see #156746). Changes: * [`951fae60`](cockroachdb/pebble@951fae60) metrics: redesign disk usage metrics * [`9e6937d2`](cockroachdb/pebble@9e6937d2) db: add validation for WALFailover options Release note: none. Epic: none. Co-authored-by: Faizan Qazi <[email protected]> Co-authored-by: Matt Spilchen <[email protected]> Co-authored-by: Radu Berinde <[email protected]>
4 parents fa5512c + fc7e08b + 15eb433 + 71d7360 commit f770100

36 files changed

+847
-75
lines changed

DEPS.bzl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,10 +1834,10 @@ def go_deps():
18341834
patches = [
18351835
"@com_github_cockroachdb_cockroach//build/patches:com_github_cockroachdb_pebble.patch",
18361836
],
1837-
sha256 = "9b2a84419f999a1a0b37fccb761dca75dd2cd2ec4fd4875dbe900c9d14e12b79",
1838-
strip_prefix = "github.com/cockroachdb/[email protected]20251029205532-e8d7ecb38559",
1837+
sha256 = "0ffbfa9854e45c7fa775c37af3e80f439c078d28ffa348a6a2bdb9af4e10ad37",
1838+
strip_prefix = "github.com/cockroachdb/[email protected]20251102183433-951fae603dfe",
18391839
urls = [
1840-
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/pebble/com_github_cockroachdb_pebble-v0.0.0-20251029205532-e8d7ecb38559.zip",
1840+
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/pebble/com_github_cockroachdb_pebble-v0.0.0-20251102183433-951fae603dfe.zip",
18411841
],
18421842
)
18431843
go_repository(

build/bazelutil/distdir_files.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ DISTDIR_FILES = {
352352
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/gostdlib/com_github_cockroachdb_gostdlib-v1.19.0.zip": "c4d516bcfe8c07b6fc09b8a9a07a95065b36c2855627cb3514e40c98f872b69e",
353353
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/logtags/com_github_cockroachdb_logtags-v0.0.0-20241215232642-bb51bb14a506.zip": "920068af09e3846d9ebb4e4a7787ff1dd10f3989c5f940ad861b0f6a9f824f6e",
354354
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/metamorphic/com_github_cockroachdb_metamorphic-v0.0.0-20231108215700-4ba948b56895.zip": "28c8cf42192951b69378cf537be5a9a43f2aeb35542908cc4fe5f689505853ea",
355-
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/pebble/com_github_cockroachdb_pebble-v0.0.0-20251029205532-e8d7ecb38559.zip": "9b2a84419f999a1a0b37fccb761dca75dd2cd2ec4fd4875dbe900c9d14e12b79",
355+
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/pebble/com_github_cockroachdb_pebble-v0.0.0-20251102183433-951fae603dfe.zip": "0ffbfa9854e45c7fa775c37af3e80f439c078d28ffa348a6a2bdb9af4e10ad37",
356356
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/redact/com_github_cockroachdb_redact-v1.1.6.zip": "018eccb5fb9ca52d43ec9eaf213539d01c1f2b94e0e822406ebfb2e9321ef6cf",
357357
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/returncheck/com_github_cockroachdb_returncheck-v0.0.0-20200612231554-92cdbca611dd.zip": "ce92ba4352deec995b1f2eecf16eba7f5d51f5aa245a1c362dfe24c83d31f82b",
358358
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/stress/com_github_cockroachdb_stress-v0.0.0-20220803192808-1806698b1b7b.zip": "3fda531795c600daf25532a4f98be2a1335cd1e5e182c72789bca79f5f69fcc1",

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ require (
137137
github.com/cockroachdb/errors v1.12.1-0.20251010171200-64801262cd6f
138138
github.com/cockroachdb/gostdlib v1.19.0
139139
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506
140-
github.com/cockroachdb/pebble v0.0.0-20251029205532-e8d7ecb38559
140+
github.com/cockroachdb/pebble v0.0.0-20251102183433-951fae603dfe
141141
github.com/cockroachdb/redact v1.1.6
142142
github.com/cockroachdb/returncheck v0.0.0-20200612231554-92cdbca611dd
143143
github.com/cockroachdb/tokenbucket v0.0.0-20250429170803-42689b6311bb

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,8 +572,8 @@ github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 h1:ASDL+UJcILM
572572
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506/go.mod h1:Mw7HqKr2kdtu6aYGn3tPmAftiP3QPX63LdK/zcariIo=
573573
github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895 h1:XANOgPYtvELQ/h4IrmPAohXqe2pWA8Bwhejr3VQoZsA=
574574
github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895/go.mod h1:aPd7gM9ov9M8v32Yy5NJrDyOcD8z642dqs+F0CeNXfA=
575-
github.com/cockroachdb/pebble v0.0.0-20251029205532-e8d7ecb38559 h1:ov6vATG9hZ7bwMYnrrmRrSRvaqAzCGlrNMjOqc8ivzA=
576-
github.com/cockroachdb/pebble v0.0.0-20251029205532-e8d7ecb38559/go.mod h1:GflN9NRwberlF+gFRJd6r6jrUYdWR/QD+gtgtH0LRK8=
575+
github.com/cockroachdb/pebble v0.0.0-20251102183433-951fae603dfe h1:HUrVJv2RUIT2L9Gl4STK1rS0AvlubDvHgreuc3f+Boc=
576+
github.com/cockroachdb/pebble v0.0.0-20251102183433-951fae603dfe/go.mod h1:GflN9NRwberlF+gFRJd6r6jrUYdWR/QD+gtgtH0LRK8=
577577
github.com/cockroachdb/redact v1.1.6 h1:zXJBwDZ84xJNlHl1rMyCojqyIxv+7YUpQiJLQ7n4314=
578578
github.com/cockroachdb/redact v1.1.6/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
579579
github.com/cockroachdb/returncheck v0.0.0-20200612231554-92cdbca611dd h1:KFOt5I9nEKZgCnOSmy8r4Oykh8BYQO8bFOTgHDS8YZA=

pkg/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ ALL_TESTS = [
396396
"//pkg/sql/appstatspb:appstatspb_test",
397397
"//pkg/sql/auditlogging:auditlogging_test",
398398
"//pkg/sql/backfill:backfill_test",
399+
"//pkg/sql/bulkutil:bulkutil_test",
399400
"//pkg/sql/cacheutil:cacheutil_test",
400401
"//pkg/sql/catalog/bootstrap:bootstrap_test",
401402
"//pkg/sql/catalog/catalogkeys:catalogkeys_test",
@@ -521,6 +522,7 @@ ALL_TESTS = [
521522
"//pkg/sql/logictest/tests/fakedist-disk:fakedist-disk_test",
522523
"//pkg/sql/logictest/tests/fakedist-vec-off:fakedist-vec-off_test",
523524
"//pkg/sql/logictest/tests/fakedist:fakedist_test",
525+
"//pkg/sql/logictest/tests/local-leased-descriptors:local-leased-descriptors_test",
524526
"//pkg/sql/logictest/tests/local-legacy-schema-changer:local-legacy-schema-changer_test",
525527
"//pkg/sql/logictest/tests/local-mixed-25.2:local-mixed-25_2_test",
526528
"//pkg/sql/logictest/tests/local-mixed-25.3:local-mixed-25_3_test",
@@ -1878,6 +1880,8 @@ GO_TARGETS = [
18781880
"//pkg/sql/auditlogging:auditlogging_test",
18791881
"//pkg/sql/backfill:backfill",
18801882
"//pkg/sql/backfill:backfill_test",
1883+
"//pkg/sql/bulkutil:bulkutil",
1884+
"//pkg/sql/bulkutil:bulkutil_test",
18811885
"//pkg/sql/cacheutil:cacheutil",
18821886
"//pkg/sql/cacheutil:cacheutil_test",
18831887
"//pkg/sql/catalog/bootstrap:bootstrap",
@@ -2091,6 +2095,7 @@ GO_TARGETS = [
20912095
"//pkg/sql/logictest/tests/fakedist-disk:fakedist-disk_test",
20922096
"//pkg/sql/logictest/tests/fakedist-vec-off:fakedist-vec-off_test",
20932097
"//pkg/sql/logictest/tests/fakedist:fakedist_test",
2098+
"//pkg/sql/logictest/tests/local-leased-descriptors:local-leased-descriptors_test",
20942099
"//pkg/sql/logictest/tests/local-legacy-schema-changer:local-legacy-schema-changer_test",
20952100
"//pkg/sql/logictest/tests/local-mixed-25.2:local-mixed-25_2_test",
20962101
"//pkg/sql/logictest/tests/local-mixed-25.3:local-mixed-25_3_test",

pkg/kv/kvserver/metrics.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,8 +4331,9 @@ func (sm *StoreMetrics) updateEngineMetrics(m storage.Metrics) {
43314331
sm.IngestCount.Update(int64(m.Ingest.Count))
43324332
sm.ValueSeparationBytesReferenced.Update(int64(m.BlobFiles.ReferencedValueSize))
43334333
sm.ValueSeparationBytesUnreferenced.Update(int64(m.BlobFiles.ValueSize - m.BlobFiles.ReferencedValueSize))
4334-
sm.ValueSeparationBlobFileCount.Update(int64(m.BlobFiles.Live.All.Count))
4335-
sm.ValueSeparationBlobFileSize.Update(int64(m.BlobFiles.Live.All.Bytes))
4334+
liveBlobFiles := m.BlobFiles.Live.Total()
4335+
sm.ValueSeparationBlobFileCount.Update(int64(liveBlobFiles.Count))
4336+
sm.ValueSeparationBlobFileSize.Update(int64(liveBlobFiles.Bytes))
43364337
sm.ValueSeparationValueRetrievalCount.Update(int64(m.Iterator.ValueRetrievalCount))
43374338
// NB: `UpdateIfHigher` is used here since there is a race in pebble where
43384339
// sometimes the WAL is rotated but metrics are retrieved prior to the update
@@ -4350,7 +4351,7 @@ func (sm *StoreMetrics) updateEngineMetrics(m storage.Metrics) {
43504351
sm.BatchCommitL0StallDuration.Update(int64(m.BatchCommitStats.L0ReadAmpWriteStallDuration))
43514352
sm.BatchCommitWALRotWaitDuration.Update(int64(m.BatchCommitStats.WALRotationDuration))
43524353
sm.BatchCommitCommitWaitDuration.Update(int64(m.BatchCommitStats.CommitWaitDuration))
4353-
sm.SSTableZombieBytes.Update(int64(m.Table.Zombie.All.Bytes))
4354+
sm.SSTableZombieBytes.Update(int64(m.Table.Physical.Zombie.Total().Bytes))
43544355
remoteTables := m.RemoteTablesTotal()
43554356
sm.SSTableRemoteBytes.Update(int64(remoteTables.Bytes))
43564357
sm.SSTableRemoteCount.Update(int64(remoteTables.Count))

pkg/sql/bulkutil/BUILD.bazel

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
2+
3+
go_library(
4+
name = "bulkutil",
5+
srcs = ["external_storage_mux.go"],
6+
importpath = "github.com/cockroachdb/cockroach/pkg/sql/bulkutil",
7+
visibility = ["//visibility:public"],
8+
deps = [
9+
"//pkg/ccl/storageccl",
10+
"//pkg/cloud",
11+
"//pkg/security/username",
12+
"@com_github_cockroachdb_errors//:errors",
13+
],
14+
)
15+
16+
go_test(
17+
name = "bulkutil_test",
18+
srcs = [
19+
"external_storage_mux_test.go",
20+
"main_test.go",
21+
],
22+
embed = [":bulkutil"],
23+
deps = [
24+
"//pkg/cloud",
25+
"//pkg/security/username",
26+
"//pkg/util/leaktest",
27+
"//pkg/util/randutil",
28+
"@com_github_stretchr_testify//require",
29+
],
30+
)
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright 2025 The Cockroach Authors.
2+
//
3+
// Use of this software is governed by the CockroachDB Software License
4+
// included in the /LICENSE file.
5+
6+
package bulkutil
7+
8+
import (
9+
"context"
10+
"net/url"
11+
12+
"github.com/cockroachdb/cockroach/pkg/ccl/storageccl"
13+
"github.com/cockroachdb/cockroach/pkg/cloud"
14+
"github.com/cockroachdb/cockroach/pkg/security/username"
15+
"github.com/cockroachdb/errors"
16+
)
17+
18+
// ExternalStorageMux is a utility for managing multiple cloud storage instances.
19+
// The main motivator for this is each node has its own nodelocal://<node-id>
20+
// instance.
21+
type ExternalStorageMux struct {
22+
factory cloud.ExternalStorageFromURIFactory
23+
storeInstances map[string]cloud.ExternalStorage
24+
user username.SQLUsername
25+
}
26+
27+
// NewExternalStorageMux creates a new ExternalStorageMux that caches external storage
28+
// instances. This is particularly useful for nodelocal storage where each node
29+
// has its own storage instance (nodelocal://1/, nodelocal://2/, etc.).
30+
func NewExternalStorageMux(
31+
factory cloud.ExternalStorageFromURIFactory, user username.SQLUsername,
32+
) *ExternalStorageMux {
33+
return &ExternalStorageMux{
34+
factory: factory,
35+
storeInstances: make(map[string]cloud.ExternalStorage),
36+
user: user,
37+
}
38+
}
39+
40+
// Close closes all cached storage instances.
41+
func (c *ExternalStorageMux) Close() error {
42+
var err error
43+
for _, store := range c.storeInstances {
44+
err = errors.CombineErrors(err, store.Close())
45+
}
46+
return err
47+
}
48+
49+
// StoreFile splits a URI into its storage prefix and file path, caching the
50+
// storage instance for reuse. For example, "nodelocal://1/import/123/file.sst"
51+
// is split into storage "nodelocal://1" and path "/import/123/file.sst".
52+
func (c *ExternalStorageMux) StoreFile(
53+
ctx context.Context, uri string,
54+
) (storageccl.StoreFile, error) {
55+
prefix, filepath, err := c.splitURI(uri)
56+
if err != nil {
57+
return storageccl.StoreFile{}, err
58+
}
59+
prefixKey := prefix.String()
60+
store, ok := c.storeInstances[prefixKey]
61+
if !ok {
62+
storage, err := c.factory(ctx, prefix.String(), c.user)
63+
if err != nil {
64+
return storageccl.StoreFile{}, err
65+
}
66+
c.storeInstances[prefixKey] = storage
67+
store = storage
68+
}
69+
return storageccl.StoreFile{
70+
Store: store,
71+
FilePath: filepath,
72+
}, nil
73+
}
74+
75+
// splitURI splits a URI into its prefix (scheme + host) and path components.
76+
// For example, "nodelocal://1/import/123/file.sst" becomes:
77+
// - prefix: url.URL{Scheme: "nodelocal", Host: "1"}
78+
// - path: "/import/123/file.sst"
79+
func (c *ExternalStorageMux) splitURI(uri string) (url.URL, string, error) {
80+
parsed, err := url.Parse(uri)
81+
if err != nil {
82+
return url.URL{}, "", errors.Wrap(err, "failed to parse external storage uri")
83+
}
84+
85+
path := parsed.Path
86+
parsed.Path = ""
87+
88+
return *parsed, path, nil
89+
}

0 commit comments

Comments
 (0)