github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/scatter_test.go (about) 1 // Copyright 2018 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 "fmt" 16 "reflect" 17 "testing" 18 19 "github.com/cockroachdb/cockroach/pkg/base" 20 "github.com/cockroachdb/cockroach/pkg/keys" 21 "github.com/cockroachdb/cockroach/pkg/roachpb" 22 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 23 "github.com/cockroachdb/cockroach/pkg/testutils" 24 "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" 25 "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" 26 "github.com/cockroachdb/cockroach/pkg/util" 27 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 28 ) 29 30 func TestScatterRandomizeLeases(t *testing.T) { 31 defer leaktest.AfterTest(t)() 32 33 if testutils.NightlyStress() && util.RaceEnabled { 34 t.Skip("uses too many resources for stressrace") 35 } 36 37 const numHosts = 3 38 39 tc := serverutils.StartTestCluster(t, numHosts, base.TestClusterArgs{}) 40 defer tc.Stopper().Stop(context.Background()) 41 42 sqlutils.CreateTable( 43 t, tc.ServerConn(0), "t", 44 "k INT PRIMARY KEY, v INT", 45 1000, 46 sqlutils.ToRowFn(sqlutils.RowIdxFn, sqlutils.RowModuloFn(10)), 47 ) 48 49 r := sqlutils.MakeSQLRunner(tc.ServerConn(0)) 50 51 // Even though we disabled merges via the store testing knob, we must also 52 // disable the setting in order for manual splits to be allowed. 53 r.Exec(t, "SET CLUSTER SETTING kv.range_merge.queue_enabled = false") 54 55 // Introduce 99 splits to get 100 ranges. 56 r.Exec(t, "ALTER TABLE test.t SPLIT AT (SELECT i*10 FROM generate_series(1, 99) AS g(i))") 57 58 getLeaseholders := func() (map[int]int, error) { 59 rows := r.Query(t, `SELECT range_id, lease_holder FROM [SHOW RANGES FROM TABLE test.t]`) 60 leaseholders := make(map[int]int) 61 numRows := 0 62 for ; rows.Next(); numRows++ { 63 var rangeID, leaseholder int 64 if err := rows.Scan(&rangeID, &leaseholder); err != nil { 65 return nil, err 66 } 67 if rangeID < 1 { 68 t.Fatalf("invalid rangeID: %d", rangeID) 69 } 70 if leaseholder < 1 || leaseholder > numHosts { 71 return nil, fmt.Errorf("invalid lease_holder value: %d", leaseholder) 72 } 73 leaseholders[rangeID] = leaseholder 74 } 75 if err := rows.Err(); err != nil { 76 return nil, err 77 } 78 if numRows != 100 { 79 return nil, fmt.Errorf("expected 100 ranges, got %d", numRows) 80 } 81 return leaseholders, nil 82 } 83 84 oldLeaseholders, err := getLeaseholders() 85 if err != nil { 86 t.Fatal(err) 87 } 88 89 for i := 0; i < 10; i++ { 90 // Ensure that scattering changes the leaseholders, which is really all 91 // that randomizing the lease placements can probabilistically guarantee - 92 // it doesn't guarantee a uniform distribution. 93 r.Exec(t, "ALTER TABLE test.t SCATTER") 94 newLeaseholders, err := getLeaseholders() 95 if err != nil { 96 t.Fatal(err) 97 } 98 if reflect.DeepEqual(oldLeaseholders, newLeaseholders) { 99 t.Errorf("expected scatter to change lease distribution, but got no change: %v", newLeaseholders) 100 } 101 oldLeaseholders = newLeaseholders 102 } 103 } 104 105 // TestScatterResponse ensures that ALTER TABLE... SCATTER includes one row of 106 // output per range in the table. It does *not* test that scatter properly 107 // distributes replicas and leases; see TestScatter for that. 108 // 109 // TODO(benesch): consider folding this test into TestScatter once TestScatter 110 // is unskipped. 111 func TestScatterResponse(t *testing.T) { 112 defer leaktest.AfterTest(t)() 113 114 s, sqlDB, kvDB := serverutils.StartServer(t, base.TestServerArgs{}) 115 defer s.Stopper().Stop(context.Background()) 116 117 sqlutils.CreateTable( 118 t, sqlDB, "t", 119 "k INT PRIMARY KEY, v INT", 120 1000, 121 sqlutils.ToRowFn(sqlutils.RowIdxFn, sqlutils.RowModuloFn(10)), 122 ) 123 tableDesc := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "test", "t") 124 125 r := sqlutils.MakeSQLRunner(sqlDB) 126 r.Exec(t, "ALTER TABLE test.t SPLIT AT (SELECT i*10 FROM generate_series(1, 99) AS g(i))") 127 rows := r.Query(t, "ALTER TABLE test.t SCATTER") 128 129 i := 0 130 for ; rows.Next(); i++ { 131 var actualKey []byte 132 var pretty string 133 if err := rows.Scan(&actualKey, &pretty); err != nil { 134 t.Fatal(err) 135 } 136 var expectedKey roachpb.Key 137 if i == 0 { 138 expectedKey = keys.SystemSQLCodec.TablePrefix(uint32(tableDesc.ID)) 139 } else { 140 var err error 141 expectedKey, err = sqlbase.TestingMakePrimaryIndexKey(tableDesc, i*10) 142 if err != nil { 143 t.Fatal(err) 144 } 145 } 146 if e, a := expectedKey, roachpb.Key(actualKey); !e.Equal(a) { 147 t.Errorf("%d: expected split key %s, but got %s", i, e, a) 148 } 149 if e, a := expectedKey.String(), pretty; e != a { 150 t.Errorf("%d: expected pretty split key %s, but got %s", i, e, a) 151 } 152 } 153 if err := rows.Err(); err != nil { 154 t.Fatal(err) 155 } 156 if e, a := 100, i; e != a { 157 t.Fatalf("expected %d rows, but got %d", e, a) 158 } 159 }