Commit 69531820 authored by Nathan VanBenschoten's avatar Nathan VanBenschoten

config: introduce pseudo "tenants" zone

Fixes #49318.
Fixes #49445.
Progress towards #48123.
Informs #48774.

This commit introduces a new pseudo object ID in the system tenant's
namespace called "tenants". Like "liveness" and "timeseries" before it,
the pseudo object allows zone configurations to be applied to
pseudo-objects that do not live directly in the system tenant's SQL
keyspace. In this case, the "tenants" zone allows zone configurations to
be set by the system tenant and applied to all other tenants in the
system. There may come a time when we want secondary tenants to have
more control over their zone configurations, but that will require a
much larger change to the zone config structure and UX as a whole.

While making this change, we rationalize the rest of zone configuration
handling and how it relates to multi-tenancy. Now that secondary tenant
ranges have a zone config to call their own, we can make sense of calls
from KV into the zone configuration infrastructure. We gate off calls
that don't make sense for secondary tenants and clean up hooks in SQL
that handle zone config manipulation.

All of this works towards a good cause - we eliminate the remaining uses
of `keys.TODOSQLCodec` from `pkg/sql/...` and `pkg/config/...`, bringing
us a big step closer towards being able to remove the placeholder and
close #48123.

This work also reveals that in order to address #48774, we need to be
able to determine split points from the SystemConfig. This makes it very
difficult to split on secondary tenant object (e.g. table) boundaries.
However, it makes it straightforward to split on secondary tenant
keysapce boundaries. This is already what we were thinking (see #47907),
so out both convenience and desire, I expect that we'll follow this up
with a PR that splits Ranges only at secondary tenant boundaries -
placing the overhead of an otherwise empty tenant at only a single Range
and a few KBs of data.
parent d8ae78a4
......@@ -1228,7 +1228,7 @@ func TestBackupRestoreControlJob(t *testing.T) {
if err != nil {
t.Fatal(err)
}
last := uint32(v.ValueInt())
last := config.SystemTenantObjectID(v.ValueInt())
zoneConfig := zonepb.DefaultZoneConfig()
zoneConfig.RangeMaxBytes = proto.Int64(5000)
config.TestingSetZoneConfig(last+1, zoneConfig)
......
......@@ -55,7 +55,7 @@ func setupExportableBank(t *testing.T, nodes, rows int) (*sqlutils.SQLRunner, st
if err != nil {
t.Fatal(err)
}
last := uint32(v.ValueInt())
last := config.SystemTenantObjectID(v.ValueInt())
zoneConfig := zonepb.DefaultZoneConfig()
zoneConfig.RangeMaxBytes = proto.Int64(5000)
config.TestingSetZoneConfig(last+1, zoneConfig)
......
......@@ -1406,7 +1406,7 @@ ALTER TABLE t ALTER PRIMARY KEY USING COLUMNS (y)
// Get the zone config corresponding to the table.
table := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "t", "t")
kv, err := kvDB.Get(ctx, config.MakeZoneKey(uint32(table.ID)))
kv, err := kvDB.Get(ctx, config.MakeZoneKey(config.SystemTenantObjectID(table.ID)))
if err != nil {
t.Fatal(err)
}
......
......@@ -54,7 +54,7 @@ requesting heap files for node 1... writing: debug/nodes/1/heapprof.err.txt
requesting goroutine files for node 1... writing: debug/nodes/1/goroutines.err.txt
^- resulted in ...
requesting log file ...
requesting ranges... 33 found
requesting ranges... 34 found
writing: debug/nodes/1/ranges/1.json
writing: debug/nodes/1/ranges/2.json
writing: debug/nodes/1/ranges/3.json
......@@ -88,6 +88,7 @@ writing: debug/nodes/1/ranges/30.json
writing: debug/nodes/1/ranges/31.json
writing: debug/nodes/1/ranges/32.json
writing: debug/nodes/1/ranges/33.json
writing: debug/nodes/1/ranges/34.json
writing: debug/nodes/2/status.json
using SQL connection URL for node 2: postgresql://...
retrieving SQL data for crdb_internal.feature_usage... writing: debug/nodes/2/crdb_internal.feature_usage.txt
......@@ -179,7 +180,7 @@ requesting heap files for node 3... writing: debug/nodes/3/heapprof.err.txt
requesting goroutine files for node 3... writing: debug/nodes/3/goroutines.err.txt
^- resulted in ...
requesting log file ...
requesting ranges... 33 found
requesting ranges... 34 found
writing: debug/nodes/3/ranges/1.json
writing: debug/nodes/3/ranges/2.json
writing: debug/nodes/3/ranges/3.json
......@@ -213,6 +214,7 @@ writing: debug/nodes/3/ranges/30.json
writing: debug/nodes/3/ranges/31.json
writing: debug/nodes/3/ranges/32.json
writing: debug/nodes/3/ranges/33.json
writing: debug/nodes/3/ranges/34.json
requesting list of SQL databases... 3 found
requesting database details for defaultdb... writing: debug/schema/[email protected]
0 tables found
......
......@@ -54,7 +54,7 @@ requesting heap files for node 1... writing: debug/nodes/1/heapprof.err.txt
requesting goroutine files for node 1... writing: debug/nodes/1/goroutines.err.txt
^- resulted in ...
requesting log file ...
requesting ranges... 33 found
requesting ranges... 34 found
writing: debug/nodes/1/ranges/1.json
writing: debug/nodes/1/ranges/2.json
writing: debug/nodes/1/ranges/3.json
......@@ -88,6 +88,7 @@ writing: debug/nodes/1/ranges/30.json
writing: debug/nodes/1/ranges/31.json
writing: debug/nodes/1/ranges/32.json
writing: debug/nodes/1/ranges/33.json
writing: debug/nodes/1/ranges/34.json
writing: debug/nodes/2.skipped
writing: debug/nodes/3/status.json
using SQL connection URL for node 3: postgresql://...
......@@ -116,7 +117,7 @@ requesting heap files for node 3... writing: debug/nodes/3/heapprof.err.txt
requesting goroutine files for node 3... writing: debug/nodes/3/goroutines.err.txt
^- resulted in ...
requesting log file ...
requesting ranges... 33 found
requesting ranges... 34 found
writing: debug/nodes/3/ranges/1.json
writing: debug/nodes/3/ranges/2.json
writing: debug/nodes/3/ranges/3.json
......@@ -150,6 +151,7 @@ writing: debug/nodes/3/ranges/30.json
writing: debug/nodes/3/ranges/31.json
writing: debug/nodes/3/ranges/32.json
writing: debug/nodes/3/ranges/33.json
writing: debug/nodes/3/ranges/34.json
requesting list of SQL databases... 3 found
requesting database details for defaultdb... writing: debug/schema/[email protected]
0 tables found
......
......@@ -54,7 +54,7 @@ requesting heap files for node 1... writing: debug/nodes/1/heapprof.err.txt
requesting goroutine files for node 1... writing: debug/nodes/1/goroutines.err.txt
^- resulted in ...
requesting log file ...
requesting ranges... 33 found
requesting ranges... 34 found
writing: debug/nodes/1/ranges/1.json
writing: debug/nodes/1/ranges/2.json
writing: debug/nodes/1/ranges/3.json
......@@ -88,6 +88,7 @@ writing: debug/nodes/1/ranges/30.json
writing: debug/nodes/1/ranges/31.json
writing: debug/nodes/1/ranges/32.json
writing: debug/nodes/1/ranges/33.json
writing: debug/nodes/1/ranges/34.json
writing: debug/nodes/3/status.json
using SQL connection URL for node 3: postgresql://...
retrieving SQL data for crdb_internal.feature_usage... writing: debug/nodes/3/crdb_internal.feature_usage.txt
......@@ -115,7 +116,7 @@ requesting heap files for node 3... writing: debug/nodes/3/heapprof.err.txt
requesting goroutine files for node 3... writing: debug/nodes/3/goroutines.err.txt
^- resulted in ...
requesting log file ...
requesting ranges... 33 found
requesting ranges... 34 found
writing: debug/nodes/3/ranges/1.json
writing: debug/nodes/3/ranges/2.json
writing: debug/nodes/3/ranges/3.json
......@@ -149,6 +150,7 @@ writing: debug/nodes/3/ranges/30.json
writing: debug/nodes/3/ranges/31.json
writing: debug/nodes/3/ranges/32.json
writing: debug/nodes/3/ranges/33.json
writing: debug/nodes/3/ranges/34.json
requesting list of SQL databases... 3 found
requesting database details for defaultdb... writing: debug/schema/[email protected]
0 tables found
......
......@@ -52,7 +52,7 @@ requesting heap profile for node 1... writing: debug/nodes/1/heap.pprof
requesting heap files for node 1... ? found
requesting goroutine files for node 1... 0 found
requesting log file ...
requesting ranges... 33 found
requesting ranges... 34 found
writing: debug/nodes/1/ranges/1.json
writing: debug/nodes/1/ranges/2.json
writing: debug/nodes/1/ranges/3.json
......@@ -86,6 +86,7 @@ writing: debug/nodes/1/ranges/30.json
writing: debug/nodes/1/ranges/31.json
writing: debug/nodes/1/ranges/32.json
writing: debug/nodes/1/ranges/33.json
writing: debug/nodes/1/ranges/34.json
requesting list of SQL databases... 3 found
requesting database details for defaultdb... writing: debug/schema/[email protected]
0 tables found
......
......@@ -17,19 +17,20 @@ import (
// MakeZoneKeyPrefix returns the key prefix for id's row in the system.zones
// table.
func MakeZoneKeyPrefix(id uint32) roachpb.Key {
return keys.SystemSQLCodec.ZoneKeyPrefix(id)
func MakeZoneKeyPrefix(id SystemTenantObjectID) roachpb.Key {
return keys.SystemSQLCodec.ZoneKeyPrefix(uint32(id))
}
// MakeZoneKey returns the key for id's entry in the system.zones table.
func MakeZoneKey(id uint32) roachpb.Key {
return keys.SystemSQLCodec.ZoneKey(id)
func MakeZoneKey(id SystemTenantObjectID) roachpb.Key {
return keys.SystemSQLCodec.ZoneKey(uint32(id))
}
// DecodeObjectID decodes the object ID from the front of key. It returns the
// decoded object ID, the remainder of the key, and whether the result is valid
// (i.e., whether the key was within the structured key space).
func DecodeObjectID(key roachpb.RKey) (uint32, []byte, bool) {
rem, id, err := keys.TODOSQLCodec.DecodeTablePrefix(key.AsRawKey())
return id, rem, err == nil
// DecodeSystemTenantObjectID decodes the object ID for the system-tenant from
// the front of key. It returns the decoded object ID, the remainder of the key,
// and whether the result is valid (i.e., whether the key was within the system
// tenant's structured key space).
func DecodeSystemTenantObjectID(key roachpb.RKey) (SystemTenantObjectID, []byte, bool) {
rem, id, err := keys.SystemSQLCodec.DecodeTablePrefix(key.AsRawKey())
return SystemTenantObjectID(id), rem, err == nil
}
......@@ -21,14 +21,14 @@ import (
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
)
func TestDecodeObjectID(t *testing.T) {
func TestDecodeSystemTenantObjectID(t *testing.T) {
defer leaktest.AfterTest(t)()
testCases := []struct {
key roachpb.RKey
keySuffix []byte
success bool
id uint32
id config.SystemTenantObjectID
}{
// Before the structured span.
{roachpb.RKeyMin, nil, false, 0},
......@@ -43,7 +43,7 @@ func TestDecodeObjectID(t *testing.T) {
}
for tcNum, tc := range testCases {
id, keySuffix, success := config.DecodeObjectID(tc.key)
id, keySuffix, success := config.DecodeSystemTenantObjectID(tc.key)
if success != tc.success {
t.Errorf("#%d: expected success=%t", tcNum, tc.success)
continue
......
This diff is collapsed.
......@@ -40,16 +40,24 @@ func tkey(tableID uint32, chunks ...string) []byte {
return key
}
func sqlKV(tableID uint32, indexID, descriptorID uint64) roachpb.KeyValue {
func tenantTkey(tenantID uint64, tableID uint32, chunks ...string) []byte {
key := keys.MakeSQLCodec(roachpb.MakeTenantID(tenantID)).TablePrefix(tableID)
for _, c := range chunks {
key = append(key, []byte(c)...)
}
return key
}
func sqlKV(tableID uint32, indexID, descID uint64) roachpb.KeyValue {
k := tkey(tableID)
k = encoding.EncodeUvarintAscending(k, indexID)
k = encoding.EncodeUvarintAscending(k, descriptorID)
k = encoding.EncodeUvarintAscending(k, descID)
k = encoding.EncodeUvarintAscending(k, 12345) // Column ID, but could be anything.
return kv(k, nil)
}
func descriptor(descriptorID uint64) roachpb.KeyValue {
k := sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, sqlbase.ID(descriptorID))
func descriptor(descID uint64) roachpb.KeyValue {
k := sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, sqlbase.ID(descID))
v := sqlbase.WrapDescriptor(&sqlbase.TableDescriptor{})
kv := roachpb.KeyValue{Key: k}
if err := kv.Value.SetProto(v); err != nil {
......@@ -58,9 +66,9 @@ func descriptor(descriptorID uint64) roachpb.KeyValue {
return kv
}
func zoneConfig(descriptorID uint32, spans ...zonepb.SubzoneSpan) roachpb.KeyValue {
func zoneConfig(descID config.SystemTenantObjectID, spans ...zonepb.SubzoneSpan) roachpb.KeyValue {
kv := roachpb.KeyValue{
Key: config.MakeZoneKey(descriptorID),
Key: config.MakeZoneKey(descID),
}
if err := kv.Value.SetProto(&zonepb.ZoneConfig{SubzoneSpans: spans}); err != nil {
panic(err)
......@@ -128,8 +136,8 @@ func TestGetLargestID(t *testing.T) {
type testCase struct {
values []roachpb.KeyValue
largest uint32
maxID uint32
largest config.SystemTenantObjectID
maxID config.SystemTenantObjectID
pseudoIDs []uint32
errStr string
}
......@@ -184,10 +192,14 @@ func TestGetLargestID(t *testing.T) {
func() testCase {
ms := sqlbase.MakeMetadataSchema(keys.SystemSQLCodec, zonepb.DefaultZoneConfigRef(), zonepb.DefaultSystemZoneConfigRef())
descIDs := ms.DescriptorIDs()
maxDescID := descIDs[len(descIDs)-1]
maxDescID := config.SystemTenantObjectID(descIDs[len(descIDs)-1])
kvs, _ /* splits */ := ms.GetInitialValues()
pseudoIDs := keys.PseudoTableIDs
return testCase{kvs, uint32(maxDescID), 0, pseudoIDs, ""}
const pseudoIDIsMax = true // NOTE: will change as new system objects are added
if pseudoIDIsMax {
maxDescID = config.SystemTenantObjectID(keys.MaxPseudoTableID)
}
return testCase{kvs, maxDescID, 0, pseudoIDs, ""}
}(),
// Test non-zero max.
......@@ -431,7 +443,7 @@ func TestGetZoneConfigForKey(t *testing.T) {
testCases := []struct {
key roachpb.RKey
expectedID uint32
expectedID config.SystemTenantObjectID
}{
{roachpb.RKeyMin, keys.MetaRangesID},
{roachpb.RKey(keys.Meta1Prefix), keys.MetaRangesID},
......@@ -473,6 +485,12 @@ func TestGetZoneConfigForKey(t *testing.T) {
{tkey(keys.MinUserDescID), keys.MinUserDescID},
{tkey(keys.MinUserDescID + 22), keys.MinUserDescID + 22},
{roachpb.RKeyMax, keys.RootNamespaceID},
// Secondary tenant tables should refer to the TenantsRangesID.
{tenantTkey(5, keys.MinUserDescID), keys.TenantsRangesID},
{tenantTkey(5, keys.MinUserDescID+22), keys.TenantsRangesID},
{tenantTkey(10, keys.MinUserDescID), keys.TenantsRangesID},
{tenantTkey(10, keys.MinUserDescID+22), keys.TenantsRangesID},
}
originalZoneConfigHook := config.ZoneConfigHook
......@@ -488,9 +506,9 @@ func TestGetZoneConfigForKey(t *testing.T) {
Values: kvs,
}
for tcNum, tc := range testCases {
var objectID uint32
var objectID config.SystemTenantObjectID
config.ZoneConfigHook = func(
_ *config.SystemConfig, id uint32,
_ *config.SystemConfig, id config.SystemTenantObjectID,
) (*zonepb.ZoneConfig, *zonepb.ZoneConfig, bool, error) {
objectID = id
return &zonepb.ZoneConfig{}, nil, false, nil
......
......@@ -16,7 +16,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/util/syncutil"
)
type zoneConfigMap map[uint32]zonepb.ZoneConfig
type zoneConfigMap map[SystemTenantObjectID]zonepb.ZoneConfig
var (
testingZoneConfig zoneConfigMap
......@@ -40,7 +40,7 @@ func TestingSetupZoneConfigHook(stopper *stop.Stopper) {
testingZoneConfig = make(zoneConfigMap)
testingPreviousHook = ZoneConfigHook
ZoneConfigHook = testingZoneConfigHook
testingLargestIDHook = func(maxID uint32) (max uint32) {
testingLargestIDHook = func(maxID SystemTenantObjectID) (max SystemTenantObjectID) {
testingLock.Lock()
defer testingLock.Unlock()
for id := range testingZoneConfig {
......@@ -70,14 +70,14 @@ func testingResetZoneConfigHook() {
// TestingSetZoneConfig sets the zone config entry for object 'id'
// in the testing map.
func TestingSetZoneConfig(id uint32, zone zonepb.ZoneConfig) {
func TestingSetZoneConfig(id SystemTenantObjectID, zone zonepb.ZoneConfig) {
testingLock.Lock()
defer testingLock.Unlock()
testingZoneConfig[id] = zone
}
func testingZoneConfigHook(
_ *SystemConfig, id uint32,
_ *SystemConfig, id SystemTenantObjectID,
) (*zonepb.ZoneConfig, *zonepb.ZoneConfig, bool, error) {
testingLock.Lock()
defer testingLock.Unlock()
......
......@@ -35,6 +35,7 @@ const (
MetaZoneName = "meta"
SystemZoneName = "system"
TimeseriesZoneName = "timeseries"
TenantsZoneName = "tenants"
)
// NamedZones maps named zones to their pseudo-table ID that can be used to
......@@ -45,6 +46,7 @@ var NamedZones = map[string]uint32{
MetaZoneName: keys.MetaRangesID,
SystemZoneName: keys.SystemRangesID,
TimeseriesZoneName: keys.TimeseriesRangesID,
TenantsZoneName: keys.TenantsRangesID,
}
// NamedZonesByID is the inverse of NamedZones: it maps pseudo-table IDs to
......
......@@ -353,34 +353,31 @@ const (
RangeEventTableID = 13
UITableID = 14
JobsTableID = 15
MetaRangesID = 16
SystemRangesID = 17
TimeseriesRangesID = 18
MetaRangesID = 16 // pseudo
SystemRangesID = 17 // pseudo
TimeseriesRangesID = 18 // pseudo
WebSessionsTableID = 19
TableStatisticsTableID = 20
LocationsTableID = 21
LivenessRangesID = 22
LivenessRangesID = 22 // pseudo
RoleMembersTableID = 23
CommentsTableID = 24
ReplicationConstraintStatsTableID = 25
ReplicationCriticalLocalitiesTableID = 26
ReplicationStatsTableID = 27
ReportsMetaTableID = 28
PublicSchemaID = 29
PublicSchemaID = 29 // pseudo
// New NamespaceTableID for cluster version >= 20.1
// Ensures that NamespaceTable does not get gossiped again
NamespaceTableID = 30
ProtectedTimestampsMetaTableID = 31
ProtectedTimestampsRecordsTableID = 32
RoleOptionsTableID = 33
NamespaceTableID = 30
ProtectedTimestampsMetaTableID = 31
ProtectedTimestampsRecordsTableID = 32
RoleOptionsTableID = 33
StatementBundleChunksTableID = 34
StatementDiagnosticsRequestsTableID = 35
StatementDiagnosticsTableID = 36
ScheduledJobsTableID = 37
ScheduledJobsTableID = 37
TenantsRangesID = 38 // pseudo
// CommentType is type for system.comments
DatabaseCommentType = 0
......@@ -402,4 +399,22 @@ const (
// there's no table descriptor). They're grouped here because the cluster
// bootstrap process needs to create splits for them; splits for the tables
// happen separately.
var PseudoTableIDs = []uint32{MetaRangesID, SystemRangesID, TimeseriesRangesID, LivenessRangesID, PublicSchemaID}
var PseudoTableIDs = []uint32{
MetaRangesID,
SystemRangesID,
TimeseriesRangesID,
LivenessRangesID,
PublicSchemaID,
TenantsRangesID,
}
// MaxPseudoTableID is the largest ID in PseudoTableIDs.
var MaxPseudoTableID = func() uint32 {
var max uint32
for _, id := range PseudoTableIDs {
if max < id {
max = id
}
}
return max
}()
......@@ -1017,7 +1017,7 @@ func TestStoreZoneUpdateAndRangeSplit(t *testing.T) {
descID := uint32(keys.MinUserDescID)
zoneConfig := zonepb.DefaultZoneConfig()
zoneConfig.RangeMaxBytes = proto.Int64(maxBytes)
config.TestingSetZoneConfig(descID, zoneConfig)
config.TestingSetZoneConfig(config.SystemTenantObjectID(descID), zoneConfig)
// Trigger gossip callback.
if err := store.Gossip().AddInfoProto(gossip.KeySystemConfig, &config.SystemConfigEntries{}, 0); err != nil {
......@@ -1079,7 +1079,7 @@ func TestStoreRangeSplitWithMaxBytesUpdate(t *testing.T) {
descID := uint32(keys.MinUserDescID)
zoneConfig := zonepb.DefaultZoneConfig()
zoneConfig.RangeMaxBytes = proto.Int64(maxBytes)
config.TestingSetZoneConfig(descID, zoneConfig)
config.TestingSetZoneConfig(config.SystemTenantObjectID(descID), zoneConfig)
// Trigger gossip callback.
if err := store.Gossip().AddInfoProto(gossip.KeySystemConfig, &config.SystemConfigEntries{}, 0); err != nil {
......@@ -1325,6 +1325,9 @@ func TestStoreRangeSystemSplits(t *testing.T) {
}
ids := schema.DescriptorIDs()
maxID := uint32(ids[len(ids)-1])
if maxPseudo := keys.MaxPseudoTableID; maxID < maxPseudo {
maxID = maxPseudo
}
for i := uint32(keys.MaxSystemConfigDescID + 1); i <= maxID; i++ {
expKeys = append(expKeys,
testutils.MakeKey(keys.Meta2Prefix, keys.SystemSQLCodec.TablePrefix(i)),
......
......@@ -183,7 +183,7 @@ func (r *replicationConstraintStatsReportSaver) loadPreviousVersion(
r.previousVersion = make(ConstraintReport, len(rows))
for _, row := range rows {
key := ConstraintStatusKey{}
key.ZoneID = (uint32)(*row[0].(*tree.DInt))
key.ZoneID = (config.SystemTenantObjectID)(*row[0].(*tree.DInt))
key.SubzoneID = base.SubzoneID((*row[1].(*tree.DInt)))
key.ViolationType = (ConstraintType)(*row[2].(*tree.DString))
key.Constraint = (ConstraintRepr)(*row[3].(*tree.DString))
......@@ -395,7 +395,7 @@ func (v *constraintConformanceVisitor) reset(ctx context.Context) {
if err != nil {
log.Fatalf(ctx, "unexpected failure to compute max object id: %s", err)
}
for i := uint32(1); i <= maxObjectID; i++ {
for i := config.SystemTenantObjectID(1); i <= maxObjectID; i++ {
zone, err := getZoneByID(i, v.cfg)
if err != nil {
log.Fatalf(ctx, "unexpected failure to compute max object id: %s", err)
......
......@@ -1011,13 +1011,13 @@ func (b *systemConfigBuilder) setDefaultZoneConfig(cfg zonepb.ZoneConfig) error
}
func (b *systemConfigBuilder) addZoneInner(objectName string, id int, cfg zonepb.ZoneConfig) error {
k := config.MakeZoneKey(uint32(id))
k := config.MakeZoneKey(config.SystemTenantObjectID(id))
var v roachpb.Value
if err := v.SetProto(&cfg); err != nil {
panic(err)
}
b.kv = append(b.kv, roachpb.KeyValue{Key: k, Value: v})
return b.addZoneToObjectMapping(MakeZoneKey(uint32(id), NoSubzone), objectName)
return b.addZoneToObjectMapping(MakeZoneKey(config.SystemTenantObjectID(id), NoSubzone), objectName)
}
func (b *systemConfigBuilder) addDatabaseZone(name string, id int, cfg zonepb.ZoneConfig) error {
......@@ -1044,7 +1044,7 @@ func (b *systemConfigBuilder) addTableZone(t sqlbase.TableDescriptor, cfg zonepb
object = fmt.Sprintf("%s.%s", idx, subzone.PartitionName)
}
if err := b.addZoneToObjectMapping(
MakeZoneKey(uint32(t.ID), base.SubzoneIDFromIndex(i)), object,
MakeZoneKey(config.SystemTenantObjectID(t.ID), base.SubzoneIDFromIndex(i)), object,
); err != nil {
return err
}
......
......@@ -113,7 +113,7 @@ func (r *replicationCriticalLocalitiesReportSaver) loadPreviousVersion(
r.previousVersion = make(LocalityReport, len(rows))
for _, row := range rows {
key := localityKey{}
key.ZoneID = (uint32)(*row[0].(*tree.DInt))
key.ZoneID = (config.SystemTenantObjectID)(*row[0].(*tree.DInt))
key.SubzoneID = base.SubzoneID(*row[1].(*tree.DInt))
key.locality = (LocalityRepr)(*row[2].(*tree.DString))
r.previousVersion[key] = localityStatus{(int32)(*row[3].(*tree.DInt))}
......
......@@ -121,7 +121,7 @@ func (r *replicationStatsReportSaver) loadPreviousVersion(
r.previousVersion = make(RangeReport, len(rows))
for _, row := range rows {
key := ZoneKey{}
key.ZoneID = (uint32)(*row[0].(*tree.DInt))
key.ZoneID = (config.SystemTenantObjectID)(*row[0].(*tree.DInt))
key.SubzoneID = base.SubzoneID(*row[1].(*tree.DInt))
r.previousVersion[key] = zoneRangeStatus{
(int32)(*row[2].(*tree.DInt)),
......@@ -305,7 +305,7 @@ func (v *replicationStatsVisitor) reset(ctx context.Context) {
if err != nil {
log.Fatalf(ctx, "unexpected failure to compute max object id: %s", err)
}
for i := uint32(1); i <= maxObjectID; i++ {
for i := config.SystemTenantObjectID(1); i <= maxObjectID; i++ {
zone, err := getZoneByID(i, v.cfg)
if err != nil {
log.Fatalf(ctx, "unexpected failure to compute max object id: %s", err)
......
......@@ -280,7 +280,7 @@ type nodeChecker func(nodeID roachpb.NodeID) bool
type zoneResolver struct {
init bool
// curObjectID is the object (i.e. usually table) of the configured range.
curObjectID uint32
curObjectID config.SystemTenantObjectID
// curRootZone is the lowest zone convering the previously resolved range
// that's not a subzone.
// This is used to compute the subzone for a range.
......@@ -302,7 +302,9 @@ func (c *zoneResolver) resolveRange(
// setZone remembers the passed-in info as the reference for further
// checkSameZone() calls.
// Clients should generally use the higher-level updateZone().
func (c *zoneResolver) setZone(objectID uint32, key ZoneKey, rootZone *zonepb.ZoneConfig) {
func (c *zoneResolver) setZone(
objectID config.SystemTenantObjectID, key ZoneKey, rootZone *zonepb.ZoneConfig,
) {
c.init = true
c.curObjectID = objectID
c.curRootZone = rootZone
......@@ -425,7 +427,7 @@ func visitZones(
// corresponding to id. The zone corresponding to id itself is not visited.
func visitAncestors(
ctx context.Context,
id uint32,
id config.SystemTenantObjectID,
cfg *config.SystemConfig,
visitor func(context.Context, *zonepb.ZoneConfig, ZoneKey) bool,
) (bool, error) {
......@@ -449,12 +451,12 @@ func visitAncestors(
}
// If it's a table, the parent is a database.
zone, err := getZoneByID(uint32(tableDesc.ParentID), cfg)
zone, err := getZoneByID(config.SystemTenantObjectID(tableDesc.ParentID), cfg)
if err != nil {
return false, err
}
if zone != nil {
if visitor(ctx, zone, MakeZoneKey(uint32(tableDesc.ParentID), NoSubzone)) {
if visitor(ctx, zone, MakeZoneKey(config.SystemTenantObjectID(tableDesc.ParentID), NoSubzone)) {
return true, nil
}
}
......@@ -478,7 +480,9 @@ func visitDefaultZone(
}
// getZoneByID returns a zone given its id. Inheritance does not apply.
func getZoneByID(id uint32, cfg *config.SystemConfig) (*zonepb.ZoneConfig, error) {
func getZoneByID(
id config.SystemTenantObjectID, cfg *config.SystemConfig,
) (*zonepb.ZoneConfig, error) {
zoneVal := cfg.GetValue(config.MakeZoneKey(id))
if zoneVal == nil {
return nil, nil
......
......@@ -511,9 +511,9 @@ func TestZoneChecker(t *testing.T) {
p2SubzoneIndex := 1
require.Equal(t, "p1", t1Zone.Subzones[p1SubzoneIndex].PartitionName)
require.Equal(t, "p2", t1Zone.Subzones[p2SubzoneIndex].PartitionName)
t1ZoneKey := MakeZoneKey(uint32(t1ID), NoSubzone)
p1ZoneKey := MakeZoneKey(uint32(t1ID), base.SubzoneIDFromIndex(p1SubzoneIndex))
p2ZoneKey := MakeZoneKey(uint32(t1ID), base.SubzoneIDFromIndex(p2SubzoneIndex))
t1ZoneKey := MakeZoneKey(config.SystemTenantObjectID(t1ID), NoSubzone)
p1ZoneKey := MakeZoneKey(config.SystemTenantObjectID(t1ID), base.SubzoneIDFromIndex(p1SubzoneIndex))
p2ZoneKey := MakeZoneKey(config.SystemTenantObjectID(t1ID), base.SubzoneIDFromIndex(p2SubzoneIndex))
ranges := []tc{
{
......
......@@ -14,12 +14,13 @@ import (
"fmt"
"github.com/cockroachdb/cockroach/pkg/base"
"github.com/cockroachdb/cockroach/pkg/config"
)
// ZoneKey is the index of the first level in the constraint conformance report.
type ZoneKey struct {
// ZoneID is the id of the zone this key is referencing.
ZoneID uint32
ZoneID config.SystemTenantObjectID
// SubzoneID identifies what subzone, if any, this key is referencing. The
// zero value (also named NoSubzone) indicates that the key is referring to a
// zone, not a subzone.
......@@ -34,7 +35,7 @@ const NoSubzone base.SubzoneID = 0
//
// Use NoSubzone for subzoneID to indicate that the key references a zone, not a
// subzone.
func MakeZoneKey(zoneID uint32, subzoneID base.SubzoneID) ZoneKey {
func MakeZoneKey(zoneID config.SystemTenantObjectID, subzoneID base.SubzoneID) ZoneKey {
return ZoneKey{
ZoneID: zoneID,
SubzoneID: subzoneID,
......
......@@ -1475,8 +1475,12 @@ func TestStoreSetRangesMaxBytes(t *testing.T) {
}
// Set zone configs.
config.TestingSetZoneConfig(baseID, zonepb.ZoneConfig{RangeMaxBytes: proto.Int64(1 << 20)})
config.TestingSetZoneConfig(baseID+2, zonepb.ZoneConfig{RangeMaxBytes: proto.Int64(2 << 20)})
config.TestingSetZoneConfig(
config.SystemTenantObjectID(baseID), zonepb.ZoneConfig{RangeMaxBytes: proto.Int64(1 << 20)},
)
config.TestingSetZoneConfig(
config.SystemTenantObjectID(baseID+2), zonepb.ZoneConfig{RangeMaxBytes: proto.Int64(2 << 20)},
)
// Despite faking the zone configs, we still need to have a system config
// entry so that the store picks up the new zone configs. This new system
......
......@@ -78,6 +78,7 @@ func nonTableDescriptorRangeCount() int64 {
keys.TimeseriesRangesID,
keys.LivenessRangesID,
keys.PublicSchemaID,
keys.TenantsRangesID,
}))
}
......@@ -699,9 +700,8 @@ func (s *adminServer) NonTableStats(
}
}
// There are four empty ranges for table descriptors 17, 18, 19, and 22 that
// aren't actually tables (a.k.a. MetaRangesID, SystemRangesID,
// TimeseriesRangesID, and LivenessRangesID in pkg/keys).
// There are six empty ranges for table descriptors 17, 18, 19, 22, 29, and
// 37 that aren't actually tables (a.k.a. the PseudoTableIDs in pkg/keys).
// No data is ever really written to them since they don't have actual
// tables. Some backend work could probably be done to eliminate these empty
// ranges, but it may be more trouble than it's worth. In the meantime,
......
......@@ -403,7 +403,7 @@ func TestAdminAPINonTableStats(t *testing.T) {
NodeCount: 3,
},
InternalUseStats: &serverpb.TableStatsResponse{
RangeCount: 9,
RangeCount: 10,
ReplicaCount: 12,
NodeCount: 3,
},
......
......@@ -728,6 +728,9 @@ func ExpectedInitialRangeCount(
maxSystemDescriptorID = descID
}
}
if maxSystemDescriptorID < sqlbase.ID(keys.MaxPseudoTableID) {
maxSystemDescriptorID = sqlbase.ID(keys.MaxPseudoTableID)
}
systemTableSplits := int(maxSystemDescriptorID - keys.MaxSystemConfigDescID)
// `n` splits create `n+1` ranges.
......
......@@ -23,6 +23,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/base"
"github.com/cockroachdb/cockroach/pkg/build"
"github.com/cockroachdb/cockroach/pkg/clusterversion"
"github.com/cockroachdb/cockroach/pkg/config"
"github.com/cockroachdb/cockroach/pkg/config/zonepb"
"github.com/cockroachdb/cockroach/pkg/gossip"
"github.com/cockroachdb/cockroach/pkg/jobs"
......@@ -42,6 +43,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
"github.com/cockroachdb/cockroach/pkg/sql/types"
"github.com/cockroachdb/cockroach/pkg/util/errorutil"