From dd52e49685cca60aa0d60a966cd38ac64d9dc75e Mon Sep 17 00:00:00 2001 From: Jianjun Liao <36503113+Leavrth@users.noreply.github.com> Date: Wed, 17 Dec 2025 02:41:54 +0800 Subject: [PATCH] br: fix with sys check, check pass even privilege tables' schema are the same (#65078) close pingcap/tidb#64667 --- .../restore/snap_client/systable_restore.go | 4 +-- br/pkg/task/restore.go | 4 +++ pkg/executor/brie_utils_test.go | 35 ++++++++++++------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/br/pkg/restore/snap_client/systable_restore.go b/br/pkg/restore/snap_client/systable_restore.go index 6d2d830c75..478300014d 100644 --- a/br/pkg/restore/snap_client/systable_restore.go +++ b/br/pkg/restore/snap_client/systable_restore.go @@ -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 diff --git a/br/pkg/task/restore.go b/br/pkg/task/restore.go index 376318ec3a..de6e987c10 100644 --- a/br/pkg/task/restore.go +++ b/br/pkg/task/restore.go @@ -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 diff --git a/pkg/executor/brie_utils_test.go b/pkg/executor/brie_utils_test.go index a876a07e84..ca8e201d7d 100644 --- a/pkg/executor/brie_utils_test.go +++ b/pkg/executor/brie_utils_test.go @@ -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]) }