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: stop duplicating regions on the database descriptor #61585

Merged
merged 1 commit into from
Mar 17, 2021
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/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ ALL_TESTS = [
"//pkg/sql/catalog/descs:descs_test",
"//pkg/sql/catalog/hydratedtables:hydratedtables_test",
"//pkg/sql/catalog/lease:lease_test",
"//pkg/sql/catalog/multiregion:multiregion_test",
"//pkg/sql/catalog/schemadesc:schemadesc_test",
"//pkg/sql/catalog/schemaexpr:schemaexpr_test",
"//pkg/sql/catalog/systemschema:systemschema_test",
Expand Down
1 change: 1 addition & 0 deletions pkg/ccl/backupccl/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ go_library(
"//pkg/sql/catalog/dbdesc",
"//pkg/sql/catalog/descpb",
"//pkg/sql/catalog/descs",
"//pkg/sql/catalog/multiregion",
"//pkg/sql/catalog/schemadesc",
"//pkg/sql/catalog/schemaexpr",
"//pkg/sql/catalog/systemschema",
Expand Down
23 changes: 19 additions & 4 deletions pkg/ccl/backupccl/restore_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql/catalog/dbdesc"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descs"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/multiregion"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/schemadesc"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/typedesc"
Expand Down Expand Up @@ -375,7 +376,7 @@ func WriteDescriptors(
if err != nil {
return err
}
if dbDesc.GetRegionConfig() != nil {
if dbDesc.IsMultiRegion() {
if table.GetLocalityConfig() == nil {
table.(*tabledesc.Mutable).SetTableLocalityRegionalByTable(tree.PrimaryRegionNotSpecifiedName)
}
Expand Down Expand Up @@ -1085,7 +1086,7 @@ func createImportingDescriptors(
// as the system tables are restored.
mrEnumsFound := make(map[descpb.ID]descpb.ID)
for _, t := range typesByID {
typeDesc := t.TypeDesc()
typeDesc := typedesc.NewBuilder(t.TypeDesc()).BuildImmutableType()
if typeDesc.GetKind() == descpb.TypeDescriptor_MULTIREGION_ENUM {
// Check to see if we've found more than one multi-region enum on any
// given database.
Expand All @@ -1110,10 +1111,20 @@ func createImportingDescriptors(
// configuration.
if details.DescriptorCoverage != tree.AllDescriptors {
log.Infof(ctx, "restoring zone configuration for database %d", desc.ID)
regionNames, err := typeDesc.RegionNames()
if err != nil {
return err
}
regionConfig := multiregion.MakeRegionConfig(
regionNames,
desc.RegionConfig.PrimaryRegion,
desc.RegionConfig.SurvivalGoal,
desc.RegionConfig.RegionEnumID,
)
if err := sql.ApplyZoneConfigFromDatabaseRegionConfig(
ctx,
desc.GetID(),
*desc.RegionConfig,
regionConfig,
txn,
p.ExecCfg(),
); err != nil {
Expand Down Expand Up @@ -1240,11 +1251,15 @@ func createImportingDescriptors(
return err
}

regionConfig, err := sql.SynthesizeRegionConfig(ctx, txn, desc.ID, descsCol)
if err != nil {
return err
}
if err := sql.ApplyZoneConfigForMultiRegionTable(
ctx,
txn,
p.ExecCfg(),
*desc.RegionConfig,
regionConfig,
mutTable,
sql.ApplyZoneConfigForMultiRegionTableOptionTableAndIndexes,
); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/ccl/backupccl/restore_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ func allocateDescriptorRewrites(
// want to modify the table so that it can exist in the multi-region
// database.
// https://github.com/cockroachdb/cockroach/issues/59804
if parentDB.GetRegionConfig() != nil {
if parentDB.IsMultiRegion() {
return pgerror.Newf(pgcode.FeatureNotSupported,
"cannot restore individual table %d into multi-region database %d",
table.GetID(),
Expand Down
7 changes: 3 additions & 4 deletions pkg/ccl/importccl/import_table_creation.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,9 @@ func (so *importSequenceOperators) GetSerialSequenceNameFromColumn(
}

// CurrentDatabaseRegionConfig is part of the tree.EvalDatabase interface.
func (so *importSequenceOperators) CurrentDatabaseRegionConfig() (
tree.DatabaseRegionConfig,
error,
) {
func (so *importSequenceOperators) CurrentDatabaseRegionConfig(
_ context.Context,
) (tree.DatabaseRegionConfig, error) {
return nil, errors.WithStack(errSequenceOperators)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/ccl/logictestccl/testdata/logic_test/multi_region
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ CREATE DATABASE region_test_db PRIMARY REGION "ap-southeast-2" SURVIVE ZONE FAIL
statement ok
CREATE DATABASE multi_region_test_db PRIMARY REGION "ca-central-1" REGIONS "ap-southeast-2", "us-east-1" SURVIVE REGION FAILURE

statement error cannot DROP REGION on database multi_region_test_db as databases with SURVIVE REGION FAILURE must have at least 3 regions\nHINT: you must first add another region, or configure the database to SURVIVE ZONE FAILURE using ALTER DATABASE multi_region_test_db SURVIVE ZONE FAILURE
statement error at least 3 regions are required for surviving a region failure\nHINT: you must add additional regions to the database or change the survivability goal
ALTER DATABASE multi_region_test_db DROP REGION "ap-southeast-2"

statement ok
Expand Down
1 change: 1 addition & 0 deletions pkg/ccl/multiregionccl/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ go_library(
"//pkg/sql",
"//pkg/sql/catalog/catalogkv",
"//pkg/sql/catalog/descpb",
"//pkg/sql/catalog/multiregion",
"//pkg/sql/catalog/typedesc",
"//pkg/sql/pgwire/pgcode",
"//pkg/sql/pgwire/pgerror",
Expand Down
90 changes: 42 additions & 48 deletions pkg/ccl/multiregionccl/multiregion.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,29 @@ import (
"github.com/cockroachdb/cockroach/pkg/sql"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/catalogkv"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/multiregion"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/typedesc"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
)

func init() {
sql.CreateRegionConfigCCL = createRegionConfig
sql.InitializeMultiRegionMetadataCCL = initializeMultiRegionMetadata
sql.GetMultiRegionEnumAddValuePlacementCCL = getMultiRegionEnumAddValuePlacement
}

func createRegionConfig(
func initializeMultiRegionMetadata(
ctx context.Context,
evalCtx *tree.EvalContext,
execCfg *sql.ExecutorConfig,
liveRegions sql.LiveClusterRegions,
survivalGoal tree.SurvivalGoal,
primaryRegion tree.Name,
goal tree.SurvivalGoal,
primaryRegion descpb.RegionName,
regions []tree.Name,
) (descpb.DatabaseDescriptor_RegionConfig, error) {
) (*multiregion.RegionConfig, error) {
if err := checkClusterSupportsMultiRegion(evalCtx); err != nil {
return descpb.DatabaseDescriptor_RegionConfig{}, err
return nil, err
}

if err := utilccl.CheckEnterpriseEnabled(
Expand All @@ -47,78 +48,71 @@ func createRegionConfig(
execCfg.Organization(),
"multi-region features",
); err != nil {
return descpb.DatabaseDescriptor_RegionConfig{}, err
return nil, err
}

var regionConfig descpb.DatabaseDescriptor_RegionConfig
var err error
regionConfig.SurvivalGoal, err = sql.TranslateSurvivalGoal(survivalGoal)
survivalGoal, err := sql.TranslateSurvivalGoal(goal)
if err != nil {
return descpb.DatabaseDescriptor_RegionConfig{}, err
return nil, err
}

regionConfig.PrimaryRegion = descpb.RegionName(primaryRegion)
if regionConfig.PrimaryRegion != descpb.RegionName(tree.PrimaryRegionNotSpecifiedName) {
if err := sql.CheckLiveClusterRegion(liveRegions, regionConfig.PrimaryRegion); err != nil {
return descpb.DatabaseDescriptor_RegionConfig{}, err
if primaryRegion != descpb.RegionName(tree.PrimaryRegionNotSpecifiedName) {
if err := sql.CheckClusterRegionIsLive(liveRegions, primaryRegion); err != nil {
return nil, err
}
}
regionNames := make(descpb.RegionNames, 0, len(regions)+1)
seenRegions := make(map[descpb.RegionName]struct{}, len(regions)+1)
if len(regions) > 0 {
if regionConfig.PrimaryRegion == descpb.RegionName(tree.PrimaryRegionNotSpecifiedName) {
return descpb.DatabaseDescriptor_RegionConfig{}, pgerror.Newf(
if primaryRegion == descpb.RegionName(tree.PrimaryRegionNotSpecifiedName) {
return nil, pgerror.Newf(
pgcode.InvalidDatabaseDefinition,
"PRIMARY REGION must be specified if REGIONS are specified",
)
}
regionConfig.Regions = make([]descpb.DatabaseDescriptor_RegionConfig_Region, 0, len(regions)+1)
seenRegions := make(map[descpb.RegionName]struct{}, len(regions)+1)
for _, r := range regions {
region := descpb.RegionName(r)
if err := sql.CheckLiveClusterRegion(liveRegions, region); err != nil {
return descpb.DatabaseDescriptor_RegionConfig{}, err
if err := sql.CheckClusterRegionIsLive(liveRegions, region); err != nil {
return nil, err
}

if _, ok := seenRegions[region]; ok {
return descpb.DatabaseDescriptor_RegionConfig{}, pgerror.Newf(
return nil, pgerror.Newf(
pgcode.InvalidName,
"region %q defined multiple times",
region,
)
}
seenRegions[region] = struct{}{}
regionConfig.Regions = append(
regionConfig.Regions,
descpb.DatabaseDescriptor_RegionConfig_Region{
Name: region,
},
)
}
// If PRIMARY REGION is not in REGIONS, add it implicitly.
if _, ok := seenRegions[regionConfig.PrimaryRegion]; !ok {
regionConfig.Regions = append(
regionConfig.Regions,
descpb.DatabaseDescriptor_RegionConfig_Region{
Name: regionConfig.PrimaryRegion,
},
)
}
sort.SliceStable(regionConfig.Regions, func(i, j int) bool {
return regionConfig.Regions[i].Name < regionConfig.Regions[j].Name
})
} else {
regionConfig.Regions = []descpb.DatabaseDescriptor_RegionConfig_Region{
{Name: regionConfig.PrimaryRegion},
regionNames = append(regionNames, region)
}
}
// If PRIMARY REGION is not in REGIONS, add it implicitly.
if _, ok := seenRegions[primaryRegion]; !ok {
regionNames = append(regionNames, primaryRegion)
}

sort.SliceStable(regionNames, func(i, j int) bool {
return regionNames[i] < regionNames[j]
})

// Generate a unique ID for the multi-region enum type descriptor here as
// well.
id, err := catalogkv.GenerateUniqueDescID(ctx, execCfg.DB, execCfg.Codec)
regionEnumID, err := catalogkv.GenerateUniqueDescID(ctx, execCfg.DB, execCfg.Codec)
if err != nil {
return descpb.DatabaseDescriptor_RegionConfig{}, err
return nil, err
}
regionConfig := multiregion.MakeRegionConfig(
regionNames,
primaryRegion,
survivalGoal,
regionEnumID,
)
if err := multiregion.ValidateRegionConfig(regionConfig); err != nil {
return nil, err
}
regionConfig.RegionEnumID = id
return regionConfig, nil

return &regionConfig, nil
}

func checkClusterSupportsMultiRegion(evalCtx *tree.EvalContext) error {
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ go_test(
"//pkg/sql/catalog/descpb",
"//pkg/sql/catalog/descs",
"//pkg/sql/catalog/lease",
"//pkg/sql/catalog/multiregion",
"//pkg/sql/catalog/tabledesc",
"//pkg/sql/catalog/typedesc",
"//pkg/sql/distsql",
Expand Down
Loading