Skip to content

Commit

Permalink
cherry pick pingcap#685 to release-4.0
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
lichunzhu authored and ti-srebot committed Jan 19, 2021
1 parent 139df44 commit 3e264c7
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
54 changes: 54 additions & 0 deletions pkg/restore/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,13 @@ func (rc *Client) createTable(
if err != nil {
return CreatedTable{}, errors.Trace(err)
}
if newTableInfo.IsCommonHandle != table.Info.IsCommonHandle {
return CreatedTable{}, errors.Annotatef(berrors.ErrRestoreModeMismatch,
"Clustered index option mismatch. Restored cluster's @@tidb_enable_clustered_index should be %v (backup table = %v, created table = %v).",
transferBoolToValue(table.Info.IsCommonHandle),
table.Info.IsCommonHandle,
newTableInfo.IsCommonHandle)
}
rules := GetRewriteRules(newTableInfo, table.Info, newTS)
et := CreatedTable{
RewriteRule: rules,
Expand Down Expand Up @@ -975,3 +982,50 @@ func (rc *Client) EnableSkipCreateSQL() {
func (rc *Client) IsSkipCreateSQL() bool {
return rc.noSchema
}

// PreCheckTableClusterIndex checks whether backup tables and existed tables have different cluster index options。
func (rc *Client) PreCheckTableClusterIndex(
tables []*utils.Table,
ddlJobs []*model.Job,
dom *domain.Domain,
) error {
for _, table := range tables {
oldTableInfo, err := rc.GetTableSchema(dom, table.DB.Name, table.Info.Name)
// table exists in database
if err == nil {
if table.Info.IsCommonHandle != oldTableInfo.IsCommonHandle {
return errors.Annotatef(berrors.ErrRestoreModeMismatch,
"Clustered index option mismatch. Restored cluster's @@tidb_enable_clustered_index should be %v (backup table = %v, created table = %v).",
transferBoolToValue(table.Info.IsCommonHandle),
table.Info.IsCommonHandle,
oldTableInfo.IsCommonHandle)
}
}
}
for _, job := range ddlJobs {
if job.Type == model.ActionCreateTable {
tableInfo := job.BinlogInfo.TableInfo
if tableInfo != nil {
oldTableInfo, err := rc.GetTableSchema(dom, model.NewCIStr(job.SchemaName), tableInfo.Name)
// table exists in database
if err == nil {
if tableInfo.IsCommonHandle != oldTableInfo.IsCommonHandle {
return errors.Annotatef(berrors.ErrRestoreModeMismatch,
"Clustered index option mismatch. Restored cluster's @@tidb_enable_clustered_index should be %v (backup table = %v, created table = %v).",
transferBoolToValue(tableInfo.IsCommonHandle),
tableInfo.IsCommonHandle,
oldTableInfo.IsCommonHandle)
}
}
}
}
}
return nil
}

func transferBoolToValue(enable bool) string {
if enable {
return "ON"
}
return "OFF"
}
62 changes: 62 additions & 0 deletions pkg/restore/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,65 @@ func (s *testRestoreClientSuite) TestIsOnline(c *C) {
client.EnableOnline()
c.Assert(client.IsOnline(), IsTrue)
}

func (s *testRestoreClientSuite) TestPreCheckTableClusterIndex(c *C) {
c.Assert(s.mock.Start(), IsNil)
defer s.mock.Stop()

client, err := restore.NewRestoreClient(gluetidb.New(), s.mock.PDClient, s.mock.Storage, nil, defaultKeepaliveCfg)
c.Assert(err, IsNil)

info, err := s.mock.Domain.GetSnapshotInfoSchema(math.MaxUint64)
c.Assert(err, IsNil)
dbSchema, isExist := info.SchemaByName(model.NewCIStr("test"))
c.Assert(isExist, IsTrue)

tables := make([]*utils.Table, 4)
intField := types.NewFieldType(mysql.TypeLong)
intField.Charset = "binary"
for i := len(tables) - 1; i >= 0; i-- {
tables[i] = &utils.Table{
DB: dbSchema,
Info: &model.TableInfo{
ID: int64(i),
Name: model.NewCIStr("test" + strconv.Itoa(i)),
Columns: []*model.ColumnInfo{{
ID: 1,
Name: model.NewCIStr("id"),
FieldType: *intField,
State: model.StatePublic,
}},
Charset: "utf8mb4",
Collate: "utf8mb4_bin",
},
}
}
_, _, err = client.CreateTables(s.mock.Domain, tables, 0)
c.Assert(err, IsNil)

// exist different tables
tables[1].Info.IsCommonHandle = true
c.Assert(client.PreCheckTableClusterIndex(tables, nil, s.mock.Domain),
ErrorMatches, `.*@@tidb_enable_clustered_index should be ON \(backup table = true, created table = false\).*`)

// exist different DDLs
jobs := []*model.Job{{
ID: 5,
Type: model.ActionCreateTable,
SchemaName: "test",
Query: "",
BinlogInfo: &model.HistoryInfo{
TableInfo: &model.TableInfo{
Name: model.NewCIStr("test1"),
IsCommonHandle: true,
},
},
}}
c.Assert(client.PreCheckTableClusterIndex(nil, jobs, s.mock.Domain),
ErrorMatches, `.*@@tidb_enable_clustered_index should be ON \(backup table = true, created table = false\).*`)

// should pass pre-check cluster index
tables[1].Info.IsCommonHandle = false
jobs[0].BinlogInfo.TableInfo.IsCommonHandle = false
c.Assert(client.PreCheckTableClusterIndex(tables, jobs, s.mock.Domain), IsNil)
}
5 changes: 5 additions & 0 deletions pkg/task/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ func RunRestore(c context.Context, g glue.Glue, cmdName string, cfg *RestoreConf
}
ddlJobs := restore.FilterDDLJobs(client.GetDDLJobs(), tables)

err = client.PreCheckTableClusterIndex(tables, ddlJobs, mgr.GetDomain())
if err != nil {
return errors.Trace(err)
}

// pre-set TiDB config for restore
restoreDBConfig := enableTiDBConfig()
defer restoreDBConfig()
Expand Down

0 comments on commit 3e264c7

Please sign in to comment.