github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/metric_test.go (about) 1 // Copyright 2016 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 "bytes" 15 "context" 16 "regexp" 17 "testing" 18 19 "github.com/cockroachdb/cockroach/pkg/base" 20 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/kvserverbase" 21 "github.com/cockroachdb/cockroach/pkg/roachpb" 22 "github.com/cockroachdb/cockroach/pkg/sql" 23 "github.com/cockroachdb/cockroach/pkg/sql/catalog/lease" 24 "github.com/cockroachdb/cockroach/pkg/sql/tests" 25 "github.com/cockroachdb/cockroach/pkg/testutils" 26 "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" 27 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 28 ) 29 30 type queryCounter struct { 31 query string 32 expectError bool 33 txnBeginCount int64 34 selectCount int64 35 selectExecutedCount int64 36 distSQLSelectCount int64 37 fallbackCount int64 38 updateCount int64 39 insertCount int64 40 deleteCount int64 41 ddlCount int64 42 miscCount int64 43 miscExecutedCount int64 44 failureCount int64 45 txnCommitCount int64 46 txnRollbackCount int64 47 txnAbortCount int64 48 savepointCount int64 49 restartSavepointCount int64 50 releaseRestartSavepointCount int64 51 rollbackToRestartSavepointCount int64 52 } 53 54 func TestQueryCounts(t *testing.T) { 55 defer leaktest.AfterTest(t)() 56 57 params, _ := tests.CreateTestServerParams() 58 params.Knobs = base.TestingKnobs{ 59 SQLLeaseManager: &lease.ManagerTestingKnobs{ 60 // Disable SELECT called for delete orphaned leases to keep 61 // query stats stable. 62 DisableDeleteOrphanedLeases: true, 63 }, 64 } 65 s, sqlDB, _ := serverutils.StartServer(t, params) 66 defer s.Stopper().Stop(context.Background()) 67 68 var testcases = []queryCounter{ 69 // The counts are deltas for each query. 70 {query: "SET DISTSQL = 'off'", miscCount: 1, miscExecutedCount: 1}, 71 {query: "BEGIN; END", txnBeginCount: 1, txnCommitCount: 1}, 72 {query: "SELECT 1", selectCount: 1, selectExecutedCount: 1, txnCommitCount: 1}, 73 {query: "CREATE DATABASE mt", ddlCount: 1}, 74 {query: "CREATE TABLE mt.n (num INTEGER PRIMARY KEY)", ddlCount: 1}, 75 {query: "INSERT INTO mt.n VALUES (3)", insertCount: 1}, 76 // Test failure (uniqueness violation). 77 {query: "INSERT INTO mt.n VALUES (3)", failureCount: 1, insertCount: 1, expectError: true}, 78 // Test failure (planning error). 79 { 80 query: "INSERT INTO nonexistent VALUES (3)", 81 failureCount: 1, insertCount: 1, expectError: true, 82 }, 83 {query: "UPDATE mt.n SET num = num + 1", updateCount: 1}, 84 {query: "DELETE FROM mt.n", deleteCount: 1}, 85 {query: "ALTER TABLE mt.n ADD COLUMN num2 INTEGER", ddlCount: 1}, 86 {query: "EXPLAIN SELECT * FROM mt.n", miscCount: 1, miscExecutedCount: 1}, 87 { 88 query: "BEGIN; UPDATE mt.n SET num = num + 1; END", 89 txnBeginCount: 1, updateCount: 1, txnCommitCount: 1, 90 }, 91 { 92 query: "SELECT * FROM mt.n; SELECT * FROM mt.n; SELECT * FROM mt.n", 93 selectCount: 3, selectExecutedCount: 3, 94 }, 95 {query: "SET DISTSQL = 'on'", miscCount: 1, miscExecutedCount: 1}, 96 { 97 query: "SELECT * FROM mt.n", 98 selectCount: 1, selectExecutedCount: 1, distSQLSelectCount: 1, 99 }, 100 {query: "SET DISTSQL = 'off'", miscCount: 1, miscExecutedCount: 1}, 101 {query: "DROP TABLE mt.n", ddlCount: 1}, 102 {query: "SET database = system", miscCount: 1, miscExecutedCount: 1}, 103 {query: "SELECT 3", selectCount: 1, selectExecutedCount: 1}, 104 {query: "CREATE TABLE mt.n (num INTEGER PRIMARY KEY)", ddlCount: 1}, 105 {query: "UPDATE mt.n SET num = num + 1", updateCount: 1}, 106 } 107 108 accum := initializeQueryCounter(s) 109 110 for _, tc := range testcases { 111 t.Run(tc.query, func(t *testing.T) { 112 if _, err := sqlDB.Exec(tc.query); err != nil && !tc.expectError { 113 t.Fatalf("unexpected error executing '%s': %s'", tc.query, err) 114 } 115 116 // Force metric snapshot refresh. 117 if err := s.WriteSummaries(); err != nil { 118 t.Fatal(err) 119 } 120 121 var err error 122 if accum.txnBeginCount, err = checkCounterDelta(s, sql.MetaTxnBeginStarted, accum.txnBeginCount, tc.txnBeginCount); err != nil { 123 t.Errorf("%q: %s", tc.query, err) 124 } 125 if accum.distSQLSelectCount, err = checkCounterDelta(s, sql.MetaDistSQLSelect, accum.distSQLSelectCount, tc.distSQLSelectCount); err != nil { 126 t.Errorf("%q: %s", tc.query, err) 127 } 128 if accum.txnRollbackCount, err = checkCounterDelta(s, sql.MetaTxnRollbackStarted, accum.txnRollbackCount, tc.txnRollbackCount); err != nil { 129 t.Errorf("%q: %s", tc.query, err) 130 } 131 if accum.txnAbortCount, err = checkCounterDelta(s, sql.MetaTxnAbort, accum.txnAbortCount, 0); err != nil { 132 t.Errorf("%q: %s", tc.query, err) 133 } 134 if accum.selectCount, err = checkCounterDelta(s, sql.MetaSelectStarted, accum.selectCount, tc.selectCount); err != nil { 135 t.Errorf("%q: %s", tc.query, err) 136 } 137 if accum.selectExecutedCount, err = checkCounterDelta(s, sql.MetaSelectExecuted, accum.selectExecutedCount, tc.selectExecutedCount); err != nil { 138 t.Errorf("%q: %s", tc.query, err) 139 } 140 if accum.updateCount, err = checkCounterDelta(s, sql.MetaUpdateStarted, accum.updateCount, tc.updateCount); err != nil { 141 t.Errorf("%q: %s", tc.query, err) 142 } 143 if accum.insertCount, err = checkCounterDelta(s, sql.MetaInsertStarted, accum.insertCount, tc.insertCount); err != nil { 144 t.Errorf("%q: %s", tc.query, err) 145 } 146 if accum.deleteCount, err = checkCounterDelta(s, sql.MetaDeleteStarted, accum.deleteCount, tc.deleteCount); err != nil { 147 t.Errorf("%q: %s", tc.query, err) 148 } 149 if accum.ddlCount, err = checkCounterDelta(s, sql.MetaDdlStarted, accum.ddlCount, tc.ddlCount); err != nil { 150 t.Errorf("%q: %s", tc.query, err) 151 } 152 if accum.miscCount, err = checkCounterDelta(s, sql.MetaMiscStarted, accum.miscCount, tc.miscCount); err != nil { 153 t.Errorf("%q: %s", tc.query, err) 154 } 155 if accum.miscExecutedCount, err = checkCounterDelta(s, sql.MetaMiscExecuted, accum.miscExecutedCount, tc.miscExecutedCount); err != nil { 156 t.Errorf("%q: %s", tc.query, err) 157 } 158 if accum.failureCount, err = checkCounterDelta(s, sql.MetaFailure, accum.failureCount, tc.failureCount); err != nil { 159 t.Errorf("%q: %s", tc.query, err) 160 } 161 if accum.fallbackCount, err = checkCounterDelta(s, sql.MetaSQLOptFallback, accum.fallbackCount, tc.fallbackCount); err != nil { 162 t.Errorf("%q: %s", tc.query, err) 163 } 164 }) 165 } 166 } 167 168 func TestAbortCountConflictingWrites(t *testing.T) { 169 defer leaktest.AfterTest(t)() 170 171 testutils.RunTrueAndFalse(t, "retry loop", func(t *testing.T, retry bool) { 172 params, cmdFilters := tests.CreateTestServerParams() 173 s, sqlDB, _ := serverutils.StartServer(t, params) 174 defer s.Stopper().Stop(context.Background()) 175 176 accum := initializeQueryCounter(s) 177 178 if _, err := sqlDB.Exec("CREATE DATABASE db"); err != nil { 179 t.Fatal(err) 180 } 181 if _, err := sqlDB.Exec("CREATE TABLE db.t (k TEXT PRIMARY KEY, v TEXT)"); err != nil { 182 t.Fatal(err) 183 } 184 185 // Inject errors on the INSERT below. 186 restarted := false 187 cmdFilters.AppendFilter(func(args kvserverbase.FilterArgs) *roachpb.Error { 188 switch req := args.Req.(type) { 189 // SQL INSERT generates ConditionalPuts for unique indexes (such as the PK). 190 case *roachpb.ConditionalPutRequest: 191 if bytes.Contains(req.Value.RawBytes, []byte("marker")) && !restarted { 192 restarted = true 193 return roachpb.NewErrorWithTxn( 194 roachpb.NewTransactionAbortedError( 195 roachpb.ABORT_REASON_ABORTED_RECORD_FOUND), args.Hdr.Txn) 196 } 197 } 198 return nil 199 }, false) 200 201 txn, err := sqlDB.Begin() 202 if err != nil { 203 t.Fatal(err) 204 } 205 if retry { 206 if _, err := txn.Exec("SAVEPOINT cockroach_restart"); err != nil { 207 t.Fatal(err) 208 } 209 } 210 // Run a batch of statements to move the txn out of the AutoRetry state, 211 // otherwise the INSERT below would be automatically retried. 212 if _, err := txn.Exec("SELECT 1"); err != nil { 213 t.Fatal(err) 214 } 215 216 _, err = txn.Exec("INSERT INTO db.t VALUES ('key', 'marker')") 217 expErr := "TransactionAbortedError(ABORT_REASON_ABORTED_RECORD_FOUND)" 218 if !testutils.IsError(err, regexp.QuoteMeta(expErr)) { 219 t.Fatalf("expected %s, got: %v", expErr, err) 220 } 221 222 var expRestart, expRollback, expCommit, expAbort int64 223 if retry { 224 if _, err := txn.Exec("ROLLBACK TO SAVEPOINT cockroach_restart"); err != nil { 225 t.Fatal(err) 226 } 227 if _, err := txn.Exec("RELEASE SAVEPOINT cockroach_restart"); err != nil { 228 t.Fatal(err) 229 } 230 if err = txn.Commit(); err != nil { 231 t.Fatal(err) 232 } 233 234 expRestart = 1 235 expCommit = 1 236 } else { 237 if err = txn.Rollback(); err != nil { 238 t.Fatal(err) 239 } 240 241 expRollback = 1 242 expAbort = 1 243 } 244 245 if _, err := checkCounterDelta(s, sql.MetaTxnBeginStarted, accum.txnBeginCount, 1); err != nil { 246 t.Error(err) 247 } 248 if _, err := checkCounterDelta(s, sql.MetaInsertStarted, accum.insertCount, 1); err != nil { 249 t.Error(err) 250 } 251 if _, err := checkCounterDelta(s, sql.MetaRestartSavepointStarted, accum.restartSavepointCount, expRestart); err != nil { 252 t.Error(err) 253 } 254 if _, err := checkCounterDelta(s, sql.MetaRollbackToRestartSavepointStarted, accum.rollbackToRestartSavepointCount, expRestart); err != nil { 255 t.Error(err) 256 } 257 if _, err := checkCounterDelta(s, sql.MetaReleaseRestartSavepointStarted, accum.releaseRestartSavepointCount, expRestart); err != nil { 258 t.Error(err) 259 } 260 if _, err := checkCounterDelta(s, sql.MetaTxnRollbackStarted, accum.txnRollbackCount, expRollback); err != nil { 261 t.Error(err) 262 } 263 if _, err := checkCounterDelta(s, sql.MetaTxnCommitStarted, accum.txnCommitCount, expCommit); err != nil { 264 t.Error(err) 265 } 266 if _, err := checkCounterDelta(s, sql.MetaTxnAbort, accum.txnAbortCount, expAbort); err != nil { 267 t.Error(err) 268 } 269 }) 270 } 271 272 // TestErrorDuringTransaction tests that the transaction abort count goes up when a query 273 // results in an error during a txn. 274 func TestAbortCountErrorDuringTransaction(t *testing.T) { 275 defer leaktest.AfterTest(t)() 276 params, _ := tests.CreateTestServerParams() 277 s, sqlDB, _ := serverutils.StartServer(t, params) 278 defer s.Stopper().Stop(context.Background()) 279 280 accum := initializeQueryCounter(s) 281 282 txn, err := sqlDB.Begin() 283 if err != nil { 284 t.Fatal(err) 285 } 286 287 if _, err := txn.Query("SELECT * FROM i_do.not_exist"); err == nil { 288 t.Fatal("Expected an error but didn't get one") 289 } 290 291 if _, err := checkCounterDelta(s, sql.MetaTxnBeginStarted, accum.txnBeginCount, 1); err != nil { 292 t.Error(err) 293 } 294 if _, err := checkCounterDelta(s, sql.MetaSelectStarted, accum.selectCount, 1); err != nil { 295 t.Error(err) 296 } 297 298 if err := txn.Rollback(); err != nil { 299 t.Fatal(err) 300 } 301 302 if _, err := checkCounterDelta(s, sql.MetaTxnAbort, accum.txnAbortCount, 1); err != nil { 303 t.Error(err) 304 } 305 } 306 307 func TestSavepointMetrics(t *testing.T) { 308 defer leaktest.AfterTest(t)() 309 310 params, _ := tests.CreateTestServerParams() 311 s, sqlDB, _ := serverutils.StartServer(t, params) 312 defer s.Stopper().Stop(context.Background()) 313 314 accum := initializeQueryCounter(s) 315 316 // Normal-case use of all three savepoint statements. 317 txn, err := sqlDB.Begin() 318 if err != nil { 319 t.Fatal(err) 320 } 321 if _, err := txn.Exec("SAVEPOINT cockroach_restart"); err != nil { 322 t.Fatal(err) 323 } 324 if _, err := txn.Exec("ROLLBACK TRANSACTION TO SAVEPOINT cockroach_restart"); err != nil { 325 t.Fatal(err) 326 } 327 if _, err := txn.Exec("RELEASE SAVEPOINT cockroach_restart"); err != nil { 328 t.Fatal(err) 329 } 330 if err := txn.Commit(); err != nil { 331 t.Fatal(err) 332 } 333 334 if _, err := checkCounterDelta(s, sql.MetaRestartSavepointStarted, accum.restartSavepointCount, 1); err != nil { 335 t.Error(err) 336 } 337 if _, err := checkCounterDelta(s, sql.MetaRestartSavepointStarted, accum.releaseRestartSavepointCount, 1); err != nil { 338 t.Error(err) 339 } 340 if _, err := checkCounterDelta(s, sql.MetaRestartSavepointStarted, accum.rollbackToRestartSavepointCount, 1); err != nil { 341 t.Error(err) 342 } 343 344 // Unsupported savepoints go in a different counter. 345 txn, err = sqlDB.Begin() 346 if err != nil { 347 t.Fatal(err) 348 } 349 if _, err := txn.Exec("SAVEPOINT blah"); err != nil { 350 t.Fatal(err) 351 } 352 if err := txn.Rollback(); err != nil { 353 t.Fatal(err) 354 } 355 if _, err := checkCounterDelta(s, sql.MetaSavepointStarted, accum.savepointCount, 1); err != nil { 356 t.Error(err) 357 } 358 if _, err := checkCounterDelta(s, sql.MetaTxnRollbackStarted, accum.txnRollbackCount, 1); err != nil { 359 t.Error(err) 360 } 361 362 // Custom restart savepoint names are recognized. 363 txn, err = sqlDB.Begin() 364 if err != nil { 365 t.Fatal(err) 366 } 367 if _, err := txn.Exec("SET force_savepoint_restart = true"); err != nil { 368 t.Fatal(err) 369 } 370 if _, err := txn.Exec("SAVEPOINT blah"); err != nil { 371 t.Fatal(err) 372 } 373 if err := txn.Rollback(); err != nil { 374 t.Fatal(err) 375 } 376 if _, err := checkCounterDelta(s, sql.MetaRestartSavepointStarted, accum.restartSavepointCount, 2); err != nil { 377 t.Error(err) 378 } 379 if _, err := checkCounterDelta(s, sql.MetaTxnRollbackStarted, accum.txnRollbackCount, 2); err != nil { 380 t.Error(err) 381 } 382 }