diff --git a/br/pkg/restore/db.go b/br/pkg/restore/db.go index 8b5c619bd1..a7b29a3e90 100644 --- a/br/pkg/restore/db.go +++ b/br/pkg/restore/db.go @@ -12,10 +12,12 @@ import ( "github.com/pingcap/tidb/br/pkg/glue" "github.com/pingcap/tidb/br/pkg/metautil" "github.com/pingcap/tidb/br/pkg/utils" + "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/variable" + tidbutil "github.com/pingcap/tidb/util" "go.uber.org/zap" "golang.org/x/exp/slices" ) @@ -450,6 +452,24 @@ func DDLJobBlockListRule(ddlJob *model.Job) bool { return checkIsInActions(ddlJob.Type, incrementalRestoreActionBlockList) } +// GetExistedUserDBs get dbs created or modified by users +func GetExistedUserDBs(dom *domain.Domain) []*model.DBInfo { + databases := dom.InfoSchema().AllSchemas() + existedDatabases := make([]*model.DBInfo, 0, 16) + for _, db := range databases { + dbName := db.Name.L + if tidbutil.IsMemOrSysDB(dbName) { + continue + } else if dbName == "test" && len(db.Tables) == 0 { + continue + } else { + existedDatabases = append(existedDatabases, db) + } + } + + return existedDatabases +} + func getDatabases(tables []*metautil.Table) (dbs []*model.DBInfo) { dbIDs := make(map[int64]bool) for _, table := range tables { diff --git a/br/pkg/restore/db_test.go b/br/pkg/restore/db_test.go index 7c84d53536..a3279ddaad 100644 --- a/br/pkg/restore/db_test.go +++ b/br/pkg/restore/db_test.go @@ -18,6 +18,7 @@ import ( "github.com/pingcap/tidb/br/pkg/mock" "github.com/pingcap/tidb/br/pkg/restore" "github.com/pingcap/tidb/br/pkg/storage" + "github.com/pingcap/tidb/infoschema" "github.com/pingcap/tidb/meta/autoid" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" @@ -368,3 +369,52 @@ func TestFilterDDLJobByRules(t *testing.T) { assert.Equal(t, expectedDDLTypes[i], ddlJob.Type) } } + +func TestGetExistedUserDBs(t *testing.T) { + m, err := mock.NewCluster() + require.Nil(t, err) + defer m.Stop() + dom := m.Domain + + dbs := restore.GetExistedUserDBs(dom) + require.Equal(t, 0, len(dbs)) + + builder, err := infoschema.NewBuilder(m.Store(), nil).InitWithDBInfos( + []*model.DBInfo{ + {Name: model.NewCIStr("mysql")}, + {Name: model.NewCIStr("test")}, + }, + nil, 1) + require.Nil(t, err) + dom.MockInfoCacheAndLoadInfoSchema(builder.Build()) + dbs = restore.GetExistedUserDBs(dom) + require.Equal(t, 0, len(dbs)) + + builder, err = infoschema.NewBuilder(m.Store(), nil).InitWithDBInfos( + []*model.DBInfo{ + {Name: model.NewCIStr("mysql")}, + {Name: model.NewCIStr("test")}, + {Name: model.NewCIStr("d1")}, + }, + nil, 1) + require.Nil(t, err) + dom.MockInfoCacheAndLoadInfoSchema(builder.Build()) + dbs = restore.GetExistedUserDBs(dom) + require.Equal(t, 1, len(dbs)) + + builder, err = infoschema.NewBuilder(m.Store(), nil).InitWithDBInfos( + []*model.DBInfo{ + {Name: model.NewCIStr("mysql")}, + {Name: model.NewCIStr("d1")}, + { + Name: model.NewCIStr("test"), + Tables: []*model.TableInfo{{Name: model.NewCIStr("t1"), State: model.StatePublic}}, + State: model.StatePublic, + }, + }, + nil, 1) + require.Nil(t, err) + dom.MockInfoCacheAndLoadInfoSchema(builder.Build()) + dbs = restore.GetExistedUserDBs(dom) + require.Equal(t, 2, len(dbs)) +}