Skip to content

Commit

Permalink
meta,ddl: fix duplicate entry error when insert after drop and recove…
Browse files Browse the repository at this point in the history
…r table (#52761) (#53187)

close #52680
  • Loading branch information
ti-chi-bot committed May 16, 2024
1 parent 1100794 commit 0f37766
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
62 changes: 62 additions & 0 deletions pkg/ddl/db_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
_ "github.com/pingcap/tidb/pkg/autoid_service"
"github.com/pingcap/tidb/pkg/config"
"github.com/pingcap/tidb/pkg/ddl/schematracker"
ddlutil "github.com/pingcap/tidb/pkg/ddl/util"
"github.com/pingcap/tidb/pkg/ddl/util/callback"
"github.com/pingcap/tidb/pkg/domain"
"github.com/pingcap/tidb/pkg/errno"
Expand Down Expand Up @@ -3020,3 +3021,64 @@ func TestOptimizeTable(t *testing.T) {
tk := testkit.NewTestKit(t, store)
tk.MustGetErrMsg("optimize table t", "[ddl:8200]OPTIMIZE TABLE is not supported")
}

func TestIssue52680(t *testing.T) {
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test;")
tk.MustExec("create table issue52680 (id bigint primary key auto_increment) auto_id_cache=1;")
tk.MustExec("insert into issue52680 values(default),(default);")
tk.MustQuery("select * from issue52680").Check(testkit.Rows("1", "2"))

is := dom.InfoSchema()
ti, err := is.TableInfoByName(model.NewCIStr("test"), model.NewCIStr("issue52680"))
require.NoError(t, err)

ddlutil.EmulatorGCDisable()
defer ddlutil.EmulatorGCEnable()

// For mocktikv, safe point is not initialized, we manually insert it for snapshot to use.
safePointName := "tikv_gc_safe_point"
safePointValue := "20060102-15:04:05 -0700"
safePointComment := "All versions after safe point can be accessed. (DO NOT EDIT)"
updateSafePoint := fmt.Sprintf(`INSERT INTO mysql.tidb VALUES ('%[1]s', '%[2]s', '%[3]s')
ON DUPLICATE KEY
UPDATE variable_value = '%[2]s', comment = '%[3]s'`, safePointName, safePointValue, safePointComment)
tk.MustExec(updateSafePoint)

testSteps := []struct {
sql string
expect meta.AutoIDGroup
}{
{sql: "", expect: meta.AutoIDGroup{RowID: 0, IncrementID: 4000, RandomID: 0}},
{sql: "drop table issue52680", expect: meta.AutoIDGroup{RowID: 0, IncrementID: 0, RandomID: 0}},
{sql: "recover table issue52680", expect: meta.AutoIDGroup{RowID: 0, IncrementID: 4000, RandomID: 0}},
}
for _, step := range testSteps {
if step.sql != "" {
tk.MustExec(step.sql)
}

txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMeta(txn)
idAcc := m.GetAutoIDAccessors(ti.DBID, ti.ID)
ids, err := idAcc.Get()
require.NoError(t, err)
require.Equal(t, ids, step.expect)
txn.Rollback()
}

tk.MustQuery("show table issue52680 next_row_id").Check(testkit.Rows(
"test issue52680 id 1 _TIDB_ROWID",
"test issue52680 id 3 AUTO_INCREMENT",
))

is = dom.InfoSchema()
ti1, err := is.TableInfoByName(model.NewCIStr("test"), model.NewCIStr("issue52680"))
require.NoError(t, err)
require.Equal(t, ti1.ID, ti.ID)

tk.MustExec("insert into issue52680 values(default);")
tk.MustQuery("select * from issue52680").Check(testkit.Rows("1", "2", "3"))
}
2 changes: 1 addition & 1 deletion pkg/ddl/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ func (w *worker) recoverTable(t *meta.Meta, job *model.Job, recoverInfo *Recover
tableInfo := recoverInfo.TableInfo.Clone()
tableInfo.State = model.StatePublic
tableInfo.UpdateTS = t.StartTS
err = t.CreateTableAndSetAutoID(recoverInfo.SchemaID, recoverInfo.OldSchemaName, tableInfo, recoverInfo.AutoIDs.RowID, recoverInfo.AutoIDs.RandomID)
err = t.CreateTableAndSetAutoID(recoverInfo.SchemaID, recoverInfo.OldSchemaName, tableInfo, recoverInfo.AutoIDs)
if err != nil {
return ver, errors.Trace(err)
}
Expand Down
12 changes: 9 additions & 3 deletions pkg/meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -813,17 +813,23 @@ func (m *Meta) GetMetadataLock() (enable bool, isNull bool, err error) {

// CreateTableAndSetAutoID creates a table with tableInfo in database,
// and rebases the table autoID.
func (m *Meta) CreateTableAndSetAutoID(dbID int64, dbName string, tableInfo *model.TableInfo, autoIncID, autoRandID int64) error {
func (m *Meta) CreateTableAndSetAutoID(dbID int64, dbName string, tableInfo *model.TableInfo, autoIDs AutoIDGroup) error {
err := m.CreateTableOrView(dbID, dbName, tableInfo)
if err != nil {
return errors.Trace(err)
}
_, err = m.txn.HInc(m.dbKey(dbID), m.autoTableIDKey(tableInfo.ID), autoIncID)
_, err = m.txn.HInc(m.dbKey(dbID), m.autoTableIDKey(tableInfo.ID), autoIDs.RowID)
if err != nil {
return errors.Trace(err)
}
if tableInfo.AutoRandomBits > 0 {
_, err = m.txn.HInc(m.dbKey(dbID), m.autoRandomTableIDKey(tableInfo.ID), autoRandID)
_, err = m.txn.HInc(m.dbKey(dbID), m.autoRandomTableIDKey(tableInfo.ID), autoIDs.RandomID)
if err != nil {
return errors.Trace(err)
}
}
if tableInfo.SepAutoInc() && tableInfo.GetAutoIncrementColInfo() != nil {
_, err = m.txn.HInc(m.dbKey(dbID), m.autoIncrementIDKey(tableInfo.ID), autoIDs.IncrementID)
if err != nil {
return errors.Trace(err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/meta/meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ func TestMeta(t *testing.T) {
ID: 3,
Name: model.NewCIStr("tbl3"),
}
err = m.CreateTableAndSetAutoID(1, dbInfo.Name.L, tbInfo3, 123, 0)
err = m.CreateTableAndSetAutoID(1, dbInfo.Name.L, tbInfo3, meta.AutoIDGroup{RowID: 123, IncrementID: 0})
require.NoError(t, err)
id, err := m.GetAutoIDAccessors(1, tbInfo3.ID).RowID().Get()
require.NoError(t, err)
Expand Down

0 comments on commit 0f37766

Please sign in to comment.