github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/zone_config_test.go (about) 1 // Copyright 2015 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package sql_test 12 13 import ( 14 "context" 15 "testing" 16 17 "github.com/cockroachdb/cockroach/pkg/config" 18 "github.com/cockroachdb/cockroach/pkg/config/zonepb" 19 "github.com/cockroachdb/cockroach/pkg/keys" 20 "github.com/cockroachdb/cockroach/pkg/kv" 21 "github.com/cockroachdb/cockroach/pkg/roachpb" 22 "github.com/cockroachdb/cockroach/pkg/server" 23 "github.com/cockroachdb/cockroach/pkg/sql" 24 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 25 "github.com/cockroachdb/cockroach/pkg/sql/tests" 26 "github.com/cockroachdb/cockroach/pkg/testutils" 27 "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" 28 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 29 "github.com/cockroachdb/cockroach/pkg/util/protoutil" 30 "github.com/cockroachdb/errors" 31 "github.com/gogo/protobuf/proto" 32 "github.com/stretchr/testify/require" 33 ) 34 35 var configID = sqlbase.ID(1) 36 var configDescKey = sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, keys.MaxReservedDescID) 37 38 // forceNewConfig forces a system config update by writing a bogus descriptor with an 39 // incremented value inside. It then repeatedly fetches the gossip config until the 40 // just-written descriptor is found. 41 func forceNewConfig(t testing.TB, s *server.TestServer) *config.SystemConfig { 42 configID++ 43 configDesc := &sqlbase.Descriptor{ 44 Union: &sqlbase.Descriptor_Database{ 45 Database: &sqlbase.DatabaseDescriptor{ 46 Name: "sentinel", 47 ID: configID, 48 Privileges: &sqlbase.PrivilegeDescriptor{}, 49 }, 50 }, 51 } 52 53 // This needs to be done in a transaction with the system trigger set. 54 if err := s.DB().Txn(context.Background(), func(ctx context.Context, txn *kv.Txn) error { 55 if err := txn.SetSystemConfigTrigger(); err != nil { 56 return err 57 } 58 return txn.Put(ctx, configDescKey, configDesc) 59 }); err != nil { 60 t.Fatal(err) 61 } 62 return waitForConfigChange(t, s) 63 } 64 65 func waitForConfigChange(t testing.TB, s *server.TestServer) *config.SystemConfig { 66 var foundDesc sqlbase.Descriptor 67 var cfg *config.SystemConfig 68 testutils.SucceedsSoon(t, func() error { 69 if cfg = s.Gossip().GetSystemConfig(); cfg != nil { 70 if val := cfg.GetValue(configDescKey); val != nil { 71 if err := val.GetProto(&foundDesc); err != nil { 72 t.Fatal(err) 73 } 74 if id := foundDesc.GetDatabase().GetID(); id != configID { 75 return errors.Errorf("expected database id %d; got %d", configID, id) 76 } 77 return nil 78 } 79 } 80 return errors.Errorf("got nil system config") 81 }) 82 return cfg 83 } 84 85 // TODO(benesch,ridwansharif): modernize these tests to avoid hardcoding 86 // expectations about descriptor IDs and zone config encoding. 87 // TestGetZoneConfig exercises config.getZoneConfig and the sql hook for it. 88 func TestGetZoneConfig(t *testing.T) { 89 defer leaktest.AfterTest(t)() 90 params, _ := tests.CreateTestServerParams() 91 defaultZoneConfig := zonepb.DefaultSystemZoneConfig() 92 defaultZoneConfig.NumReplicas = proto.Int32(1) 93 defaultZoneConfig.RangeMinBytes = proto.Int64(1 << 20) 94 defaultZoneConfig.RangeMaxBytes = proto.Int64(1 << 21) 95 defaultZoneConfig.GC = &zonepb.GCPolicy{TTLSeconds: 60} 96 require.NoError(t, defaultZoneConfig.Validate()) 97 params.Knobs.Server = &server.TestingKnobs{ 98 DefaultZoneConfigOverride: &defaultZoneConfig, 99 DefaultSystemZoneConfigOverride: &defaultZoneConfig, 100 } 101 102 srv, sqlDB, _ := serverutils.StartServer(t, params) 103 defer srv.Stopper().Stop(context.Background()) 104 s := srv.(*server.TestServer) 105 106 expectedCounter := uint32(keys.MinNonPredefinedUserDescID) 107 108 type testCase struct { 109 objectID uint32 110 111 // keySuffix and partitionName must specify the same subzone. 112 keySuffix []byte 113 partitionName string 114 115 zoneCfg zonepb.ZoneConfig 116 } 117 verifyZoneConfigs := func(testCases []testCase) { 118 cfg := forceNewConfig(t, s) 119 120 for tcNum, tc := range testCases { 121 // Verify SystemConfig.GetZoneConfigForKey. 122 { 123 key := append(roachpb.RKey(keys.SystemSQLCodec.TablePrefix(tc.objectID)), tc.keySuffix...) 124 zoneCfg, err := cfg.GetZoneConfigForKey(key) // Complete ZoneConfig 125 if err != nil { 126 t.Fatalf("#%d: err=%s", tcNum, err) 127 } 128 129 if !tc.zoneCfg.Equal(zoneCfg) { 130 t.Errorf("#%d: bad zone config.\nexpected: %+v\ngot: %+v", tcNum, tc.zoneCfg, zoneCfg) 131 } 132 } 133 134 // Verify sql.GetZoneConfigInTxn. 135 if err := s.DB().Txn(context.Background(), func(ctx context.Context, txn *kv.Txn) error { 136 _, zoneCfg, subzone, err := sql.GetZoneConfigInTxn(ctx, txn, 137 tc.objectID, &sqlbase.IndexDescriptor{}, tc.partitionName, false) 138 if err != nil { 139 return err 140 } else if subzone != nil { 141 zoneCfg = &subzone.Config 142 } 143 if !tc.zoneCfg.Equal(zoneCfg) { 144 t.Errorf("#%d: bad zone config.\nexpected: %+v\ngot: %+v", tcNum, tc.zoneCfg, zoneCfg) 145 } 146 return nil 147 }); err != nil { 148 t.Fatalf("#%d: err=%s", tcNum, err) 149 } 150 } 151 } 152 153 { 154 buf, err := protoutil.Marshal(&defaultZoneConfig) 155 if err != nil { 156 t.Fatal(err) 157 } 158 objID := keys.RootNamespaceID 159 if _, err = sqlDB.Exec(`UPDATE system.zones SET config = $2 WHERE id = $1`, objID, buf); err != nil { 160 t.Fatalf("problem writing zone %+v: %s", defaultZoneConfig, err) 161 } 162 } 163 164 // Naming scheme for database and tables: 165 // db1 has tables tb11 and tb12 166 // db2 has tables tb21 and tb22 167 168 db1 := expectedCounter 169 if _, err := sqlDB.Exec(`CREATE DATABASE db1`); err != nil { 170 t.Fatal(err) 171 } 172 173 expectedCounter++ 174 db2 := expectedCounter 175 if _, err := sqlDB.Exec(`CREATE DATABASE db2`); err != nil { 176 t.Fatal(err) 177 } 178 179 expectedCounter++ 180 tb11 := expectedCounter 181 if _, err := sqlDB.Exec(`CREATE TABLE db1.tb1 (k INT PRIMARY KEY, v INT)`); err != nil { 182 t.Fatal(err) 183 } 184 185 expectedCounter++ 186 tb12 := expectedCounter 187 if _, err := sqlDB.Exec(`CREATE TABLE db1.tb2 (k INT PRIMARY KEY, v INT)`); err != nil { 188 t.Fatal(err) 189 } 190 191 expectedCounter++ 192 tb21 := expectedCounter 193 if _, err := sqlDB.Exec(`CREATE TABLE db2.tb1 (k INT PRIMARY KEY, v INT)`); err != nil { 194 t.Fatal(err) 195 } 196 197 expectedCounter++ 198 if _, err := sqlDB.Exec(`CREATE TABLE db2.tb2 (k INT PRIMARY KEY, v INT)`); err != nil { 199 t.Fatal(err) 200 } 201 202 expectedCounter++ 203 tb22 := expectedCounter 204 if _, err := sqlDB.Exec(`TRUNCATE TABLE db2.tb2`); err != nil { 205 t.Fatal(err) 206 } 207 208 // We have no custom zone configs. 209 verifyZoneConfigs([]testCase{ 210 {0, nil, "", defaultZoneConfig}, 211 {1, nil, "", defaultZoneConfig}, 212 {keys.MaxReservedDescID, nil, "", defaultZoneConfig}, 213 {db1, nil, "", defaultZoneConfig}, 214 {db2, nil, "", defaultZoneConfig}, 215 {tb11, nil, "", defaultZoneConfig}, 216 {tb11, []byte{42}, "p0", defaultZoneConfig}, 217 {tb12, nil, "", defaultZoneConfig}, 218 {tb12, []byte{42}, "p0", defaultZoneConfig}, 219 {tb21, nil, "", defaultZoneConfig}, 220 {tb22, nil, "", defaultZoneConfig}, 221 }) 222 223 // Now set some zone configs. We don't have a nice way of using table 224 // names for this, so we do raw puts. 225 // Here is the list of dbs/tables/partitions and whether they have a custom 226 // zone config: 227 // db1: true 228 // tb1: true 229 // tb2: false 230 // db2: false 231 // tb1: true 232 // p1: true [1, 2), [6, 7) 233 // p2: true [3, 5) 234 // tb2: false 235 // p1: true [1, 255) 236 237 db1Cfg := defaultZoneConfig 238 db1Cfg.NumReplicas = proto.Int32(1) 239 db1Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1"}}}} 240 241 tb11Cfg := defaultZoneConfig 242 tb11Cfg.NumReplicas = proto.Int32(1) 243 tb11Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1.tb1"}}}} 244 245 p211Cfg := defaultZoneConfig 246 p211Cfg.NumReplicas = proto.Int32(1) 247 p211Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p1"}}}} 248 249 p212Cfg := defaultZoneConfig 250 p212Cfg.NumReplicas = proto.Int32(1) 251 p212Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p2"}}}} 252 253 tb21Cfg := defaultZoneConfig 254 tb21Cfg.NumReplicas = proto.Int32(1) 255 tb21Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1"}}}} 256 tb21Cfg.Subzones = []zonepb.Subzone{ 257 {PartitionName: "p0", Config: p211Cfg}, 258 {PartitionName: "p1", Config: p212Cfg}, 259 } 260 tb21Cfg.SubzoneSpans = []zonepb.SubzoneSpan{ 261 {SubzoneIndex: 0, Key: []byte{1}}, 262 {SubzoneIndex: 1, Key: []byte{3}, EndKey: []byte{5}}, 263 {SubzoneIndex: 0, Key: []byte{6}}, 264 } 265 266 p221Cfg := defaultZoneConfig 267 p221Cfg.NumReplicas = proto.Int32(1) 268 p221Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb2.p1"}}}} 269 270 // Subzone Placeholder 271 tb22Cfg := *zonepb.NewZoneConfig() 272 tb22Cfg.NumReplicas = proto.Int32(0) 273 tb22Cfg.Subzones = []zonepb.Subzone{{PartitionName: "p0", Config: p221Cfg}} 274 tb22Cfg.SubzoneSpans = []zonepb.SubzoneSpan{ 275 {SubzoneIndex: 0, Key: []byte{1}, EndKey: []byte{255}}, 276 } 277 278 for objID, objZone := range map[uint32]zonepb.ZoneConfig{ 279 db1: db1Cfg, 280 tb11: tb11Cfg, 281 tb21: tb21Cfg, 282 tb22: tb22Cfg, 283 } { 284 buf, err := protoutil.Marshal(&objZone) 285 if err != nil { 286 t.Fatal(err) 287 } 288 if _, err = sqlDB.Exec(`INSERT INTO system.zones VALUES ($1, $2)`, objID, buf); err != nil { 289 t.Fatalf("problem writing zone %+v: %s", objZone, err) 290 } 291 } 292 293 verifyZoneConfigs([]testCase{ 294 {0, nil, "", defaultZoneConfig}, 295 {1, nil, "", defaultZoneConfig}, 296 {keys.MaxReservedDescID, nil, "", defaultZoneConfig}, 297 {db1, nil, "", db1Cfg}, 298 {db2, nil, "", defaultZoneConfig}, 299 {tb11, nil, "", tb11Cfg}, 300 {tb11, []byte{42}, "p0", tb11Cfg}, 301 {tb12, nil, "", db1Cfg}, 302 {tb12, []byte{42}, "p0", db1Cfg}, 303 {tb21, nil, "", tb21Cfg}, 304 {tb21, []byte{}, "", tb21Cfg}, 305 {tb21, []byte{0}, "", tb21Cfg}, 306 {tb21, []byte{1}, "p0", p211Cfg}, 307 {tb21, []byte{1, 255}, "p0", p211Cfg}, 308 {tb21, []byte{2}, "", tb21Cfg}, 309 {tb21, []byte{3}, "p1", p212Cfg}, 310 {tb21, []byte{4}, "p1", p212Cfg}, 311 {tb21, []byte{5}, "", tb21Cfg}, 312 {tb21, []byte{6}, "p0", p211Cfg}, 313 {tb22, nil, "", defaultZoneConfig}, 314 {tb22, []byte{0}, "", defaultZoneConfig}, 315 {tb22, []byte{1}, "p0", p221Cfg}, 316 {tb22, []byte{255}, "", defaultZoneConfig}, 317 }) 318 } 319 320 // TestCascadingZoneConfig tests whether the cascading nature of 321 // the zone configurations works well with the different inheritance 322 // hierarchies. 323 func TestCascadingZoneConfig(t *testing.T) { 324 defer leaktest.AfterTest(t)() 325 params, _ := tests.CreateTestServerParams() 326 327 defaultZoneConfig := zonepb.DefaultZoneConfig() 328 defaultZoneConfig.NumReplicas = proto.Int32(1) 329 defaultZoneConfig.RangeMinBytes = proto.Int64(1 << 20) 330 defaultZoneConfig.RangeMaxBytes = proto.Int64(1 << 21) 331 defaultZoneConfig.GC = &zonepb.GCPolicy{TTLSeconds: 60} 332 require.NoError(t, defaultZoneConfig.Validate()) 333 params.Knobs.Server = &server.TestingKnobs{ 334 DefaultZoneConfigOverride: &defaultZoneConfig, 335 DefaultSystemZoneConfigOverride: &defaultZoneConfig, 336 } 337 338 srv, sqlDB, _ := serverutils.StartServer(t, params) 339 defer srv.Stopper().Stop(context.Background()) 340 s := srv.(*server.TestServer) 341 342 expectedCounter := uint32(keys.MinNonPredefinedUserDescID) 343 344 type testCase struct { 345 objectID uint32 346 347 // keySuffix and partitionName must specify the same subzone. 348 keySuffix []byte 349 partitionName string 350 351 zoneCfg zonepb.ZoneConfig 352 } 353 verifyZoneConfigs := func(testCases []testCase) { 354 cfg := forceNewConfig(t, s) 355 356 for tcNum, tc := range testCases { 357 // Verify SystemConfig.GetZoneConfigForKey. 358 { 359 key := append(roachpb.RKey(keys.SystemSQLCodec.TablePrefix(tc.objectID)), tc.keySuffix...) 360 zoneCfg, err := cfg.GetZoneConfigForKey(key) // Complete ZoneConfig 361 if err != nil { 362 t.Fatalf("#%d: err=%s", tcNum, err) 363 } 364 365 if !tc.zoneCfg.Equal(zoneCfg) { 366 t.Errorf("#%d: bad zone config.\nexpected: %+v\ngot: %+v", tcNum, &tc.zoneCfg, zoneCfg) 367 } 368 } 369 370 // Verify sql.GetZoneConfigInTxn. 371 if err := s.DB().Txn(context.Background(), func(ctx context.Context, txn *kv.Txn) error { 372 _, zoneCfg, subzone, err := sql.GetZoneConfigInTxn(ctx, txn, 373 tc.objectID, &sqlbase.IndexDescriptor{}, tc.partitionName, false) 374 if err != nil { 375 return err 376 } else if subzone != nil { 377 zoneCfg = &subzone.Config 378 } 379 if !tc.zoneCfg.Equal(zoneCfg) { 380 t.Errorf("#%d: bad zone config.\nexpected: %+v\ngot: %+v", tcNum, &tc.zoneCfg, zoneCfg) 381 } 382 return nil 383 }); err != nil { 384 t.Fatalf("#%d: err=%s", tcNum, err) 385 } 386 } 387 } 388 389 { 390 buf, err := protoutil.Marshal(&defaultZoneConfig) 391 if err != nil { 392 t.Fatal(err) 393 } 394 objID := keys.RootNamespaceID 395 if _, err = sqlDB.Exec(`UPDATE system.zones SET config = $2 WHERE id = $1`, objID, buf); err != nil { 396 t.Fatalf("problem writing zone %+v: %s", defaultZoneConfig, err) 397 } 398 } 399 400 // Naming scheme for database and tables: 401 // db1 has tables tb11 and tb12 402 // db2 has tables tb21 and tb22 403 404 db1 := expectedCounter 405 if _, err := sqlDB.Exec(`CREATE DATABASE db1`); err != nil { 406 t.Fatal(err) 407 } 408 409 expectedCounter++ 410 db2 := expectedCounter 411 if _, err := sqlDB.Exec(`CREATE DATABASE db2`); err != nil { 412 t.Fatal(err) 413 } 414 415 expectedCounter++ 416 tb11 := expectedCounter 417 if _, err := sqlDB.Exec(`CREATE TABLE db1.tb1 (k INT PRIMARY KEY, v INT)`); err != nil { 418 t.Fatal(err) 419 } 420 421 expectedCounter++ 422 tb12 := expectedCounter 423 if _, err := sqlDB.Exec(`CREATE TABLE db1.tb2 (k INT PRIMARY KEY, v INT)`); err != nil { 424 t.Fatal(err) 425 } 426 427 expectedCounter++ 428 tb21 := expectedCounter 429 if _, err := sqlDB.Exec(`CREATE TABLE db2.tb1 (k INT PRIMARY KEY, v INT)`); err != nil { 430 t.Fatal(err) 431 } 432 433 expectedCounter++ 434 if _, err := sqlDB.Exec(`CREATE TABLE db2.tb2 (k INT PRIMARY KEY, v INT)`); err != nil { 435 t.Fatal(err) 436 } 437 438 expectedCounter++ 439 tb22 := expectedCounter 440 if _, err := sqlDB.Exec(`TRUNCATE TABLE db2.tb2`); err != nil { 441 t.Fatal(err) 442 } 443 444 // We have no custom zone configs. 445 verifyZoneConfigs([]testCase{ 446 {0, nil, "", defaultZoneConfig}, 447 {1, nil, "", defaultZoneConfig}, 448 {keys.MaxReservedDescID, nil, "", defaultZoneConfig}, 449 {db1, nil, "", defaultZoneConfig}, 450 {db2, nil, "", defaultZoneConfig}, 451 {tb11, nil, "", defaultZoneConfig}, 452 {tb11, []byte{42}, "p0", defaultZoneConfig}, 453 {tb12, nil, "", defaultZoneConfig}, 454 {tb12, []byte{42}, "p0", defaultZoneConfig}, 455 {tb21, nil, "", defaultZoneConfig}, 456 {tb22, nil, "", defaultZoneConfig}, 457 }) 458 459 // Now set some zone configs. We don't have a nice way of using table 460 // names for this, so we do raw puts. 461 // .default: has replciation factor of 1 462 // db1: has replication factor of 5 463 // tb1: inherits replication factor from db1 464 // tb2: no zone config 465 // db2: no zone config 466 // tb1: inherits replication factor from default 467 // p1: true [1, 2), [6, 7) - Explicitly set replciation factor 468 // p2: true [3, 5) - inherits repliaction factor from default 469 // tb2: no zone config 470 // p1: true [1, 255) - inherits replciation factor from default 471 472 db1Cfg := *zonepb.NewZoneConfig() 473 db1Cfg.NumReplicas = proto.Int32(5) 474 db1Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1"}}}} 475 db1Cfg.InheritedConstraints = false 476 477 // Expected complete config 478 expectedDb1Cfg := defaultZoneConfig 479 expectedDb1Cfg.NumReplicas = proto.Int32(5) 480 expectedDb1Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1"}}}} 481 482 tb11Cfg := *zonepb.NewZoneConfig() 483 tb11Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1.tb1"}}}} 484 tb11Cfg.InheritedConstraints = false 485 486 // Expected complete config 487 expectedTb11Cfg := expectedDb1Cfg 488 expectedTb11Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db1.tb1"}}}} 489 490 p211Cfg := *zonepb.NewZoneConfig() 491 p211Cfg.NumReplicas = proto.Int32(1) 492 p211Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p1"}}}} 493 p211Cfg.InheritedConstraints = false 494 495 // Expected complete config 496 expectedP211Cfg := defaultZoneConfig 497 expectedP211Cfg.NumReplicas = proto.Int32(1) 498 expectedP211Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p1"}}}} 499 500 p212Cfg := *zonepb.NewZoneConfig() 501 p212Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p2"}}}} 502 p212Cfg.InheritedConstraints = false 503 504 // Expected complete config 505 expectedP212Cfg := defaultZoneConfig 506 expectedP212Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1.p2"}}}} 507 508 tb21Cfg := *zonepb.NewZoneConfig() 509 tb21Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1"}}}} 510 tb21Cfg.InheritedConstraints = false 511 tb21Cfg.Subzones = []zonepb.Subzone{ 512 {PartitionName: "p0", Config: p211Cfg}, 513 {PartitionName: "p1", Config: p212Cfg}, 514 } 515 tb21Cfg.SubzoneSpans = []zonepb.SubzoneSpan{ 516 {SubzoneIndex: 0, Key: []byte{1}}, 517 {SubzoneIndex: 1, Key: []byte{3}, EndKey: []byte{5}}, 518 {SubzoneIndex: 0, Key: []byte{6}}, 519 } 520 521 // Expected complete config 522 expectedTb21Cfg := defaultZoneConfig 523 expectedTb21Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb1"}}}} 524 expectedTb21Cfg.Subzones = []zonepb.Subzone{ 525 {PartitionName: "p0", Config: p211Cfg}, 526 {PartitionName: "p1", Config: p212Cfg}, 527 } 528 expectedTb21Cfg.SubzoneSpans = []zonepb.SubzoneSpan{ 529 {SubzoneIndex: 0, Key: []byte{1}}, 530 {SubzoneIndex: 1, Key: []byte{3}, EndKey: []byte{5}}, 531 {SubzoneIndex: 0, Key: []byte{6}}, 532 } 533 534 p221Cfg := *zonepb.NewZoneConfig() 535 p221Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb2.p1"}}}} 536 p221Cfg.InheritedConstraints = false 537 538 // Expected complete config 539 expectedP221Cfg := defaultZoneConfig 540 expectedP221Cfg.Constraints = []zonepb.ConstraintsConjunction{{Constraints: []zonepb.Constraint{{Value: "db2.tb2.p1"}}}} 541 542 // Subzone Placeholder 543 tb22Cfg := *zonepb.NewZoneConfig() 544 tb22Cfg.NumReplicas = proto.Int32(0) 545 tb22Cfg.Subzones = []zonepb.Subzone{{PartitionName: "p0", Config: p221Cfg}} 546 tb22Cfg.SubzoneSpans = []zonepb.SubzoneSpan{ 547 {SubzoneIndex: 0, Key: []byte{1}, EndKey: []byte{255}}, 548 } 549 550 for objID, objZone := range map[uint32]zonepb.ZoneConfig{ 551 db1: db1Cfg, 552 tb11: tb11Cfg, 553 tb21: tb21Cfg, 554 tb22: tb22Cfg, 555 } { 556 buf, err := protoutil.Marshal(&objZone) 557 if err != nil { 558 t.Fatal(err) 559 } 560 if _, err = sqlDB.Exec(`INSERT INTO system.zones VALUES ($1, $2)`, objID, buf); err != nil { 561 t.Fatalf("problem writing zone %+v: %s", objZone, err) 562 } 563 } 564 565 verifyZoneConfigs([]testCase{ 566 {0, nil, "", defaultZoneConfig}, 567 {1, nil, "", defaultZoneConfig}, 568 {keys.MaxReservedDescID, nil, "", defaultZoneConfig}, 569 {db1, nil, "", expectedDb1Cfg}, 570 {db2, nil, "", defaultZoneConfig}, 571 {tb11, nil, "", expectedTb11Cfg}, 572 {tb11, []byte{42}, "p0", expectedTb11Cfg}, 573 {tb12, nil, "", expectedDb1Cfg}, 574 {tb12, []byte{42}, "p0", expectedDb1Cfg}, 575 {tb21, nil, "", expectedTb21Cfg}, 576 {tb21, []byte{}, "", expectedTb21Cfg}, 577 {tb21, []byte{0}, "", expectedTb21Cfg}, 578 {tb21, []byte{1}, "p0", expectedP211Cfg}, 579 {tb21, []byte{1, 255}, "p0", expectedP211Cfg}, 580 {tb21, []byte{2}, "", expectedTb21Cfg}, 581 {tb21, []byte{3}, "p1", expectedP212Cfg}, 582 {tb21, []byte{4}, "p1", expectedP212Cfg}, 583 {tb21, []byte{5}, "", expectedTb21Cfg}, 584 {tb21, []byte{6}, "p0", expectedP211Cfg}, 585 {tb22, nil, "", defaultZoneConfig}, 586 {tb22, []byte{0}, "", defaultZoneConfig}, 587 {tb22, []byte{1}, "p0", expectedP221Cfg}, 588 {tb22, []byte{255}, "", defaultZoneConfig}, 589 }) 590 591 // Change the default. 592 defaultZoneConfig.NumReplicas = proto.Int32(5) 593 594 buf, err := protoutil.Marshal(&defaultZoneConfig) 595 if err != nil { 596 t.Fatal(err) 597 } 598 objID := keys.RootNamespaceID 599 if _, err = sqlDB.Exec(`UPDATE system.zones SET config = $2 WHERE id = $1`, objID, buf); err != nil { 600 t.Fatalf("problem writing zone %+v: %s", defaultZoneConfig, err) 601 } 602 603 // Ensure the changes cascade down. 604 expectedTb21Cfg.NumReplicas = proto.Int32(5) 605 expectedP212Cfg.NumReplicas = proto.Int32(5) 606 expectedP221Cfg.NumReplicas = proto.Int32(5) 607 608 verifyZoneConfigs([]testCase{ 609 // TODO(ridwanmsharif): Figure out what these 3 are supposed to do. 610 // {0, nil, "", defaultZoneConfig}, 611 // {1, nil, "", cfg}, 612 // {keys.MaxReservedDescID, nil, "", defaultZoneConfig}, 613 {db1, nil, "", expectedDb1Cfg}, 614 {db2, nil, "", defaultZoneConfig}, 615 {tb11, nil, "", expectedTb11Cfg}, 616 {tb11, []byte{42}, "p0", expectedTb11Cfg}, 617 {tb12, nil, "", expectedDb1Cfg}, 618 {tb12, []byte{42}, "p0", expectedDb1Cfg}, 619 {tb21, nil, "", expectedTb21Cfg}, 620 {tb21, []byte{}, "", expectedTb21Cfg}, 621 {tb21, []byte{0}, "", expectedTb21Cfg}, 622 {tb21, []byte{1}, "p0", expectedP211Cfg}, 623 {tb21, []byte{1, 255}, "p0", expectedP211Cfg}, 624 {tb21, []byte{2}, "", expectedTb21Cfg}, 625 {tb21, []byte{3}, "p1", expectedP212Cfg}, 626 {tb21, []byte{4}, "p1", expectedP212Cfg}, 627 {tb21, []byte{5}, "", expectedTb21Cfg}, 628 {tb21, []byte{6}, "p0", expectedP211Cfg}, 629 {tb22, nil, "", defaultZoneConfig}, 630 {tb22, []byte{0}, "", defaultZoneConfig}, 631 {tb22, []byte{1}, "p0", expectedP221Cfg}, 632 {tb22, []byte{255}, "", defaultZoneConfig}, 633 }) 634 } 635 636 func BenchmarkGetZoneConfig(b *testing.B) { 637 defer leaktest.AfterTest(b)() 638 639 params, _ := tests.CreateTestServerParams() 640 srv, _, _ := serverutils.StartServer(b, params) 641 defer srv.Stopper().Stop(context.Background()) 642 s := srv.(*server.TestServer) 643 cfg := forceNewConfig(b, s) 644 645 b.ResetTimer() 646 for i := 0; i < b.N; i++ { 647 key := roachpb.RKey(keys.SystemSQLCodec.TablePrefix(keys.MinUserDescID)) 648 _, err := cfg.GetZoneConfigForKey(key) 649 if err != nil { 650 b.Fatal(err) 651 } 652 } 653 b.StopTimer() 654 }