diff --git a/pkg/sql/crdb_internal.go b/pkg/sql/crdb_internal.go index 6b4eee7dce88..f9070d53f631 100644 --- a/pkg/sql/crdb_internal.go +++ b/pkg/sql/crdb_internal.go @@ -5814,9 +5814,9 @@ var crdbInternalClusterLocksTable = virtualSchemaTable{ CREATE TABLE crdb_internal.cluster_locks ( range_id INT NOT NULL, table_id INT NOT NULL, - database_name STRING, + database_name STRING NOT NULL, schema_name STRING, - table_name STRING, + table_name STRING NOT NULL, index_name STRING, lock_key BYTES NOT NULL, lock_key_pretty STRING NOT NULL, @@ -5825,11 +5825,57 @@ CREATE TABLE crdb_internal.cluster_locks ( lock_strength STRING, durability STRING, granted BOOL, - contended BOOL, - duration INTERVAL + contended BOOL NOT NULL, + duration INTERVAL, + INDEX(table_id), + INDEX(database_name), + INDEX(table_name), + INDEX(contended) );`, - indexes: nil, - generator: func(ctx context.Context, p *planner, db catalog.DatabaseDescriptor, stopper *stop.Stopper) (virtualTableGenerator, cleanupFunc, error) { + indexes: []virtualIndex{ + { + populate: genPopulateClusterLocksWithIndex("table_id" /* idxColumnName */, func(filters *clusterLocksFilters, idxConstraint tree.Datum) { + if tableID, ok := tree.AsDInt(idxConstraint); ok { + filters.tableID = (*int64)(&tableID) + } + }), + }, + { + populate: genPopulateClusterLocksWithIndex("database_name" /* idxColumnName */, func(filters *clusterLocksFilters, idxConstraint tree.Datum) { + if dbName, ok := tree.AsDString(idxConstraint); ok { + filters.databaseName = (*string)(&dbName) + } + }), + }, + { + populate: genPopulateClusterLocksWithIndex("table_name" /* idxColumnName */, func(filters *clusterLocksFilters, idxConstraint tree.Datum) { + if tableName, ok := tree.AsDString(idxConstraint); ok { + filters.tableName = (*string)(&tableName) + } + }), + }, + { + populate: genPopulateClusterLocksWithIndex("contended" /* idxColumnName */, func(filters *clusterLocksFilters, idxConstraint tree.Datum) { + if contended, ok := tree.AsDBool(idxConstraint); ok { + filters.contended = (*bool)(&contended) + } + }), + }, + }, + generator: genClusterLocksGenerator(clusterLocksFilters{}), +} + +type clusterLocksFilters struct { + tableID *int64 + databaseName *string + tableName *string + contended *bool +} + +func genClusterLocksGenerator( + filters clusterLocksFilters, +) func(ctx context.Context, p *planner, db catalog.DatabaseDescriptor, stopper *stop.Stopper) (virtualTableGenerator, cleanupFunc, error) { + return func(ctx context.Context, p *planner, _ catalog.DatabaseDescriptor, _ *stop.Stopper) (virtualTableGenerator, cleanupFunc, error) { // TODO(sarkesian): remove gate for 22.2 release if !p.ExecCfg().Settings.Version.IsActive(ctx, clusterversion.ClusterLocksVirtualTable) { return nil, nil, pgerror.New(pgcode.FeatureNotSupported, @@ -5879,6 +5925,15 @@ CREATE TABLE crdb_internal.cluster_locks ( } switch desc := desc.(type) { case catalog.TableDescriptor: + if filters.tableName != nil && *filters.tableName != desc.GetName() { + continue + } + if filters.tableID != nil && descpb.ID(*filters.tableID) != desc.GetID() { + continue + } + if filters.databaseName != nil && *filters.databaseName != dbNames[uint32(desc.GetParentID())] { + continue + } spansToQuery = append(spansToQuery, desc.TableSpan(p.execCfg.Codec)) } } @@ -5910,6 +5965,10 @@ CREATE TABLE crdb_internal.cluster_locks ( }, IncludeUncontended: true, } + if filters.contended != nil && *filters.contended { + queryLocksRequest.IncludeUncontended = false + } + b.AddRawRequest(queryLocksRequest) b.Header.MaxSpanRequestKeys = int64(rowinfra.ProductionKVBatchSize) @@ -6047,5 +6106,47 @@ CREATE TABLE crdb_internal.cluster_locks ( }, nil }, nil, nil - }, + } +} + +func genPopulateClusterLocksWithIndex( + idxColumnName string, setFilters func(filters *clusterLocksFilters, idxConstraint tree.Datum), +) func(context.Context, tree.Datum, *planner, catalog.DatabaseDescriptor, func(...tree.Datum) error) (bool, error) { + return func(ctx context.Context, idxConstraint tree.Datum, p *planner, db catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) (matched bool, err error) { + var filters clusterLocksFilters + setFilters(&filters, idxConstraint) + + if filters.tableID == nil && filters.databaseName == nil && filters.tableName == nil && filters.contended == nil { + return false, errors.AssertionFailedf("unexpected type %T for %s column in virtual table crdb_internal.cluster_locks", idxConstraint, idxColumnName) + } + + return populateClusterLocksWithFilter(ctx, p, db, addRow, filters) + } +} + +func populateClusterLocksWithFilter( + ctx context.Context, + p *planner, + db catalog.DatabaseDescriptor, + addRow func(...tree.Datum) error, + filters clusterLocksFilters, +) (matched bool, err error) { + var rowGenerator virtualTableGenerator + generator := genClusterLocksGenerator(filters) + rowGenerator, _, err = generator(ctx, p, db, nil /* stopper */) + if err != nil { + return false, err + } + var row tree.Datums + row, err = rowGenerator() + for row != nil && err == nil { + err = addRow(row...) + if err != nil { + break + } + matched = true + + row, err = rowGenerator() + } + return matched, err } diff --git a/pkg/sql/logictest/testdata/logic_test/cluster_locks b/pkg/sql/logictest/testdata/logic_test/cluster_locks index 74faccf186fa..759c7ecdc184 100644 --- a/pkg/sql/logictest/testdata/logic_test/cluster_locks +++ b/pkg/sql/logictest/testdata/logic_test/cluster_locks @@ -145,6 +145,35 @@ test public t ยท Exclusive Repli user root +query TTTTTTBB colnames,retry +SELECT database_name, schema_name, table_name, lock_key_pretty, lock_strength, durability, granted, contended FROM crdb_internal.cluster_locks WHERE database_name='test' +---- +database_name schema_name table_name lock_key_pretty lock_strength durability granted contended +test public t /Table/106/1/"b"/0 Exclusive Replicated true true +test public t /Table/106/1/"b"/0 None Replicated false true +test public t /Table/106/1/"c"/0 Exclusive Replicated true false + +query TTTTTTBB colnames,retry +SELECT database_name, schema_name, table_name, lock_key_pretty, lock_strength, durability, granted, contended FROM crdb_internal.cluster_locks WHERE table_id='t'::regclass::oid::int +---- +database_name schema_name table_name lock_key_pretty lock_strength durability granted contended +test public t /Table/106/1/"b"/0 Exclusive Replicated true true +test public t /Table/106/1/"b"/0 None Replicated false true +test public t /Table/106/1/"c"/0 Exclusive Replicated true false + +query TTTTTTBB colnames,retry +SELECT database_name, schema_name, table_name, lock_key_pretty, lock_strength, durability, granted, contended FROM crdb_internal.cluster_locks WHERE contended=true +---- +database_name schema_name table_name lock_key_pretty lock_strength durability granted contended +test public t /Table/106/1/"b"/0 Exclusive Replicated true true +test public t /Table/106/1/"b"/0 None Replicated false true + +query TTTTTTBB colnames,retry +SELECT database_name, schema_name, table_name, lock_key_pretty, lock_strength, durability, granted, contended FROM crdb_internal.cluster_locks WHERE contended=false +---- +database_name schema_name table_name lock_key_pretty lock_strength durability granted contended +test public t /Table/106/1/"c"/0 Exclusive Replicated true false + query I SELECT count(*) FROM crdb_internal.cluster_locks WHERE table_name = 't' ---- diff --git a/pkg/sql/logictest/testdata/logic_test/create_statements b/pkg/sql/logictest/testdata/logic_test/create_statements index e5af8180fa46..3c5f8b3a7ca7 100644 --- a/pkg/sql/logictest/testdata/logic_test/create_statements +++ b/pkg/sql/logictest/testdata/logic_test/create_statements @@ -253,9 +253,9 @@ CREATE TABLE crdb_internal.cluster_inflight_traces ( CREATE TABLE crdb_internal.cluster_locks ( range_id INT8 NOT NULL, table_id INT8 NOT NULL, - database_name STRING NULL, + database_name STRING NOT NULL, schema_name STRING NULL, - table_name STRING NULL, + table_name STRING NOT NULL, index_name STRING NULL, lock_key BYTES NOT NULL, lock_key_pretty STRING NOT NULL, @@ -264,14 +264,18 @@ CREATE TABLE crdb_internal.cluster_locks ( lock_strength STRING NULL, durability STRING NULL, granted BOOL NULL, - contended BOOL NULL, - duration INTERVAL NULL + contended BOOL NOT NULL, + duration INTERVAL NULL, + INDEX cluster_locks_table_id_idx (table_id ASC) STORING (range_id, database_name, schema_name, table_name, index_name, lock_key, lock_key_pretty, txn_id, ts, lock_strength, durability, granted, contended, duration), + INDEX cluster_locks_database_name_idx (database_name ASC) STORING (range_id, table_id, schema_name, table_name, index_name, lock_key, lock_key_pretty, txn_id, ts, lock_strength, durability, granted, contended, duration), + INDEX cluster_locks_table_name_idx (table_name ASC) STORING (range_id, table_id, database_name, schema_name, index_name, lock_key, lock_key_pretty, txn_id, ts, lock_strength, durability, granted, contended, duration), + INDEX cluster_locks_contended_idx (contended ASC) STORING (range_id, table_id, database_name, schema_name, table_name, index_name, lock_key, lock_key_pretty, txn_id, ts, lock_strength, durability, granted, duration) ) CREATE TABLE crdb_internal.cluster_locks ( range_id INT8 NOT NULL, table_id INT8 NOT NULL, - database_name STRING NULL, + database_name STRING NOT NULL, schema_name STRING NULL, - table_name STRING NULL, + table_name STRING NOT NULL, index_name STRING NULL, lock_key BYTES NOT NULL, lock_key_pretty STRING NOT NULL, @@ -280,8 +284,12 @@ CREATE TABLE crdb_internal.cluster_locks ( lock_strength STRING NULL, durability STRING NULL, granted BOOL NULL, - contended BOOL NULL, - duration INTERVAL NULL + contended BOOL NOT NULL, + duration INTERVAL NULL, + INDEX cluster_locks_table_id_idx (table_id ASC) STORING (range_id, database_name, schema_name, table_name, index_name, lock_key, lock_key_pretty, txn_id, ts, lock_strength, durability, granted, contended, duration), + INDEX cluster_locks_database_name_idx (database_name ASC) STORING (range_id, table_id, schema_name, table_name, index_name, lock_key, lock_key_pretty, txn_id, ts, lock_strength, durability, granted, contended, duration), + INDEX cluster_locks_table_name_idx (table_name ASC) STORING (range_id, table_id, database_name, schema_name, index_name, lock_key, lock_key_pretty, txn_id, ts, lock_strength, durability, granted, contended, duration), + INDEX cluster_locks_contended_idx (contended ASC) STORING (range_id, table_id, database_name, schema_name, table_name, index_name, lock_key, lock_key_pretty, txn_id, ts, lock_strength, durability, granted, duration) ) {} {} CREATE TABLE crdb_internal.cluster_queries ( query_id STRING NULL,