diff --git a/pkg/task/restore.go b/pkg/task/restore.go index 11557a0ba..8d29f0c67 100644 --- a/pkg/task/restore.go +++ b/pkg/task/restore.go @@ -158,9 +158,13 @@ func CheckRestoreDBAndTable(client *restore.Client, cfg *RestoreConfig) error { schemasMap := make(map[string]struct{}) tablesMap := make(map[string]struct{}) for _, db := range schemas { - schemasMap[utils.EncloseName(db.Info.Name.O)] = struct{}{} + dbName := db.Info.Name.O + if name, ok := utils.GetSysDBName(db.Info.Name); utils.IsSysDB(name) && ok { + dbName = name + } + schemasMap[utils.EncloseName(dbName)] = struct{}{} for _, table := range db.Tables { - tablesMap[utils.EncloseDBAndTable(db.Info.Name.O, table.Info.Name.O)] = struct{}{} + tablesMap[utils.EncloseDBAndTable(dbName, table.Info.Name.O)] = struct{}{} } } restoreSchemas := cfg.Schemas @@ -463,8 +467,12 @@ func filterRestoreFiles( ) (files []*backuppb.File, tables []*utils.Table, dbs []*utils.Database) { for _, db := range client.GetDatabases() { createdDatabase := false + dbName := db.Info.Name.O + if name, ok := utils.GetSysDBName(db.Info.Name); utils.IsSysDB(name) && ok { + dbName = name + } for _, table := range db.Tables { - if !cfg.TableFilter.MatchTable(db.Info.Name.O, table.Info.Name.O) { + if !cfg.TableFilter.MatchTable(dbName, table.Info.Name.O) { continue } if !createdDatabase { diff --git a/pkg/utils/schema.go b/pkg/utils/schema.go index f1f45e0d0..c0b17cf1f 100644 --- a/pkg/utils/schema.go +++ b/pkg/utils/schema.go @@ -46,6 +46,9 @@ func (tbl *Table) NoChecksum() bool { return tbl.Crc64Xor == 0 && tbl.TotalKvs == 0 && tbl.TotalBytes == 0 } +// temporaryDBNamePrefix is the prefix name of system db, e.g. mysql system db will be rename to __TiDB_BR_Temporary_mysql +const temporaryDBNamePrefix = "__TiDB_BR_Temporary_" + // NeedAutoID checks whether the table needs backing up with an autoid. func NeedAutoID(tblInfo *model.TableInfo) bool { hasRowID := !tblInfo.PKIsHandle && !tblInfo.IsCommonHandle @@ -171,5 +174,13 @@ func IsSysDB(dbLowerName string) bool { // TemporaryDBName makes a 'private' database name. func TemporaryDBName(db string) model.CIStr { - return model.NewCIStr("__TiDB_BR_Temporary_" + db) + return model.NewCIStr(temporaryDBNamePrefix + db) +} + +// GetSysDBName get the original name of system DB +func GetSysDBName(tempDB model.CIStr) (string, bool) { + if ok := strings.HasPrefix(tempDB.O, temporaryDBNamePrefix); !ok { + return tempDB.O, false + } + return tempDB.O[len(temporaryDBNamePrefix):], true } diff --git a/tests/br_systables/run.sh b/tests/br_systables/run.sh index 94ee6d7a7..fbf233772 100644 --- a/tests/br_systables/run.sh +++ b/tests/br_systables/run.sh @@ -25,6 +25,24 @@ modify_systables() { run_sql "ANALYZE TABLE mysql.usertable;" } +add_user() { + run_sql "CREATE USER 'newuser' IDENTIFIED BY 'newuserpassword';" +} + +delete_user() { + run_sql "DROP USER 'newuser'" +} + +add_test_data() { + run_sql "CREATE DATABASE usertest;" + run_sql "CREATE TABLE usertest.test(pk int primary key auto_increment, field varchar(255));" + run_sql "INSERT INTO usertest.test(field) VALUES $test_data" +} + +delete_test_data() { + run_sql "DROP TABLE usertest.test;" +} + rollback_modify() { run_sql "DROP TABLE mysql.foo;" run_sql "DROP TABLE mysql.bar;" @@ -47,8 +65,33 @@ check() { # TODO check stats after supportting. } +check2() { + run_sql "SELECT count(*) from usertest.test;" | grep 11 + run_sql "SELECT user FROM mysql.user WHERE user='newuser';" | grep 'newuser' +} + modify_systables run_br backup full -s "local://$backup_dir" rollback_modify run_br restore full -f '*.*' -f '!mysql.bar' -s "local://$backup_dir" check + +run_br restore full -f 'mysql.bar' -s "local://$backup_dir" +run_sql "SELECT count(*) from mysql.bar;" | grep 11 + +rollback_modify +run_br restore full -f "mysql*.*" -f '!mysql.bar' -s "local://$backup_dir" +check + +add_user +add_test_data +run_br backup full -s "local://${backup_dir}1" +delete_user +delete_test_data +run_br restore full -f "mysql*.*" -f "usertest.*" -s "local://${backup_dir}1" +check2 + +delete_user +run_br restore db --db mysql -s "local://${backup_dir}1" +check2 +