Skip to content

Commit 8630c8b

Browse files
committed
roachtest/large-schema-benchmark: improve import init performance
Currently, the large schema benchmark workload benchmark times out during the PostLoad of the import because of the amount of time it takes to setup foreign keys on tables. This may have been slowed down because of the increased round trips involved since schema_locked needs to be toggled. To help improve the performance of this step in general, this patch adds parallelism. Fixes: #150100 Fixes: #150095 Fixes: #149182 Release note: None
1 parent 2f72cf4 commit 8630c8b

File tree

4 files changed

+213
-129
lines changed

4 files changed

+213
-129
lines changed

pkg/workload/tpcc/ddls.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package tpcc
77

88
import (
9+
"context"
910
gosql "database/sql"
1011
"fmt"
1112
"strings"
@@ -230,7 +231,7 @@ func makeSchema(base string, opts ...makeSchemaOption) string {
230231
return ret
231232
}
232233

233-
func scatterRanges(db *gosql.DB) error {
234+
func scatterRanges(ctx context.Context, conn *gosql.Conn) error {
234235
tables := []string{
235236
`customer`,
236237
`district`,
@@ -247,7 +248,7 @@ func scatterRanges(db *gosql.DB) error {
247248
for _, table := range tables {
248249
sql := fmt.Sprintf(`ALTER TABLE %s SCATTER`, table)
249250
g.Go(func() error {
250-
if _, err := db.Exec(sql); err != nil {
251+
if _, err := conn.ExecContext(ctx, sql); err != nil {
251252
return errors.Wrapf(err, "Couldn't exec %q", sql)
252253
}
253254
return nil

pkg/workload/tpcc/partition.go

Lines changed: 96 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package tpcc
77

88
import (
99
"bytes"
10+
"context"
1011
gosql "database/sql"
1112
"fmt"
1213
"math/rand/v2"
@@ -388,7 +389,12 @@ func (p *partitioner) randActive(rng *rand.Rand) int {
388389
// flag is passed into tpcc, it will set the constraints/preferences based on
389390
// the geographic zones provided.
390391
func configureZone(
391-
db *gosql.DB, cfg zoneConfig, table, partition string, partIdx int, totalParts int,
392+
ctx context.Context,
393+
conn *gosql.Conn,
394+
cfg zoneConfig,
395+
table, partition string,
396+
partIdx int,
397+
totalParts int,
392398
) error {
393399
var constraint string
394400
var lease string
@@ -419,7 +425,7 @@ func configureZone(
419425

420426
sql := fmt.Sprintf(`ALTER PARTITION %s OF TABLE %s CONFIGURE ZONE USING %s`,
421427
partition, table, opts)
422-
if _, err := db.Exec(sql); err != nil {
428+
if _, err := conn.ExecContext(ctx, sql); err != nil {
423429
return errors.Wrapf(err, "Couldn't exec %q", sql)
424430
}
425431
return nil
@@ -429,7 +435,12 @@ func configureZone(
429435
// provided name, given the partitioning. Callers of the function must specify
430436
// the associated table and the partition's number.
431437
func partitionObject(
432-
db *gosql.DB, cfg zoneConfig, p *partitioner, obj, name, col, table string, idx int,
438+
ctx context.Context,
439+
conn *gosql.Conn,
440+
cfg zoneConfig,
441+
p *partitioner,
442+
obj, name, col, table string,
443+
idx int,
433444
) error {
434445
var buf bytes.Buffer
435446
fmt.Fprintf(&buf, "ALTER %s %s PARTITION BY RANGE (%s) (\n", obj, name, col)
@@ -442,72 +453,93 @@ func partitionObject(
442453
buf.WriteString("\n")
443454
}
444455
buf.WriteString(")\n")
445-
if _, err := db.Exec(buf.String()); err != nil {
456+
if _, err := conn.ExecContext(ctx, buf.String()); err != nil {
446457
return errors.Wrapf(err, "Couldn't exec %q", buf.String())
447458
}
448459

449460
for i := 0; i < p.parts; i++ {
450-
if err := configureZone(db, cfg, table, fmt.Sprintf("p%d_%d", idx, i), i, p.parts); err != nil {
461+
if err := configureZone(ctx, conn, cfg, table, fmt.Sprintf("p%d_%d", idx, i), i, p.parts); err != nil {
451462
return err
452463
}
453464
}
454465
return nil
455466
}
456467

457468
func partitionTable(
458-
db *gosql.DB, cfg zoneConfig, p *partitioner, table, col string, idx int,
469+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, p *partitioner, table, col string, idx int,
459470
) error {
460-
return partitionObject(db, cfg, p, "TABLE", table, col, table, idx)
471+
return partitionObject(ctx, conn, cfg, p, "TABLE", table, col, table, idx)
461472
}
462473

463474
func partitionIndex(
464-
db *gosql.DB, cfg zoneConfig, p *partitioner, table, index, col string, idx int,
475+
ctx context.Context,
476+
conn *gosql.Conn,
477+
cfg zoneConfig,
478+
p *partitioner,
479+
table, index, col string,
480+
idx int,
465481
) error {
466482
indexStr := fmt.Sprintf("%s@%s", table, index)
467-
if exists, err := indexExists(db, table, index); err != nil {
483+
if exists, err := indexExists(ctx, conn, table, index); err != nil {
468484
return err
469485
} else if !exists {
470486
return errors.Errorf("could not find index %q", indexStr)
471487
}
472-
return partitionObject(db, cfg, p, "INDEX", indexStr, col, table, idx)
488+
return partitionObject(ctx, conn, cfg, p, "INDEX", indexStr, col, table, idx)
473489
}
474490

475-
func partitionWarehouse(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
476-
return partitionTable(db, cfg, wPart, "warehouse", "w_id", 0)
491+
func partitionWarehouse(
492+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
493+
) error {
494+
return partitionTable(ctx, conn, cfg, wPart, "warehouse", "w_id", 0)
477495
}
478496

479-
func partitionDistrict(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
480-
return partitionTable(db, cfg, wPart, "district", "d_w_id", 0)
497+
func partitionDistrict(
498+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
499+
) error {
500+
return partitionTable(ctx, conn, cfg, wPart, "district", "d_w_id", 0)
481501
}
482502

483-
func partitionNewOrder(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
484-
return partitionTable(db, cfg, wPart, "new_order", "no_w_id", 0)
503+
func partitionNewOrder(
504+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
505+
) error {
506+
return partitionTable(ctx, conn, cfg, wPart, "new_order", "no_w_id", 0)
485507
}
486508

487-
func partitionOrder(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
488-
if err := partitionTable(db, cfg, wPart, `"order"`, "o_w_id", 0); err != nil {
509+
func partitionOrder(
510+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
511+
) error {
512+
if err := partitionTable(ctx, conn, cfg, wPart, `"order"`, "o_w_id", 0); err != nil {
489513
return err
490514
}
491-
return partitionIndex(db, cfg, wPart, `"order"`, "order_idx", "o_w_id", 1)
515+
return partitionIndex(ctx, conn, cfg, wPart, `"order"`, "order_idx", "o_w_id", 1)
492516
}
493517

494-
func partitionOrderLine(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
495-
return partitionTable(db, cfg, wPart, "order_line", "ol_w_id", 0)
518+
func partitionOrderLine(
519+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
520+
) error {
521+
return partitionTable(ctx, conn, cfg, wPart, "order_line", "ol_w_id", 0)
496522
}
497523

498-
func partitionStock(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
499-
return partitionTable(db, cfg, wPart, "stock", "s_w_id", 0)
524+
func partitionStock(
525+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
526+
) error {
527+
return partitionTable(ctx, conn, cfg, wPart, "stock", "s_w_id", 0)
500528
}
501529

502-
func partitionCustomer(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
503-
if err := partitionTable(db, cfg, wPart, "customer", "c_w_id", 0); err != nil {
530+
func partitionCustomer(
531+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
532+
) error {
533+
if err := partitionTable(ctx, conn, cfg, wPart, "customer", "c_w_id", 0); err != nil {
504534
return err
505535
}
506-
return partitionIndex(db, cfg, wPart, "customer", "customer_idx", "c_w_id", 1)
536+
return partitionIndex(ctx, conn, cfg, wPart, "customer", "customer_idx", "c_w_id", 1)
507537
}
508538

509-
func partitionHistory(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
510-
return partitionTable(db, cfg, wPart, "history", "h_w_id", 0)
539+
func partitionHistory(
540+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
541+
) error {
542+
return partitionTable(ctx, conn, cfg, wPart, "history", "h_w_id", 0)
511543
}
512544

513545
// replicateColumns creates covering replicated indexes for a given table
@@ -517,7 +549,8 @@ func partitionHistory(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
517549
// lookups on those columns to be local within the provided zone. If there are
518550
// no zones, it assumes that each partition corresponds to a rack.
519551
func replicateColumns(
520-
db *gosql.DB,
552+
ctx context.Context,
553+
conn *gosql.Conn,
521554
cfg zoneConfig,
522555
wPart *partitioner,
523556
name string,
@@ -526,13 +559,13 @@ func replicateColumns(
526559
) error {
527560
constraints := synthesizeConstraints(cfg, wPart)
528561
for i, constraint := range constraints {
529-
if _, err := db.Exec(
562+
if _, err := conn.ExecContext(ctx,
530563
fmt.Sprintf(`CREATE UNIQUE INDEX %[1]s_idx_%[2]d ON %[1]s (%[3]s) STORING (%[4]s)`,
531564
name, i, strings.Join(pkColumns, ","), strings.Join(storedColumns, ",")),
532565
); err != nil {
533566
return err
534567
}
535-
if _, err := db.Exec(fmt.Sprintf(
568+
if _, err := conn.ExecContext(ctx, fmt.Sprintf(
536569
`ALTER INDEX %[1]s@%[1]s_idx_%[2]d
537570
CONFIGURE ZONE USING num_replicas = COPY FROM PARENT, constraints='{"%[3]s": 1}', lease_preferences='[[%[3]s]]'`,
538571
name, i, constraint)); err != nil {
@@ -542,17 +575,23 @@ CONFIGURE ZONE USING num_replicas = COPY FROM PARENT, constraints='{"%[3]s": 1}'
542575
return nil
543576
}
544577

545-
func replicateWarehouse(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
546-
return replicateColumns(db, cfg, wPart, "warehouse", []string{"w_id"}, []string{"w_tax"})
578+
func replicateWarehouse(
579+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
580+
) error {
581+
return replicateColumns(ctx, conn, cfg, wPart, "warehouse", []string{"w_id"}, []string{"w_tax"})
547582
}
548583

549-
func replicateDistrict(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
550-
return replicateColumns(db, cfg, wPart, "district", []string{"d_w_id", "d_id"},
584+
func replicateDistrict(
585+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
586+
) error {
587+
return replicateColumns(ctx, conn, cfg, wPart, "district", []string{"d_w_id", "d_id"},
551588
[]string{"d_name", "d_street_1", "d_street_2", "d_city", "d_state", "d_zip"})
552589
}
553590

554-
func replicateItem(db *gosql.DB, cfg zoneConfig, wPart *partitioner) error {
555-
return replicateColumns(db, cfg, wPart, "item", []string{"i_id"},
591+
func replicateItem(
592+
ctx context.Context, conn *gosql.Conn, cfg zoneConfig, wPart *partitioner,
593+
) error {
594+
return replicateColumns(ctx, conn, cfg, wPart, "item", []string{"i_id"},
556595
[]string{"i_im_id", "i_name", "i_price", "i_data"})
557596
}
558597

@@ -572,46 +611,50 @@ func synthesizeConstraints(cfg zoneConfig, wPart *partitioner) []string {
572611
}
573612

574613
func partitionTables(
575-
db *gosql.DB, cfg zoneConfig, wPart *partitioner, replicateStaticColumns bool,
614+
ctx context.Context,
615+
conn *gosql.Conn,
616+
cfg zoneConfig,
617+
wPart *partitioner,
618+
replicateStaticColumns bool,
576619
) error {
577-
if err := partitionWarehouse(db, cfg, wPart); err != nil {
620+
if err := partitionWarehouse(ctx, conn, cfg, wPart); err != nil {
578621
return err
579622
}
580-
if err := partitionDistrict(db, cfg, wPart); err != nil {
623+
if err := partitionDistrict(ctx, conn, cfg, wPart); err != nil {
581624
return err
582625
}
583-
if err := partitionNewOrder(db, cfg, wPart); err != nil {
626+
if err := partitionNewOrder(ctx, conn, cfg, wPart); err != nil {
584627
return err
585628
}
586-
if err := partitionOrder(db, cfg, wPart); err != nil {
629+
if err := partitionOrder(ctx, conn, cfg, wPart); err != nil {
587630
return err
588631
}
589-
if err := partitionOrderLine(db, cfg, wPart); err != nil {
632+
if err := partitionOrderLine(ctx, conn, cfg, wPart); err != nil {
590633
return err
591634
}
592-
if err := partitionStock(db, cfg, wPart); err != nil {
635+
if err := partitionStock(ctx, conn, cfg, wPart); err != nil {
593636
return err
594637
}
595-
if err := partitionCustomer(db, cfg, wPart); err != nil {
638+
if err := partitionCustomer(ctx, conn, cfg, wPart); err != nil {
596639
return err
597640
}
598-
if err := partitionHistory(db, cfg, wPart); err != nil {
641+
if err := partitionHistory(ctx, conn, cfg, wPart); err != nil {
599642
return err
600643
}
601644
if replicateStaticColumns {
602-
if err := replicateDistrict(db, cfg, wPart); err != nil {
645+
if err := replicateDistrict(ctx, conn, cfg, wPart); err != nil {
603646
return err
604647
}
605-
if err := replicateWarehouse(db, cfg, wPart); err != nil {
648+
if err := replicateWarehouse(ctx, conn, cfg, wPart); err != nil {
606649
return err
607650
}
608651
}
609-
return replicateItem(db, cfg, wPart)
652+
return replicateItem(ctx, conn, cfg, wPart)
610653
}
611654

612-
func partitionCount(db *gosql.DB) (int, error) {
655+
func partitionCount(ctx context.Context, conn *gosql.Conn) (int, error) {
613656
var count int
614-
if err := db.QueryRow(`
657+
if err := conn.QueryRowContext(ctx, `
615658
SELECT count(*)
616659
FROM crdb_internal.tables t
617660
JOIN crdb_internal.partitions p
@@ -624,12 +667,12 @@ func partitionCount(db *gosql.DB) (int, error) {
624667
return count, nil
625668
}
626669

627-
func indexExists(db *gosql.DB, table, index string) (bool, error) {
670+
func indexExists(ctx context.Context, conn *gosql.Conn, table, index string) (bool, error) {
628671
// Strip any quotes around the table name.
629672
table = strings.ReplaceAll(table, `"`, ``)
630673

631674
var exists bool
632-
if err := db.QueryRow(`
675+
if err := conn.QueryRowContext(ctx, `
633676
SELECT count(*) > 0
634677
FROM information_schema.statistics
635678
WHERE table_name = $1

0 commit comments

Comments
 (0)