github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ccl/backupccl/bench_test.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Licensed as a CockroachDB Enterprise file under the Cockroach Community 4 // License (the "License"); you may not use this file except in compliance with 5 // the License. You may obtain a copy of the License at 6 // 7 // https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt 8 9 package backupccl_test 10 11 import ( 12 "bytes" 13 gosql "database/sql" 14 "fmt" 15 "io" 16 "path/filepath" 17 "strings" 18 "testing" 19 20 "github.com/cockroachdb/cockroach/pkg/ccl/importccl" 21 "github.com/cockroachdb/cockroach/pkg/ccl/utilccl/sampledataccl" 22 "github.com/cockroachdb/cockroach/pkg/util/hlc" 23 "github.com/cockroachdb/cockroach/pkg/workload/bank" 24 "github.com/cockroachdb/cockroach/pkg/workload/workloadsql" 25 ) 26 27 func bankBuf(numAccounts int) *bytes.Buffer { 28 bankData := bank.FromRows(numAccounts).Tables()[0] 29 var buf bytes.Buffer 30 fmt.Fprintf(&buf, "CREATE TABLE %s %s;\n", bankData.Name, bankData.Schema) 31 for rowIdx := 0; rowIdx < bankData.InitialRows.NumBatches; rowIdx++ { 32 for _, row := range bankData.InitialRows.BatchRows(rowIdx) { 33 rowBatch := strings.Join(workloadsql.StringTuple(row), `,`) 34 fmt.Fprintf(&buf, "INSERT INTO %s VALUES (%s);\n", bankData.Name, rowBatch) 35 } 36 } 37 return &buf 38 } 39 40 func BenchmarkClusterBackup(b *testing.B) { 41 if testing.Short() { 42 b.Skip("TODO: fix benchmark") 43 } 44 // NB: This benchmark takes liberties in how b.N is used compared to the go 45 // documentation's description. We're getting useful information out of it, 46 // but this is not a pattern to cargo-cult. 47 48 _, _, sqlDB, dir, cleanupFn := backupRestoreTestSetup(b, multiNode, 0, initNone) 49 defer cleanupFn() 50 sqlDB.Exec(b, `DROP TABLE data.bank`) 51 52 bankData := bank.FromRows(b.N).Tables()[0] 53 loadDir := filepath.Join(dir, "load") 54 if _, err := sampledataccl.ToBackup(b, bankData, loadDir); err != nil { 55 b.Fatalf("%+v", err) 56 } 57 sqlDB.Exec(b, fmt.Sprintf(`RESTORE data.* FROM '%s'`, loadDir)) 58 59 // TODO(dan): Ideally, this would split and rebalance the ranges in a more 60 // controlled way. A previous version of this code did it manually with 61 // `SPLIT AT` and TestCluster's TransferRangeLease, but it seemed to still 62 // be doing work after returning, which threw off the timing and the results 63 // of the benchmark. DistSQL is working on improving this infrastructure, so 64 // use what they build. 65 66 b.ResetTimer() 67 var unused string 68 var dataSize int64 69 sqlDB.QueryRow(b, fmt.Sprintf(`BACKUP DATABASE data TO '%s'`, dir)).Scan( 70 &unused, &unused, &unused, &unused, &unused, &unused, &dataSize, 71 ) 72 b.StopTimer() 73 b.SetBytes(dataSize / int64(b.N)) 74 } 75 76 func BenchmarkClusterRestore(b *testing.B) { 77 // NB: This benchmark takes liberties in how b.N is used compared to the go 78 // documentation's description. We're getting useful information out of it, 79 // but this is not a pattern to cargo-cult. 80 81 _, _, sqlDB, dir, cleanup := backupRestoreTestSetup(b, multiNode, 0, initNone) 82 defer cleanup() 83 sqlDB.Exec(b, `DROP TABLE data.bank`) 84 85 bankData := bank.FromRows(b.N).Tables()[0] 86 backup, err := sampledataccl.ToBackup(b, bankData, filepath.Join(dir, "foo")) 87 if err != nil { 88 b.Fatalf("%+v", err) 89 } 90 b.SetBytes(backup.Desc.EntryCounts.DataSize / int64(b.N)) 91 92 b.ResetTimer() 93 sqlDB.Exec(b, `RESTORE data.* FROM 'nodelocal://0/foo'`) 94 b.StopTimer() 95 } 96 97 func BenchmarkLoadRestore(b *testing.B) { 98 if testing.Short() { 99 b.Skip("TODO: fix benchmark") 100 } 101 // NB: This benchmark takes liberties in how b.N is used compared to the go 102 // documentation's description. We're getting useful information out of it, 103 // but this is not a pattern to cargo-cult. 104 105 ctx, _, sqlDB, dir, cleanup := backupRestoreTestSetup(b, multiNode, 0, initNone) 106 defer cleanup() 107 sqlDB.Exec(b, `DROP TABLE data.bank`) 108 109 buf := bankBuf(b.N) 110 b.SetBytes(int64(buf.Len() / b.N)) 111 ts := hlc.Timestamp{WallTime: hlc.UnixNano()} 112 b.ResetTimer() 113 if _, err := importccl.Load(ctx, sqlDB.DB.(*gosql.DB), buf, "data", dir, ts, 0, dir, dir); err != nil { 114 b.Fatalf("%+v", err) 115 } 116 sqlDB.Exec(b, fmt.Sprintf(`RESTORE data.* FROM '%s'`, dir)) 117 b.StopTimer() 118 } 119 120 func BenchmarkLoadSQL(b *testing.B) { 121 // NB: This benchmark takes liberties in how b.N is used compared to the go 122 // documentation's description. We're getting useful information out of it, 123 // but this is not a pattern to cargo-cult. 124 _, _, sqlDB, _, cleanup := backupRestoreTestSetup(b, multiNode, 0, initNone) 125 defer cleanup() 126 sqlDB.Exec(b, `DROP TABLE data.bank`) 127 128 buf := bankBuf(b.N) 129 b.SetBytes(int64(buf.Len() / b.N)) 130 lines := make([]string, 0, b.N) 131 for { 132 line, err := buf.ReadString(';') 133 if err == io.EOF { 134 break 135 } else if err != nil { 136 b.Fatalf("%+v", err) 137 } 138 lines = append(lines, line) 139 } 140 141 b.ResetTimer() 142 for _, line := range lines { 143 sqlDB.Exec(b, line) 144 } 145 b.StopTimer() 146 } 147 148 func BenchmarkClusterEmptyIncrementalBackup(b *testing.B) { 149 if testing.Short() { 150 b.Skip("TODO: fix benchmark") 151 } 152 const numStatements = 100000 153 154 _, _, sqlDB, _, cleanupFn := backupRestoreTestSetup(b, multiNode, 0, initNone) 155 defer cleanupFn() 156 157 restoreDir := filepath.Join(localFoo, "restore") 158 fullDir := filepath.Join(localFoo, "full") 159 160 bankData := bank.FromRows(numStatements).Tables()[0] 161 _, err := sampledataccl.ToBackup(b, bankData, restoreDir) 162 if err != nil { 163 b.Fatalf("%+v", err) 164 } 165 sqlDB.Exec(b, `DROP TABLE data.bank`) 166 sqlDB.Exec(b, `RESTORE data.* FROM $1`, restoreDir) 167 168 var unused string 169 var dataSize int64 170 sqlDB.QueryRow(b, `BACKUP DATABASE data TO $1`, fullDir).Scan( 171 &unused, &unused, &unused, &unused, &unused, &unused, &dataSize, 172 ) 173 174 // We intentionally don't write anything to the database between the full and 175 // incremental backup. 176 177 b.ResetTimer() 178 for i := 0; i < b.N; i++ { 179 incrementalDir := filepath.Join(localFoo, fmt.Sprintf("incremental%d", i)) 180 sqlDB.Exec(b, `BACKUP DATABASE data TO $1 INCREMENTAL FROM $2`, incrementalDir, fullDir) 181 } 182 b.StopTimer() 183 184 // We report the number of bytes that incremental backup was able to 185 // *skip*--i.e., the number of bytes in the full backup. 186 b.SetBytes(int64(b.N) * dataSize) 187 }