Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: initialize virtual table descriptors concurrently; skip some vtable validations #142012

Merged
merged 3 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/sql/catalog/tabledesc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ go_library(
"//pkg/sql/types",
"//pkg/sql/vecindex/vecpb",
"//pkg/util",
"//pkg/util/buildutil",
"//pkg/util/errorutil/unimplemented",
"//pkg/util/hlc",
"//pkg/util/interval",
Expand Down
9 changes: 9 additions & 0 deletions pkg/sql/catalog/tabledesc/structured.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/cockroach/pkg/sql/sqlerrors"
"github.com/cockroachdb/cockroach/pkg/sql/types"
"github.com/cockroachdb/cockroach/pkg/util/buildutil"
"github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented"
"github.com/cockroachdb/cockroach/pkg/util/hlc"
"github.com/cockroachdb/cockroach/pkg/util/intsets"
Expand Down Expand Up @@ -636,6 +637,14 @@ func (desc *Mutable) AllocateIDs(ctx context.Context, version clusterversion.Clu
return err
}

// The virtual table descriptors are entirely under our control. Since
// validating is expensive, skip it for virtual tables if this code is running
// in a test environment. This step was found to be a bottleneck in TestServer
// startup.
if desc.IsVirtualTable() && buildutil.CrdbTestBuild {
return nil
}

// This is sort of ugly. If the descriptor does not have an ID, we hack one in
// to pass the table ID check. We use a non-reserved ID, reserved ones being set
// before AllocateIDs.
Expand Down
38 changes: 23 additions & 15 deletions pkg/sql/virtual_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
"github.com/cockroachdb/cockroach/pkg/sql/sqlerrors"
"github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry"
"github.com/cockroachdb/cockroach/pkg/util/ctxgroup"
"github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented"
"github.com/cockroachdb/cockroach/pkg/util/hlc"
"github.com/cockroachdb/cockroach/pkg/util/iterutil"
"github.com/cockroachdb/cockroach/pkg/util/stop"
"github.com/cockroachdb/cockroach/pkg/util/syncutil"
"github.com/cockroachdb/errors"
"github.com/cockroachdb/redact"
)
Expand Down Expand Up @@ -444,9 +446,6 @@ type VirtualSchemaHolder struct {
orderedNames []string

catalogCache nstree.MutableCatalog
// Needed for backward-compat on crdb_internal.ranges{_no_leases}.
// Remove in v23.2.
st *cluster.Settings
}

var _ VirtualTabler = (*VirtualSchemaHolder)(nil)
Expand Down Expand Up @@ -930,10 +929,6 @@ func NewVirtualSchemaHolder(
schemasByID: make(map[descpb.ID]*virtualSchemaEntry, len(virtualSchemas)),
orderedNames: make([]string, len(virtualSchemas)),
defsByID: make(map[descpb.ID]*virtualDefEntry, math.MaxUint32-catconstants.MinVirtualID),

// Needed for backward-compat on crdb_internal.ranges{_no_leases}.
// Remove in v23.2.
st: st,
}

order := 0
Expand Down Expand Up @@ -985,16 +980,29 @@ func NewVirtualSchemaHolder(
return tableDesc, entry, nil
}

// Initialize virtual tables concurrently. This happens all at once during
// server startup, which is a bottleneck for startup time, especially in
// the TestServer used by unit tests. Adding concurrency here speeds up
// TestServer startup by about 7% in SharedTenant mode.
g := ctxgroup.WithContext(ctx)
var mu syncutil.Mutex
for id, def := range schema.tableDefs {
tableDesc, entry, err := doTheWork(id, def, false /* bumpVersion */)
if err != nil {
return nil, err
}
defs[tableDesc.Name] = entry
vs.defsByID[tableDesc.ID] = entry
orderedDefNames = append(orderedDefNames, tableDesc.Name)
g.GoCtx(func(ctx context.Context) error {
tableDesc, entry, err := doTheWork(id, def, false /* bumpVersion */)
if err != nil {
return err
}
mu.Lock()
defer mu.Unlock()
defs[tableDesc.Name] = entry
vs.defsByID[tableDesc.ID] = entry
orderedDefNames = append(orderedDefNames, tableDesc.Name)
return nil
})
}
if err := g.Wait(); err != nil {
return nil, err
}

sort.Strings(orderedDefNames)

vse := &virtualSchemaEntry{
Expand Down
10 changes: 10 additions & 0 deletions pkg/util/ctxgroup/ctxgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,16 @@ func WithContext(ctx context.Context) Group {
}
}

// SetLimit limits the number of active goroutines in this group to at most n. A
// negative value indicates no limit. A limit of zero will prevent any new
// goroutines from being added. Any subsequent call to the Go method will block
// until it can add an active goroutine without exceeding the configured limit.
// The limit must not be modified while any goroutines in the group are active.
// This delegates to errgroup.Group.SetLimit.
func (g Group) SetLimit(n int) {
g.wrapped.SetLimit(n)
}

// Go calls the given function in a new goroutine.
func (g Group) Go(f func() error) {
g.wrapped.Go(f)
Expand Down