br: fix with sys check, check pass even privilege tables' schema are the same (#65078)

close pingcap/tidb#64667
This commit is contained in:
Jianjun Liao
2025-12-17 02:41:54 +08:00
committed by GitHub
parent 6a1556e06e
commit dd52e49685
3 changed files with 28 additions and 15 deletions

View File

@ -780,9 +780,9 @@ func (rc *SnapClient) checkPrivilegeTableRowsCollateCompatibility(
colCount := 0
for _, col := range upstreamTable.Columns {
if _, exists := collateCompatibilityColumnMap.columns[col.Name.L]; exists {
if col.GetCollate() != "utf8mb4_bin" {
if col.GetCollate() != "utf8mb4_bin" && col.GetCollate() != "utf8mb4_general_ci" {
return errors.Annotatef(berrors.ErrRestoreIncompatibleSys,
"incompatible column collate, upstream table %s.%s column %s collate should be %s",
"incompatible column collate, upstream table %s.%s column %s collate is %s but should be utf8mb4_bin",
dbNameL, tableNameL, col.Name.L, col.GetCollate())
}
colCount += 1

View File

@ -1459,6 +1459,10 @@ func runSnapshotRestore(c context.Context, mgr *conn.Mgr, g glue.Glue, cmdName s
log.Info("The system tables schema is not compatible. Fallback to logically load system tables.")
loadSysTablePhysical = false
}
if client.GetCheckPrivilegeTableRowsCollateCompatiblity() && canLoadSysTablePhysical {
log.Info("The system tables schema match so no need to set sys check collation")
client.SetCheckPrivilegeTableRowsCollateCompatiblity(false)
}
}
// preallocate the table id, because any ddl job or database creation(include checkpoint) also allocates the global ID

View File

@ -330,8 +330,8 @@ func TestBRIECreateTables(t *testing.T) {
type fakeDDLExecutor struct {
ddl.Executor
queryList []string
successQueryList []string
queryList map[string][]string
successQueryList map[string][]string
maxCount int
}
@ -341,7 +341,7 @@ func (f *fakeDDLExecutor) BatchCreateTableWithInfo(
info []*model.TableInfo,
cs ...ddl.CreateTableOption,
) error {
f.queryList = append(f.queryList, sctx.Value(sessionctx.QueryString).(string))
f.queryList[schema.O] = append(f.queryList[schema.O], sctx.Value(sessionctx.QueryString).(string))
if len(info) > f.maxCount {
switch rand.Int() % 2 {
case 0:
@ -350,7 +350,7 @@ func (f *fakeDDLExecutor) BatchCreateTableWithInfo(
return kv.ErrEntryTooLarge
}
}
f.successQueryList = append(f.successQueryList, sctx.Value(sessionctx.QueryString).(string))
f.successQueryList[info[0].Name.O] = append(f.successQueryList[info[0].Name.O], sctx.Value(sessionctx.QueryString).(string))
return nil
}
@ -388,7 +388,11 @@ func (f *fakeSessionContext) GetSessionVars() *variable.SessionVars {
}
func TestSplitTablesQueryMatch(t *testing.T) {
ddlexecutor := &fakeDDLExecutor{maxCount: 1}
ddlexecutor := &fakeDDLExecutor{
maxCount: 1,
queryList: make(map[string][]string),
successQueryList: make(map[string][]string),
}
sctx := newFakeSessionContext(ddlexecutor)
tables := map[string][]*model.TableInfo{
"test": {
@ -402,13 +406,18 @@ func TestSplitTablesQueryMatch(t *testing.T) {
err := executor.BRIECreateTables(sctx, tables, "/*from(br)*/")
require.NoError(t, err)
require.Len(t, ddlexecutor.queryList, 4)
require.Equal(t, "/*from(br)*/CREATE TABLE `t1` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;/*from(br)*/CREATE TABLE `t2` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;", ddlexecutor.queryList[0])
require.Equal(t, "/*from(br)*/CREATE TABLE `t1` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;", ddlexecutor.queryList[1])
require.Equal(t, "/*from(br)*/CREATE TABLE `t2` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;", ddlexecutor.queryList[2])
require.Equal(t, "/*from(br)*/CREATE TABLE `t3` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;", ddlexecutor.queryList[3])
require.Len(t, ddlexecutor.queryList, 2)
require.Len(t, ddlexecutor.queryList["test"], 3)
require.Len(t, ddlexecutor.queryList["test2"], 1)
require.Equal(t, "/*from(br)*/CREATE TABLE `t1` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;/*from(br)*/CREATE TABLE `t2` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;", ddlexecutor.queryList["test"][0])
require.Equal(t, "/*from(br)*/CREATE TABLE `t1` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;", ddlexecutor.queryList["test"][1])
require.Equal(t, "/*from(br)*/CREATE TABLE `t2` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;", ddlexecutor.queryList["test"][2])
require.Equal(t, "/*from(br)*/CREATE TABLE `t3` (\n\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;", ddlexecutor.queryList["test2"][0])
require.Len(t, ddlexecutor.successQueryList, 3)
require.Equal(t, ddlexecutor.queryList[1], ddlexecutor.successQueryList[0])
require.Equal(t, ddlexecutor.queryList[2], ddlexecutor.successQueryList[1])
require.Equal(t, ddlexecutor.queryList[3], ddlexecutor.successQueryList[2])
require.Len(t, ddlexecutor.successQueryList["t1"], 1)
require.Len(t, ddlexecutor.successQueryList["t2"], 1)
require.Len(t, ddlexecutor.successQueryList["t3"], 1)
require.Equal(t, ddlexecutor.queryList["test"][1], ddlexecutor.successQueryList["t1"][0])
require.Equal(t, ddlexecutor.queryList["test"][2], ddlexecutor.successQueryList["t2"][0])
require.Equal(t, ddlexecutor.queryList["test2"][0], ddlexecutor.successQueryList["t3"][0])
}