From 350691727bc39f22876dde6ee8c5e06a34a9b156 Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Fri, 9 Feb 2024 16:13:16 +0800 Subject: [PATCH] br: create database by db pool (#50771) (#51028) close pingcap/tidb#50767 --- br/pkg/restore/client.go | 35 ++++++++++++++++++++++++++++++----- br/pkg/restore/client_test.go | 2 +- br/pkg/task/restore.go | 7 ++----- br/tests/br_full_ddl/run.sh | 3 +-- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/br/pkg/restore/client.go b/br/pkg/restore/client.go index 4cdfc54834565..c914ed9067f18 100644 --- a/br/pkg/restore/client.go +++ b/br/pkg/restore/client.go @@ -774,13 +774,38 @@ func (rc *Client) GetDBSchema(dom *domain.Domain, dbName model.CIStr) (*model.DB return info.SchemaByName(dbName) } -// CreateDatabase creates a database. -func (rc *Client) CreateDatabase(ctx context.Context, db *model.DBInfo) error { +// CreateDatabases creates databases. If the client has the db pool, it would create it. +func (rc *Client) CreateDatabases(ctx context.Context, dbs []*utils.Database) error { if rc.IsSkipCreateSQL() { - log.Info("skip create database", zap.Stringer("name", db.Name)) + log.Info("skip create database") return nil } + if len(rc.dbPool) == 0 { + log.Info("create databases sequentially") + for _, db := range dbs { + err := rc.createDatabaseWithDBConn(ctx, db.Info, rc.db) + if err != nil { + return errors.Trace(err) + } + } + return nil + } + + log.Info("create databases in db pool", zap.Int("pool size", len(rc.dbPool))) + eg, ectx := errgroup.WithContext(ctx) + workers := utils.NewWorkerPool(uint(len(rc.dbPool)), "DB DDL workers") + for _, db_ := range dbs { + db := db_ + workers.ApplyWithIDInErrorGroup(eg, func(id uint64) error { + conn := rc.dbPool[id%uint64(len(rc.dbPool))] + return rc.createDatabaseWithDBConn(ectx, db.Info, conn) + }) + } + return eg.Wait() +} + +func (rc *Client) createDatabaseWithDBConn(ctx context.Context, db *model.DBInfo, conn *DB) error { log.Info("create database", zap.Stringer("name", db.Name)) if !rc.supportPolicy { @@ -790,12 +815,12 @@ func (rc *Client) CreateDatabase(ctx context.Context, db *model.DBInfo) error { } if db.PlacementPolicyRef != nil { - if err := rc.db.ensurePlacementPolicy(ctx, db.PlacementPolicyRef.Name, rc.policyMap); err != nil { + if err := conn.ensurePlacementPolicy(ctx, db.PlacementPolicyRef.Name, rc.policyMap); err != nil { return errors.Trace(err) } } - return rc.db.CreateDatabase(ctx, db) + return conn.CreateDatabase(ctx, db) } // CreateTables creates multiple tables, and returns their rewrite rules. diff --git a/br/pkg/restore/client_test.go b/br/pkg/restore/client_test.go index 14e96a458228c..86b48df2eda5f 100644 --- a/br/pkg/restore/client_test.go +++ b/br/pkg/restore/client_test.go @@ -167,7 +167,7 @@ func TestCheckTargetClusterFresh(t *testing.T) { ctx := context.Background() require.NoError(t, client.CheckTargetClusterFresh(ctx)) - require.NoError(t, client.CreateDatabase(ctx, &model.DBInfo{Name: model.NewCIStr("user_db")})) + require.NoError(t, client.CreateDatabases(ctx, []*utils.Database{{Info: &model.DBInfo{Name: model.NewCIStr("user_db")}}})) require.True(t, berrors.ErrRestoreNotFreshCluster.Equal(client.CheckTargetClusterFresh(ctx))) } diff --git a/br/pkg/task/restore.go b/br/pkg/task/restore.go index f58122c72d53c..ec7672e466ba1 100644 --- a/br/pkg/task/restore.go +++ b/br/pkg/task/restore.go @@ -896,11 +896,8 @@ func runRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf return nil } - for _, db := range dbs { - err = client.CreateDatabase(ctx, db.Info) - if err != nil { - return errors.Trace(err) - } + if err = client.CreateDatabases(ctx, dbs); err != nil { + return errors.Trace(err) } // We make bigger errCh so we won't block on multi-part failed. diff --git a/br/tests/br_full_ddl/run.sh b/br/tests/br_full_ddl/run.sh index 92b845e7313fe..06ba38bfdbe7c 100755 --- a/br/tests/br_full_ddl/run.sh +++ b/br/tests/br_full_ddl/run.sh @@ -204,8 +204,7 @@ then else echo "TEST: [$TEST_NAME] fail due to stats are not equal" grep ERROR $LOG - cat $BACKUP_STAT | head -n 1000 - cat $RESOTRE_STAT | head -n 1000 + diff $BACKUP_STAT $RESOTRE_STAT exit 1 fi