Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

infoschemaV2: support create&drop&update table/schema for v2 #51424

Merged
merged 45 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
155217b
infoschema: split InfoSchemaMisc from InfoSchema interface
tiancaiamao Feb 6, 2024
6330aeb
clean up
tiancaiamao Feb 6, 2024
0b4cff2
make lint happy
tiancaiamao Feb 6, 2024
1dc7d48
fix lint
tiancaiamao Feb 6, 2024
8fd891e
fix ci
tiancaiamao Feb 6, 2024
647ca78
Merge branch 'master' into infoschema-misc
tiancaiamao Feb 7, 2024
28423d2
infoschema,domain: introduce InfoSchemaV2, core data struct etc
tiancaiamao Feb 7, 2024
7e2305e
Merge branch 'master' into infoschema-v2-pr
tiancaiamao Feb 7, 2024
22e5139
Merge branch 'master' into infoschema-v2-pr
tiancaiamao Feb 18, 2024
f0c9727
Merge branch 'master' into infoschema-v2-pr
tiancaiamao Feb 18, 2024
8e8006c
make lint happy
tiancaiamao Feb 18, 2024
aa76904
fix build
tiancaiamao Feb 18, 2024
4c9de32
fix build
tiancaiamao Feb 18, 2024
92e004e
fix buil
tiancaiamao Feb 18, 2024
69c5803
make lint happy
tiancaiamao Feb 18, 2024
520038b
add license header
tiancaiamao Feb 18, 2024
09e30c1
*: support building infoschema V2, and introduce @@tidb_enable_infosc…
tiancaiamao Feb 22, 2024
4303b09
Merge branch 'master' into builder
tiancaiamao Feb 23, 2024
2abe220
fix ci buid
tiancaiamao Feb 23, 2024
93eabe2
address comment
tiancaiamao Feb 28, 2024
a087573
Merge branch 'master' into builder
tiancaiamao Feb 28, 2024
e7f2783
fix build
tiancaiamao Feb 28, 2024
9665839
fix CI
tiancaiamao Feb 28, 2024
943377f
rename tidb_infoschema_cache_size to tidb_schema_cache_size
tiancaiamao Feb 29, 2024
15e8adc
Merge branch 'master' into builder
tiancaiamao Feb 29, 2024
eb277e9
fix build
tiancaiamao Feb 29, 2024
3b74a2d
update
ywqzzy Feb 29, 2024
b5e925d
Merge branch 'master' of https://github.com/pingcap/tidb into support…
ywqzzy Mar 1, 2024
7365317
add todo
ywqzzy Mar 1, 2024
f403d10
Merge branch 'master' of https://github.com/pingcap/tidb into support…
ywqzzy Mar 4, 2024
5f7a041
fix conflict
ywqzzy Mar 4, 2024
549bd99
fix
ywqzzy Mar 4, 2024
4ccb655
update bazel
ywqzzy Mar 4, 2024
4e17c06
remove comment
ywqzzy Mar 4, 2024
50937a6
add it
ywqzzy Mar 4, 2024
9f8d4e4
fix build
ywqzzy Mar 4, 2024
613a43a
u
ywqzzy Mar 4, 2024
5ab90cf
refine test
ywqzzy Mar 5, 2024
4f744ba
Merge branch 'master' of https://github.com/pingcap/tidb into support…
ywqzzy Mar 5, 2024
1926ec2
u
ywqzzy Mar 5, 2024
a8b954d
refine
ywqzzy Mar 5, 2024
4e7d8f2
u
ywqzzy Mar 5, 2024
392e6b8
fix reload v2 have duplicate schemas
ywqzzy Mar 5, 2024
d2c97bc
u
ywqzzy Mar 5, 2024
e7b5a51
Merge branch 'master' of https://github.com/pingcap/tidb into support…
ywqzzy Mar 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pkg/domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ func (do *Domain) loadInfoSchema(startTS uint64) (infoschema.InfoSchema, bool, i
// We can fall back to full load, don't need to return the error.
logutil.BgLogger().Error("failed to load schema diff", zap.Error(err))
}

// full load.
schemas, err := do.fetchAllSchemasWithTables(m)
if err != nil {
return nil, false, currentSchemaVersion, nil, err
Expand All @@ -303,7 +303,8 @@ func (do *Domain) loadInfoSchema(startTS uint64) (infoschema.InfoSchema, bool, i
if err != nil {
return nil, false, currentSchemaVersion, nil, err
}

// clear data
do.infoCache.Data = infoschema.NewData()
newISBuilder, err := infoschema.NewBuilder(do, do.sysFacHack, do.infoCache.Data).InitWithDBInfos(schemas, policies, resourceGroups, neededSchemaVersion)
if err != nil {
return nil, false, currentSchemaVersion, nil, err
Expand Down
109 changes: 97 additions & 12 deletions pkg/infoschema/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (b *Builder) ApplyDiff(m *meta.Meta, diff *model.SchemaDiff) ([]int64, erro
case model.ActionCreateSchema:
return nil, b.applyCreateSchema(m, diff)
case model.ActionDropSchema:
return b.applyDropSchema(diff.SchemaID), nil
return b.applyDropSchema(diff), nil
case model.ActionRecoverSchema:
return b.applyRecoverSchema(m, diff)
case model.ActionModifySchemaCharsetAndCollate:
Expand Down Expand Up @@ -399,9 +399,9 @@ func (b *Builder) dropTableForUpdate(newTableID, oldTableID int64, dbInfo *model
)
}
oldDBInfo := b.getSchemaAndCopyIfNecessary(oldRoDBInfo.Name.L)
tmpIDs = b.applyDropTable(oldDBInfo, oldTableID, tmpIDs)
tmpIDs = b.applyDropTable(diff, oldDBInfo, oldTableID, tmpIDs)
} else {
tmpIDs = b.applyDropTable(dbInfo, oldTableID, tmpIDs)
tmpIDs = b.applyDropTable(diff, dbInfo, oldTableID, tmpIDs)
}

if oldTableID != newTableID {
Expand All @@ -413,6 +413,9 @@ func (b *Builder) dropTableForUpdate(newTableID, oldTableID int64, dbInfo *model
}

func (b *Builder) applyTableUpdate(m *meta.Meta, diff *model.SchemaDiff) ([]int64, error) {
if b.enableV2 {
return b.applyTableUpdateV2(m, diff)
}
roDBInfo, ok := b.infoSchema.SchemaByID(diff.SchemaID)
if !ok {
return nil, ErrDatabaseNotExists.GenWithStackByArgs(
Expand Down Expand Up @@ -440,6 +443,34 @@ func (b *Builder) applyTableUpdate(m *meta.Meta, diff *model.SchemaDiff) ([]int6
return tblIDs, nil
}

// TODO: more UT to check the correctness.
func (b *Builder) applyTableUpdateV2(m *meta.Meta, diff *model.SchemaDiff) ([]int64, error) {
oldDBInfo, ok := b.infoschemaV2.SchemaByID(diff.SchemaID)
if !ok {
return nil, ErrDatabaseNotExists.GenWithStackByArgs(
fmt.Sprintf("(Schema ID %d)", diff.SchemaID),
)
}

oldTableID, newTableID := b.getTableIDs(diff)
b.updateBundleForTableUpdate(diff, newTableID, oldTableID)

tblIDs, allocs, err := b.dropTableForUpdate(newTableID, oldTableID, oldDBInfo, diff)
if err != nil {
return nil, err
}

if tableIDIsValid(newTableID) {
// All types except DropTableOrView.
var err error
tblIDs, err = b.applyCreateTable(m, oldDBInfo, newTableID, allocs, diff.Type, tblIDs, diff.Version)
if err != nil {
return nil, errors.Trace(err)
}
}
return tblIDs, nil
}

func filterAllocators(diff *model.SchemaDiff, oldAllocs autoid.Allocators) autoid.Allocators {
var newAllocs autoid.Allocators
switch diff.Type {
Expand Down Expand Up @@ -521,8 +552,11 @@ func (b *Builder) applyModifySchemaDefaultPlacement(m *meta.Meta, diff *model.Sc
return nil
}

func (b *Builder) applyDropSchema(schemaID int64) []int64 {
di, ok := b.infoSchema.SchemaByID(schemaID)
func (b *Builder) applyDropSchema(diff *model.SchemaDiff) []int64 {
if b.enableV2 {
return b.applyDropSchemaV2(diff)
}
di, ok := b.infoSchema.SchemaByID(diff.SchemaID)
if !ok {
return nil
}
Expand All @@ -543,11 +577,56 @@ func (b *Builder) applyDropSchema(schemaID int64) []int64 {
di = di.Clone()
for _, id := range tableIDs {
b.deleteBundle(b.infoSchema, id)
b.applyDropTable(di, id, nil)
b.applyDropTable(diff, di, id, nil)
}
return tableIDs
}

func (b *Builder) applyDropSchemaV2(diff *model.SchemaDiff) []int64 {
di, ok := b.infoschemaV2.SchemaByID(diff.SchemaID)
if !ok {
return nil
}

b.infoData.deleteDB(di.Name)
tableIDs := make([]int64, 0, len(di.Tables))
for _, tbl := range di.Tables {
tableIDs = appendAffectedIDs(tableIDs, tbl)
}

di = di.Clone()
for _, id := range tableIDs {
b.deleteBundle(b.infoSchema, id)
b.applyDropTableV2(diff, di, id, nil)
}
return tableIDs
}

func (b *Builder) applyDropTableV2(diff *model.SchemaDiff, dbInfo *model.DBInfo, tableID int64, affected []int64) []int64 {
// Remove the table in temporaryTables
if b.infoSchemaMisc.temporaryTableIDs != nil {
delete(b.infoSchemaMisc.temporaryTableIDs, tableID)
}

table, ok := b.infoschemaV2.TableByID(tableID)

if !ok {
return nil
}

b.infoData.delete(tableItem{
dbName: dbInfo.Name.L,
dbID: dbInfo.ID,
tableName: table.Meta().Name.L,
tableID: table.Meta().ID,
schemaVersion: diff.Version,
})

// The old DBInfo still holds a reference to old table info, we need to remove it.
b.deleteReferredForeignKeys(dbInfo, tableID)
return affected
}

func (b *Builder) applyRecoverSchema(m *meta.Meta, diff *model.SchemaDiff) ([]int64, error) {
if di, ok := b.infoSchema.SchemaByID(diff.SchemaID); ok {
return nil, ErrDatabaseExists.GenWithStackByArgs(
Expand Down Expand Up @@ -726,7 +805,10 @@ func ConvertOldVersionUTF8ToUTF8MB4IfNeed(tbInfo *model.TableInfo) {
}
}

func (b *Builder) applyDropTable(dbInfo *model.DBInfo, tableID int64, affected []int64) []int64 {
func (b *Builder) applyDropTable(diff *model.SchemaDiff, dbInfo *model.DBInfo, tableID int64, affected []int64) []int64 {
if b.enableV2 {
return b.applyDropTableV2(diff, dbInfo, tableID, affected)
}
bucketIdx := tableBucketIdx(tableID)
sortedTbls := b.infoSchema.sortedTablesBuckets[bucketIdx]
idx := sortedTbls.searchTable(tableID)
Expand All @@ -745,8 +827,12 @@ func (b *Builder) applyDropTable(dbInfo *model.DBInfo, tableID int64, affected [
if b.infoSchema.temporaryTableIDs != nil {
delete(b.infoSchema.temporaryTableIDs, tableID)
}

// The old DBInfo still holds a reference to old table info, we need to remove it.
b.deleteReferredForeignKeys(dbInfo, tableID)
return affected
}

func (b *Builder) deleteReferredForeignKeys(dbInfo *model.DBInfo, tableID int64) {
for i, tblInfo := range dbInfo.Tables {
if tblInfo.ID == tableID {
if i == len(dbInfo.Tables)-1 {
Expand All @@ -758,7 +844,6 @@ func (b *Builder) applyDropTable(dbInfo *model.DBInfo, tableID int64, affected [
break
}
}
return affected
}

// Build builds and returns the built infoschema.
Expand All @@ -781,8 +866,8 @@ func (b *Builder) InitWithOldInfoSchema(oldSchema InfoSchema) (*Builder, error)
}

var oldIS *infoSchema
if proxy, ok := oldSchema.(*infoschemaV2); ok {
oldIS = proxy.infoSchema
if schemaV2, ok := oldSchema.(*infoschemaV2); ok {
oldIS = schemaV2.infoSchema
} else {
oldIS = oldSchema.(*infoSchema)
}
Expand Down Expand Up @@ -914,8 +999,8 @@ func (b *Builder) createSchemaTablesForDB(di *model.DBInfo, tableFromMeta tableF
b.addTemporaryTable(tblInfo.ID)
}
}

b.addDB(schemaVersion, di, schTbls)

return nil
}

Expand Down
66 changes: 37 additions & 29 deletions pkg/infoschema/infoschema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ type infoschemaTestContext struct {
t *testing.T
re autoid.Requirement
ctx context.Context
data *infoschema.Data
is infoschema.InfoSchema
}

Expand All @@ -949,7 +950,7 @@ func (tc *infoschemaTestContext) createSchema() {
tc.dbInfo = dbInfo

// init infoschema
builder, err := infoschema.NewBuilder(tc.re, nil, nil).InitWithDBInfos([]*model.DBInfo{tc.dbInfo}, nil, nil, 1)
builder, err := infoschema.NewBuilder(tc.re, nil, tc.data).InitWithDBInfos([]*model.DBInfo{}, nil, nil, 1)
require.NoError(tc.t, err)
tc.is = builder.Build()
}
Expand All @@ -958,7 +959,7 @@ func (tc *infoschemaTestContext) runCreateSchema() {
// create schema
tc.createSchema()

tc.applyDiffAddCheck(&model.SchemaDiff{Type: model.ActionCreateSchema, SchemaID: tc.dbInfo.ID}, func(tc *infoschemaTestContext) {
tc.applyDiffAndCheck(&model.SchemaDiff{Type: model.ActionCreateSchema, SchemaID: tc.dbInfo.ID}, func(tc *infoschemaTestContext) {
dbInfo, ok := tc.is.SchemaByID(tc.dbInfo.ID)
require.True(tc.t, ok)
require.Equal(tc.t, dbInfo.Name, tc.dbInfo.Name)
Expand All @@ -977,11 +978,11 @@ func (tc *infoschemaTestContext) dropSchema() {
func (tc *infoschemaTestContext) runDropSchema() {
// create schema
tc.runCreateSchema()

// drop schema
tc.dropSchema()
tc.applyDiffAddCheck(&model.SchemaDiff{Type: model.ActionDropSchema, SchemaID: tc.dbInfo.ID}, func(tc *infoschemaTestContext) {
_, ok := tc.is.SchemaByID(tc.dbInfo.ID)

tc.applyDiffAndCheck(&model.SchemaDiff{Type: model.ActionDropSchema, SchemaID: tc.dbInfo.ID, Version: 100}, func(tc *infoschemaTestContext) {
_, ok := tc.is.SchemaByName(tc.dbInfo.Name)
require.False(tc.t, ok)
})
}
Expand Down Expand Up @@ -1024,7 +1025,7 @@ func (tc *infoschemaTestContext) runCreateTable(tblName string) int64 {
// create table
tblID := tc.createTable(tblName)

tc.applyDiffAddCheck(&model.SchemaDiff{Type: model.ActionCreateTable, SchemaID: tc.dbInfo.ID, TableID: tblID}, func(tc *infoschemaTestContext) {
tc.applyDiffAndCheck(&model.SchemaDiff{Type: model.ActionCreateTable, SchemaID: tc.dbInfo.ID, TableID: tblID}, func(tc *infoschemaTestContext) {
tbl, ok := tc.is.TableByID(tblID)
require.True(tc.t, ok)
require.Equal(tc.t, tbl.Meta().Name.O, tblName)
Expand All @@ -1047,7 +1048,7 @@ func (tc *infoschemaTestContext) runDropTable(tblName string) {

// dropTable
tc.dropTable(tblName, tblID)
tc.applyDiffAddCheck(&model.SchemaDiff{Type: model.ActionDropTable, SchemaID: tc.dbInfo.ID, TableID: tblID}, func(tc *infoschemaTestContext) {
tc.applyDiffAndCheck(&model.SchemaDiff{Type: model.ActionDropTable, SchemaID: tc.dbInfo.ID, TableID: tblID}, func(tc *infoschemaTestContext) {
tbl, ok := tc.is.TableByID(tblID)
require.False(tc.t, ok)
require.Nil(tc.t, tbl)
Expand All @@ -1070,7 +1071,7 @@ func (tc *infoschemaTestContext) runAddColumn(tblName string) {
require.NoError(tc.t, err)

tc.addColumn(tbl.Meta())
tc.applyDiffAddCheck(&model.SchemaDiff{Type: model.ActionAddColumn, SchemaID: tc.dbInfo.ID, TableID: tbl.Meta().ID}, func(tc *infoschemaTestContext) {
tc.applyDiffAndCheck(&model.SchemaDiff{Type: model.ActionAddColumn, SchemaID: tc.dbInfo.ID, TableID: tbl.Meta().ID}, func(tc *infoschemaTestContext) {
tbl, ok := tc.is.TableByID(tbl.Meta().ID)
require.True(tc.t, ok)
require.Equal(tc.t, 2, len(tbl.Cols()))
Expand Down Expand Up @@ -1103,7 +1104,7 @@ func (tc *infoschemaTestContext) runModifyColumn(tblName string) {
require.NoError(tc.t, err)

tc.modifyColumn(tbl.Meta())
tc.applyDiffAddCheck(&model.SchemaDiff{Type: model.ActionModifyColumn, SchemaID: tc.dbInfo.ID, TableID: tbl.Meta().ID}, func(tc *infoschemaTestContext) {
tc.applyDiffAndCheck(&model.SchemaDiff{Type: model.ActionModifyColumn, SchemaID: tc.dbInfo.ID, TableID: tbl.Meta().ID}, func(tc *infoschemaTestContext) {
tbl, ok := tc.is.TableByID(tbl.Meta().ID)
require.True(tc.t, ok)
require.Equal(tc.t, "test", tbl.Cols()[0].Comment)
Expand All @@ -1122,11 +1123,11 @@ func (tc *infoschemaTestContext) modifyColumn(tblInfo *model.TableInfo) {
require.NoError(tc.t, err)
}

func (tc *infoschemaTestContext) applyDiffAddCheck(diff *model.SchemaDiff, checkFn func(tc *infoschemaTestContext)) {
func (tc *infoschemaTestContext) applyDiffAndCheck(diff *model.SchemaDiff, checkFn func(tc *infoschemaTestContext)) {
txn, err := tc.re.Store().Begin()
require.NoError(tc.t, err)

builder, err := infoschema.NewBuilder(tc.re, nil, nil).InitWithOldInfoSchema(tc.is)
builder, err := infoschema.NewBuilder(tc.re, nil, tc.data).InitWithOldInfoSchema(tc.is)
require.NoError(tc.t, err)
// applyDiff
_, err = builder.ApplyDiff(meta.NewMeta(txn), diff)
Expand All @@ -1147,23 +1148,30 @@ func TestApplyDiff(t *testing.T) {
require.NoError(t, err)
}()

tc := &infoschemaTestContext{
t: t,
re: re,
ctx: kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL),
}
for i := 0; i < 2; i++ {
if i == 0 {
// enable infoschema v2.
variable.SchemaCacheSize.Store(1000000)
}

tc.runCreateSchema()
tc.clear()
tc.runDropSchema()
tc.clear()
tc.runCreateTable("test")
tc.clear()
tc.runDropTable("test")
tc.clear()

tc.runCreateTable("test")
tc.runModifyTable("test", model.ActionAddColumn)
tc.runModifyTable("test", model.ActionModifyColumn)
// TODO check all actions..
tc := &infoschemaTestContext{
t: t,
re: re,
ctx: kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL),
data: infoschema.NewData(),
}
tc.runCreateSchema()
tc.clear()
tc.runDropSchema()
tc.clear()
tc.runCreateTable("test")
tc.clear()
tc.runDropTable("test")
tc.clear()

tc.runCreateTable("test")
tc.runModifyTable("test", model.ActionAddColumn)
tc.runModifyTable("test", model.ActionModifyColumn)
}
// TODO(ywqzzy): check all actions.
}
Loading