@@ -14,6 +14,7 @@ import (
14
14
"time"
15
15
16
16
"github.com/cockroachdb/cockroach/pkg/base"
17
+ "github.com/cockroachdb/cockroach/pkg/clusterversion"
17
18
"github.com/cockroachdb/cockroach/pkg/config"
18
19
"github.com/cockroachdb/cockroach/pkg/jobs"
19
20
"github.com/cockroachdb/cockroach/pkg/jobs/jobspb"
@@ -311,13 +312,21 @@ const schemaChangerBackfillTxnDebugName = "schemaChangerBackfill"
311
312
// validateBackfillQueryIntoTable validates that source query matches the contents of
312
313
// a backfilled table, when executing the query at queryTS.
313
314
func (sc * SchemaChanger ) validateBackfillQueryIntoTable (
314
- ctx context.Context , table catalog.TableDescriptor , queryTS hlc.Timestamp , query string ,
315
+ ctx context.Context ,
316
+ table catalog.TableDescriptor ,
317
+ entryCountWrittenToPrimaryIdx int64 ,
318
+ queryTS hlc.Timestamp ,
319
+ query string ,
320
+ skipAOSTValidation bool ,
315
321
) error {
316
- var entryCount int64
322
+ var aostEntryCount int64
317
323
sd := NewInternalSessionData (ctx , sc .execCfg .Settings , "validateBackfillQueryIntoTable" )
318
324
sd .SessionData = * sc .sessionData
319
325
// First get the expected row count for the source query at the target timestamp.
320
326
if err := sc .execCfg .InternalDB .Txn (ctx , func (ctx context.Context , txn isql.Txn ) error {
327
+ if skipAOSTValidation {
328
+ return nil
329
+ }
321
330
parsedQuery , err := parser .ParseOne (query )
322
331
if err != nil {
323
332
return err
@@ -347,9 +356,11 @@ func (sc *SchemaChanger) validateBackfillQueryIntoTable(
347
356
if err != nil {
348
357
return err
349
358
}
350
- entryCount = int64 (tree .MustBeDInt (row [0 ]))
359
+ aostEntryCount = int64 (tree .MustBeDInt (row [0 ]))
351
360
return nil
352
- }, isql .WithSessionData (sd )); err != nil {
361
+ }, isql .WithSessionData (sd ),
362
+ isql .WithPriority (admissionpb .BulkNormalPri ),
363
+ ); err != nil {
353
364
return err
354
365
}
355
366
// Next run validation on table that was populated using count queries.
@@ -361,7 +372,7 @@ func (sc *SchemaChanger) validateBackfillQueryIntoTable(
361
372
// counts match.
362
373
mut := builder .BuildExistingMutable ().(* tabledesc.Mutable )
363
374
mut .SetPublic ()
364
- count , err := countIndexRowsAndMaybeCheckUniqueness (ctx , mut , index , false ,
375
+ newTblEntryCount , err := countIndexRowsAndMaybeCheckUniqueness (ctx , mut , index , false ,
365
376
descs .NewHistoricalInternalExecTxnRunner (now , func (ctx context.Context , fn descs.InternalExecFn ) error {
366
377
return sc .execCfg .InternalDB .DescsTxn (ctx , func (
367
378
ctx context.Context , txn descs.Txn ,
@@ -379,13 +390,21 @@ func (sc *SchemaChanger) validateBackfillQueryIntoTable(
379
390
// Testing knob that allows us to manipulate counts to fail
380
391
// the validation.
381
392
if sc .testingKnobs .RunDuringQueryBackfillValidation != nil {
382
- count , err = sc .testingKnobs .RunDuringQueryBackfillValidation (entryCount , count )
393
+ newTblEntryCount , err = sc .testingKnobs .RunDuringQueryBackfillValidation (aostEntryCount , newTblEntryCount )
383
394
if err != nil {
384
395
return err
385
396
}
386
397
}
387
- if count != entryCount {
388
- return errors .AssertionFailedf ("backfill query did not populate index %q with expected number of rows (expected: %d, got: %d)" , index .GetName (), entryCount , count )
398
+ if entryCountWrittenToPrimaryIdx > 0 {
399
+ if newTblEntryCount != entryCountWrittenToPrimaryIdx {
400
+ return errors .AssertionFailedf (
401
+ "backfill query did not populate index %q with expected number of rows (expected: %d, got: %d)" ,
402
+ index .GetName (), entryCountWrittenToPrimaryIdx , newTblEntryCount ,
403
+ )
404
+ }
405
+ }
406
+ if ! skipAOSTValidation && newTblEntryCount != aostEntryCount {
407
+ return errors .AssertionFailedf ("backfill query did not populate index %q with expected number of rows (expected: %d, got: %d)" , index .GetName (), aostEntryCount , newTblEntryCount )
389
408
}
390
409
return nil
391
410
}
@@ -417,9 +436,12 @@ func (sc *SchemaChanger) backfillQueryIntoTable(
417
436
}
418
437
}()
419
438
validationTime := ts
420
- var skipValidation bool
421
- // Get the expected entry count against the source query.
439
+ var skipAOSTValidation bool
440
+ bulkSummary := kvpb.BulkOpSummary {}
441
+
422
442
err = sc .db .Txn (ctx , func (ctx context.Context , txn isql.Txn ) error {
443
+ // Clear out the previous summary if the transaction gets retried.
444
+ bulkSummary = kvpb.BulkOpSummary {}
423
445
defer func () {
424
446
isTxnRetry = true
425
447
}()
@@ -515,15 +537,12 @@ func (sc *SchemaChanger) backfillQueryIntoTable(
515
537
return err
516
538
}
517
539
}
518
- res := kvpb.BulkOpSummary {}
519
540
rw := NewCallbackResultWriter (func (ctx context.Context , row tree.Datums ) error {
520
- // TODO(adityamaru): Use the BulkOpSummary for either telemetry or to
521
- // return to user.
522
541
var counts kvpb.BulkOpSummary
523
542
if err := protoutil .Unmarshal ([]byte (* row [0 ].(* tree.DBytes )), & counts ); err != nil {
524
543
return err
525
544
}
526
- res .Add (counts )
545
+ bulkSummary .Add (counts )
527
546
return nil
528
547
})
529
548
recv := MakeDistSQLReceiver (
@@ -590,7 +609,7 @@ func (sc *SchemaChanger) backfillQueryIntoTable(
590
609
// since our AOST query might be reading data not in KV.
591
610
for _ , tbl := range localPlanner .curPlan .mem .Metadata ().AllTables () {
592
611
if tbl .Table .IsVirtualTable () {
593
- skipValidation = true
612
+ skipAOSTValidation = true
594
613
}
595
614
}
596
615
return nil
@@ -608,12 +627,19 @@ func (sc *SchemaChanger) backfillQueryIntoTable(
608
627
return err
609
628
}
610
629
630
+ // Count how many keys were written to the primary index, as reported by the
631
+ // BulkAdder. We need a version gate since pre-25.4 clusters did not count
632
+ // correctly.
633
+ entriesWrittenToPrimaryIdx := int64 (0 )
634
+ if sc .execCfg .Settings .Version .IsActive (ctx , clusterversion .V25_4 ) {
635
+ key := kvpb .BulkOpSummaryID (uint64 (table .GetID ()), uint64 (table .GetPrimaryIndex ().GetID ()))
636
+ entriesWrittenToPrimaryIdx = bulkSummary .EntryCounts [key ]
637
+ }
638
+
611
639
// Validation will be skipped if the query is not AOST safe.
612
640
// (i.e. reading non-KV data via CRDB internal)
613
- if ! skipValidation {
614
- if err := sc .validateBackfillQueryIntoTable (ctx , table , validationTime , query ); err != nil {
615
- return err
616
- }
641
+ if err := sc .validateBackfillQueryIntoTable (ctx , table , entriesWrittenToPrimaryIdx , validationTime , query , skipAOSTValidation ); err != nil {
642
+ return err
617
643
}
618
644
return nil
619
645
}
0 commit comments