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  }