Skip to content

Commit 7c6d2b6

Browse files
authored
deps: upgrade tidb release-8.5 dependency (#12589)
ref #11020
1 parent d6d53ad commit 7c6d2b6

8 files changed

Lines changed: 391 additions & 476 deletions

File tree

cdc/entry/schema_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ func TestAllTables(t *testing.T) {
130130
require.Equal(t, job.BinlogInfo.TableInfo.Name.O, tableInfos[0].TableName.Table)
131131
// add normal table
132132
job = helper.DDL2Job("create table test.t1(id int primary key)")
133+
tableIDT1 := job.BinlogInfo.TableInfo.ID
133134
require.Nil(t, schema.HandleDDLJob(job))
134135
tableInfos, err = schema.AllTables(context.Background(), job.BinlogInfo.FinishedTS)
135136
require.Nil(t, err)
@@ -138,7 +139,7 @@ func TestAllTables(t *testing.T) {
138139
require.Equal(t, model.TableName{
139140
Schema: "test",
140141
Table: "t1",
141-
TableID: 112,
142+
TableID: tableIDT1,
142143
}, tableName)
143144
// add ineligible table
144145
job = helper.DDL2Job("create table test.t2(id int)")
@@ -150,7 +151,7 @@ func TestAllTables(t *testing.T) {
150151
require.Equal(t, model.TableName{
151152
Schema: "test",
152153
Table: "t1",
153-
TableID: 112,
154+
TableID: tableIDT1,
154155
}, tableName)
155156
}
156157

dm/syncer/ddl.go

Lines changed: 115 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"time"
2020

2121
"github.com/go-mysql-org/go-mysql/replication"
22+
"github.com/pingcap/errors"
2223
"github.com/pingcap/failpoint"
2324
tidbddl "github.com/pingcap/tidb/pkg/ddl"
2425
"github.com/pingcap/tidb/pkg/meta/metabuild"
@@ -29,6 +30,7 @@ import (
2930
"github.com/pingcap/tidb/pkg/table"
3031
"github.com/pingcap/tidb/pkg/table/tables"
3132
"github.com/pingcap/tidb/pkg/types"
33+
"github.com/pingcap/tidb/pkg/util/dbterror"
3234
"github.com/pingcap/tidb/pkg/util/filter"
3335
tidbmock "github.com/pingcap/tidb/pkg/util/mock"
3436
regexprrouter "github.com/pingcap/tidb/pkg/util/regexpr-router"
@@ -1076,27 +1078,35 @@ func (ddl *DDLWorker) handleModifyColumn(qec *queryEventContext, info *ddlInfo,
10761078
if oldCol == nil {
10771079
return bf.AlterTable, nil
10781080
}
1079-
newCol := table.ToColumn(&model.ColumnInfo{
1080-
ID: oldCol.ID,
1081-
Offset: oldCol.Offset,
1082-
State: oldCol.State,
1083-
OriginDefaultValue: oldCol.OriginDefaultValue,
1084-
OriginDefaultValueBit: oldCol.OriginDefaultValueBit,
1085-
FieldType: *spec.NewColumns[0].Tp,
1086-
Name: spec.NewColumns[0].Name.Name,
1087-
Version: oldCol.Version,
1088-
})
10891081

1090-
// handle charset and collation
1091-
if err := tidbddl.ProcessColumnCharsetAndCollation(metabuild.NewContext(), oldCol, newCol, ti, spec.NewColumns[0], di); err != nil {
1092-
ddl.logger.Warn("process column charset and collation failed", zap.Error(err))
1082+
// Let TiDB build the post-DDL column definition so we stay compatible with its internal
1083+
// modify-column handling even when lower-level helpers stop being exported.
1084+
mockCtx := tidbmock.NewContext()
1085+
mockCtx.GetSessionVars().AllowRemoveAutoInc = true
1086+
jobW, err := tidbddl.GetModifiableColumnJob(
1087+
qec.tctx.Ctx,
1088+
mockCtx,
1089+
nil,
1090+
ast.Ident{Schema: di.Name, Name: ti.Name},
1091+
oldColumnName.Name,
1092+
di,
1093+
tbl,
1094+
spec,
1095+
)
1096+
if err != nil {
1097+
if et, ok := ddl.classifyUnsupportedModifyColumnEvent(info, oldCol, ti, di, spec.NewColumns[0], err); ok {
1098+
return et, nil
1099+
}
1100+
ddl.logger.Warn("build modifiable column job failed", zap.Error(err))
10931101
return bf.AlterTable, err
10941102
}
1095-
// handle column options
1096-
if err := tidbddl.ProcessModifyColumnOptions(tidbmock.NewContext(), newCol, spec.NewColumns[0].Options); err != nil {
1097-
ddl.logger.Warn("process column options failed", zap.Error(err))
1103+
args, ok := jobW.JobArgs.(*model.ModifyColumnArgs)
1104+
if !ok || args.Column == nil {
1105+
err := fmt.Errorf("unexpected modify column job args: %T", jobW.JobArgs)
1106+
ddl.logger.Warn("get modifiable column failed", zap.Error(err))
10981107
return bf.AlterTable, err
10991108
}
1109+
newCol := ddl.normalizeModifyColumnEvent(info, oldCol, args.Column, spec.NewColumns[0])
11001110

11011111
if et := ddl.needChangeColumnData(oldCol, newCol); et != bf.AlterTable {
11021112
return et, nil
@@ -1123,6 +1133,95 @@ func (ddl *DDLWorker) handleModifyColumn(qec *queryEventContext, info *ddlInfo,
11231133
}
11241134
}
11251135

1136+
func (ddl *DDLWorker) classifyUnsupportedModifyColumnEvent(
1137+
info *ddlInfo,
1138+
oldCol *table.Column,
1139+
ti *model.TableInfo,
1140+
di *model.DBInfo,
1141+
specNewColumn *ast.ColumnDef,
1142+
jobErr error,
1143+
) (bf.EventType, bool) {
1144+
cause := errors.Cause(jobErr)
1145+
if !dbterror.ErrUnsupportedModifyCharset.Equal(cause) && !dbterror.ErrUnsupportedModifyCollation.Equal(cause) {
1146+
return bf.AlterTable, false
1147+
}
1148+
1149+
// Newer TiDB rejects some MODIFY/CHANGE COLUMN charset transitions while DM still
1150+
// needs the historical event type so binlog-filter can block them before tracker/execution.
1151+
newCol := table.ToColumn(&model.ColumnInfo{
1152+
ID: oldCol.ID,
1153+
Offset: oldCol.Offset,
1154+
State: oldCol.State,
1155+
OriginDefaultValue: oldCol.OriginDefaultValue,
1156+
OriginDefaultValueBit: oldCol.OriginDefaultValueBit,
1157+
FieldType: *specNewColumn.Tp,
1158+
Name: specNewColumn.Name.Name,
1159+
Version: oldCol.Version,
1160+
})
1161+
if err := tidbddl.ProcessColumnCharsetAndCollation(metabuild.NewContext(), oldCol, newCol, ti, specNewColumn, di); err != nil {
1162+
ddl.logger.Warn("fallback classify modify column charset/collation failed",
1163+
zap.String("origin_sql", info.originDDL),
1164+
zap.Error(jobErr),
1165+
zap.Error(err),
1166+
)
1167+
return bf.AlterTable, false
1168+
}
1169+
1170+
switch {
1171+
case oldCol.GetCharset() != newCol.GetCharset():
1172+
return bf.ModifyCharset, true
1173+
case oldCol.GetCollate() != newCol.GetCollate():
1174+
return bf.ModifyCollation, true
1175+
default:
1176+
return bf.AlterTable, false
1177+
}
1178+
}
1179+
1180+
func (ddl *DDLWorker) normalizeModifyColumnEvent(
1181+
info *ddlInfo,
1182+
oldCol *table.Column,
1183+
jobCol *model.ColumnInfo,
1184+
specNewColumn *ast.ColumnDef,
1185+
) *table.Column {
1186+
eventCol := table.ToColumn(jobCol.Clone())
1187+
1188+
// TiDB's modify-column job builder preserves existing key flags so the DDL can
1189+
// execute correctly. DM's incompatible-DDL classification is historical and
1190+
// spec-based: omitted key attributes in CHANGE/MODIFY COLUMN should still be
1191+
// treated as removals for event typing.
1192+
const indexFlagMask = mysql.PriKeyFlag | mysql.UniqueKeyFlag | mysql.MultipleKeyFlag
1193+
eventCol.DelFlag(indexFlagMask)
1194+
eventCol.AddFlag(specNewColumn.Tp.GetFlag() & indexFlagMask)
1195+
1196+
hasExplicitDefault := false
1197+
for _, opt := range specNewColumn.Options {
1198+
if opt.Tp == ast.ColumnOptionDefaultValue {
1199+
hasExplicitDefault = true
1200+
break
1201+
}
1202+
}
1203+
if !hasExplicitDefault {
1204+
// Preserve the tracked schema's default when the statement does not specify
1205+
// one. This matches DM's previous event classification semantics and avoids
1206+
// misclassifying a key drop as a default-value change after earlier skipped DDLs.
1207+
eventCol.DefaultValue = oldCol.DefaultValue
1208+
eventCol.DefaultValueBit = oldCol.DefaultValueBit
1209+
eventCol.DefaultIsExpr = oldCol.DefaultIsExpr
1210+
}
1211+
1212+
ddl.logger.Debug("normalized modify column event",
1213+
zap.String("origin_sql", info.originDDL),
1214+
zap.Uint64("old_flags", uint64(oldCol.GetFlag())),
1215+
zap.Uint64("job_flags", uint64(jobCol.GetFlag())),
1216+
zap.Uint64("event_flags", uint64(eventCol.GetFlag())),
1217+
zap.Any("old_default", oldCol.GetDefaultValue()),
1218+
zap.Any("job_default", jobCol.GetDefaultValue()),
1219+
zap.Any("event_default", eventCol.GetDefaultValue()),
1220+
)
1221+
1222+
return eventCol
1223+
}
1224+
11261225
// AstToDDLEvent returns filter.DDLEvent.
11271226
func (ddl *DDLWorker) AstToDDLEvent(qec *queryEventContext, info *ddlInfo) (et bf.EventType) {
11281227
defer func() {

dm/syncer/ddl_test.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,13 @@ import (
2222
"github.com/DATA-DOG/go-sqlmock"
2323
"github.com/go-mysql-org/go-mysql/mysql"
2424
"github.com/pingcap/check"
25+
"github.com/pingcap/tidb/pkg/meta/model"
2526
"github.com/pingcap/tidb/pkg/parser"
2627
"github.com/pingcap/tidb/pkg/parser/ast"
28+
pmodel "github.com/pingcap/tidb/pkg/parser/model"
29+
tmysql "github.com/pingcap/tidb/pkg/parser/mysql"
30+
fieldtypes "github.com/pingcap/tidb/pkg/parser/types"
31+
"github.com/pingcap/tidb/pkg/table"
2732
"github.com/pingcap/tidb/pkg/util/filter"
2833
regexprrouter "github.com/pingcap/tidb/pkg/util/regexpr-router"
2934
router "github.com/pingcap/tidb/pkg/util/table-router"
@@ -36,6 +41,7 @@ import (
3641
"github.com/pingcap/tiflow/dm/pkg/terror"
3742
"github.com/pingcap/tiflow/dm/syncer/metrics"
3843
onlineddl "github.com/pingcap/tiflow/dm/syncer/online-ddl-tools"
44+
bf "github.com/pingcap/tiflow/pkg/binlog-filter"
3945
"github.com/stretchr/testify/require"
4046
"go.uber.org/zap"
4147
)
@@ -841,6 +847,110 @@ func TestAdjustCollation(t *testing.T) {
841847
}
842848
}
843849

850+
func TestNormalizeModifyColumnEventPrefersDropUniqueOverDefault(t *testing.T) {
851+
tctx := tcontext.Background().WithLogger(log.With(zap.String("test", "TestNormalizeModifyColumnEventPrefersDropUniqueOverDefault")))
852+
ddlWorker := &DDLWorker{logger: tctx.Logger}
853+
854+
p := parser.New()
855+
stmt, err := p.ParseOneStmt("alter table test.t change c_int c_int int", "", "")
856+
require.NoError(t, err)
857+
alterStmt, ok := stmt.(*ast.AlterTableStmt)
858+
require.True(t, ok)
859+
require.Len(t, alterStmt.Specs, 1)
860+
spec := alterStmt.Specs[0]
861+
862+
oldCol := table.ToColumn(&model.ColumnInfo{
863+
ID: 1,
864+
Name: pmodel.NewCIStr("c_int"),
865+
Offset: 0,
866+
DefaultValue: int64(1),
867+
OriginDefaultValue: int64(1),
868+
FieldType: *fieldtypes.NewFieldType(tmysql.TypeLong),
869+
})
870+
oldCol.AddFlag(tmysql.UniqueKeyFlag)
871+
872+
jobCol := oldCol.ColumnInfo.Clone()
873+
jobCol.DefaultValue = nil
874+
875+
eventCol := ddlWorker.normalizeModifyColumnEvent(&ddlInfo{originDDL: "alter table test.t change c_int c_int int"}, oldCol, jobCol, spec.NewColumns[0])
876+
require.Equal(t, oldCol.GetDefaultValue(), eventCol.GetDefaultValue())
877+
require.False(t, tmysql.HasUniKeyFlag(eventCol.GetFlag()))
878+
879+
eventType := ddlWorker.needChangeColumnData(oldCol, eventCol)
880+
if eventType == bf.AlterTable {
881+
switch {
882+
case tmysql.HasAutoIncrementFlag(oldCol.GetFlag()) && !tmysql.HasAutoIncrementFlag(eventCol.GetFlag()):
883+
eventType = bf.RemoveAutoIncrement
884+
case tmysql.HasPriKeyFlag(oldCol.GetFlag()) && !tmysql.HasPriKeyFlag(eventCol.GetFlag()):
885+
eventType = bf.DropPrimaryKey
886+
case tmysql.HasUniKeyFlag(oldCol.GetFlag()) && !tmysql.HasUniKeyFlag(eventCol.GetFlag()):
887+
eventType = bf.DropUniqueKey
888+
case oldCol.GetDefaultValue() != eventCol.GetDefaultValue():
889+
eventType = bf.ModifyDefaultValue
890+
}
891+
}
892+
require.Equal(t, bf.DropUniqueKey, eventType)
893+
}
894+
895+
func TestClassifyUnsupportedModifyColumnEventAsModifyCharset(t *testing.T) {
896+
tctx := tcontext.Background().WithLogger(log.With(zap.String("test", "TestClassifyUnsupportedModifyColumnEventAsModifyCharset")))
897+
898+
tableInfo := &model.TableInfo{
899+
ID: 1,
900+
Name: pmodel.NewCIStr("t"),
901+
Charset: "utf8mb4",
902+
Collate: "utf8mb4_bin",
903+
State: model.StatePublic,
904+
Columns: []*model.ColumnInfo{
905+
{
906+
ID: 1,
907+
Name: pmodel.NewCIStr("c_char"),
908+
Offset: 0,
909+
State: model.StatePublic,
910+
FieldType: *fieldtypes.NewFieldType(tmysql.TypeString),
911+
},
912+
},
913+
}
914+
tableInfo.Columns[0].SetCharset("utf8mb4")
915+
tableInfo.Columns[0].SetCollate("utf8mb4_bin")
916+
917+
dbInfo := &model.DBInfo{
918+
Name: pmodel.NewCIStr("test"),
919+
Charset: "utf8mb4",
920+
Collate: "utf8mb4_bin",
921+
}
922+
923+
ddlWorker := &DDLWorker{
924+
logger: tctx.Logger,
925+
getTableInfo: func(_ *tcontext.Context, _, _ *filter.Table) (*model.TableInfo, error) {
926+
return tableInfo.Clone(), nil
927+
},
928+
getDBInfoFromDownstream: func(_ *tcontext.Context, _, _ *filter.Table) (*model.DBInfo, error) {
929+
return dbInfo, nil
930+
},
931+
}
932+
933+
p := parser.New()
934+
stmt, err := p.ParseOneStmt("alter table test.t modify c_char char(4) character set latin1", "", "")
935+
require.NoError(t, err)
936+
alterStmt, ok := stmt.(*ast.AlterTableStmt)
937+
require.True(t, ok)
938+
require.Len(t, alterStmt.Specs, 1)
939+
940+
qec := &queryEventContext{
941+
eventContext: &eventContext{tctx: tctx},
942+
}
943+
info := &ddlInfo{
944+
originDDL: "alter table test.t modify c_char char(4) character set latin1",
945+
sourceTables: []*filter.Table{{Schema: "test", Name: "t"}},
946+
targetTables: []*filter.Table{{Schema: "test", Name: "t"}},
947+
}
948+
949+
eventType, err := ddlWorker.handleModifyColumn(qec, info, alterStmt.Specs[0])
950+
require.NoError(t, err)
951+
require.Equal(t, bf.ModifyCharset, eventType)
952+
}
953+
844954
type mockOnlinePlugin struct {
845955
toFinish map[string]struct{}
846956
}

engine/pkg/promutil/registry_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ func TestMustRegister(t *testing.T) {
100100
require.Len(t, reg.collectorByWorker["worker4"], 2)
101101
}
102102

103-
// prometheus metric name and label name only support [a-z][A-Z][0-9][_][:]
104-
// label name can't have prefix '__'
103+
// metric name must not be empty, and label name can't have prefix '__'
105104
func TestMustRegisterNotValidName(t *testing.T) {
106105
t.Parallel()
107106

@@ -116,7 +115,7 @@ func TestMustRegisterNotValidName(t *testing.T) {
116115

117116
// not a valid metric name
118117
reg.MustRegister("worker", prometheus.NewCounter(prometheus.CounterOpts{
119-
Name: "counter-5",
118+
Name: "",
120119
}))
121120
}
122121

0 commit comments

Comments
 (0)