github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/cmd/roachtest/secondary_indexes.go (about) 1 // Copyright 2019 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 main 12 13 import ( 14 "context" 15 gosql "database/sql" 16 "runtime" 17 18 "github.com/cockroachdb/cockroach/pkg/util/binfetcher" 19 "github.com/stretchr/testify/require" 20 ) 21 22 func registerSecondaryIndexesMultiVersionCluster(r *testRegistry) { 23 runTest := func(ctx context.Context, t *test, c *cluster) { 24 // Start a 3 node 19.2 cluster. 25 goos := ifLocal(runtime.GOOS, "linux") 26 b, err := binfetcher.Download(ctx, binfetcher.Options{ 27 Binary: "cockroach", 28 Version: "v19.2.2", 29 GOOS: goos, 30 GOARCH: "amd64", 31 }) 32 if err != nil { 33 t.Fatal(err) 34 } 35 c.Put(ctx, b, "./cockroach", c.All()) 36 c.Start(ctx, t, c.All()) 37 // Create a table with some data, and a secondary index. 38 conn := c.Conn(ctx, 1) 39 if _, err := conn.Exec(` 40 CREATE TABLE t ( 41 x INT PRIMARY KEY, y INT, z INT, w INT, 42 INDEX i (y) STORING (z, w), 43 FAMILY (x), FAMILY (y), FAMILY (z), FAMILY (w) 44 ); 45 INSERT INTO t VALUES (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12); 46 `); err != nil { 47 t.Fatal(err) 48 } 49 t.Status("created sample data") 50 51 upgradeNode := func(node int) { 52 if err := c.StopCockroachGracefullyOnNode(ctx, node); err != nil { 53 t.Fatal(err) 54 } 55 c.Put(ctx, cockroach, "./cockroach", c.Node(node)) 56 c.Start(ctx, t, c.Node(node)) 57 } 58 59 // Upgrade one of the nodes to the current cockroach version. 60 upgradeNode(1) 61 t.Status("done upgrading node 1") 62 63 // Get a connection to the new node and ensure that we can read the index fine, and 64 // an insert in the mixed cluster setting doesn't result in unreadable data. 65 conn = c.Conn(ctx, 1) 66 if _, err := conn.Exec(`INSERT INTO t VALUES (13, 14, 15, 16)`); err != nil { 67 t.Fatal(err) 68 } 69 if _, err := conn.Exec(`UPDATE t SET w = 17 WHERE y = 14`); err != nil { 70 t.Fatal(err) 71 } 72 verifyTable := func(conn *gosql.DB, expected [][]int) { 73 rows, err := conn.Query(`SELECT y, z, w FROM t@i ORDER BY y`) 74 if err != nil { 75 t.Fatal(err) 76 } 77 var y, z, w int 78 count := 0 79 for ; rows.Next(); count++ { 80 if err := rows.Scan(&y, &z, &w); err != nil { 81 t.Fatal(err) 82 } 83 found := []int{y, z, w} 84 require.Equal(t, found, expected[count]) 85 } 86 } 87 expected := [][]int{ 88 {2, 3, 4}, 89 {6, 7, 8}, 90 {10, 11, 12}, 91 {14, 15, 17}, 92 } 93 for i := 1; i <= c.spec.NodeCount; i++ { 94 verifyTable(c.Conn(ctx, i), expected) 95 } 96 t.Status("mixed version cluster passed test") 97 98 // Fully upgrade the cluster and ensure that the data is still valid. 99 for i := 2; i <= c.spec.NodeCount; i++ { 100 upgradeNode(i) 101 } 102 103 conn = c.Conn(ctx, 1) 104 105 if _, err := conn.Exec(`INSERT INTO t VALUES (20, 21, 22, 23)`); err != nil { 106 t.Fatal(err) 107 } 108 if _, err := conn.Exec(`UPDATE t SET w = 25, z = 25 WHERE y = 21`); err != nil { 109 t.Fatal(err) 110 } 111 112 expected = [][]int{ 113 {2, 3, 4}, 114 {6, 7, 8}, 115 {10, 11, 12}, 116 {14, 15, 17}, 117 {21, 25, 25}, 118 } 119 for i := 1; i <= c.spec.NodeCount; i++ { 120 verifyTable(c.Conn(ctx, i), expected) 121 } 122 t.Status("passed on fully upgraded cluster") 123 } 124 r.Add(testSpec{ 125 Name: "secondary-index-multi-version", 126 Owner: OwnerSQLExec, 127 Cluster: makeClusterSpec(3), 128 MinVersion: "v20.1.0", 129 Run: runTest, 130 }) 131 }