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) (#53186)

close #52680
  • Loading branch information
ti-chi-bot authored Jun 4, 2024
1 parent e1067d1 commit b789f60
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 5 deletions.
66 changes: 66 additions & 0 deletions ddl/db_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/ddl"
"github.com/pingcap/tidb/ddl/schematracker"
"github.com/pingcap/tidb/ddl/util"
"github.com/pingcap/tidb/domain"
"github.com/pingcap/tidb/errno"
"github.com/pingcap/tidb/infoschema"
Expand Down Expand Up @@ -4276,3 +4277,68 @@ func TestRegexpFunctionsGeneratedColumn(t *testing.T) {

tk.MustExec("drop table if exists reg_like")
}

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()
tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("issue52680"))
require.NoError(t, err)
ti := tbl.Meta()
dbInfo, ok := is.SchemaByName(model.NewCIStr("test"))
require.True(t, ok)

util.EmulatorGCDisable()
defer util.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(dbInfo.ID, 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()
tbl, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("issue52680"))
require.NoError(t, err)
ti1 := tbl.Meta()
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 ddl/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,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, tableInfo, recoverInfo.AutoIDs.RowID, recoverInfo.AutoIDs.RandomID)
err = t.CreateTableAndSetAutoID(recoverInfo.SchemaID, tableInfo, recoverInfo.AutoIDs)
if err != nil {
return ver, errors.Trace(err)
}
Expand Down
12 changes: 9 additions & 3 deletions meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,17 +699,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, tableInfo *model.TableInfo, autoIncID, autoRandID int64) error {
func (m *Meta) CreateTableAndSetAutoID(dbID int64, tableInfo *model.TableInfo, autoIDs AutoIDGroup) error {
err := m.CreateTableOrView(dbID, 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 meta/meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ func TestMeta(t *testing.T) {
ID: 3,
Name: model.NewCIStr("tbl3"),
}
err = m.CreateTableAndSetAutoID(1, tbInfo3, 123, 0)
err = m.CreateTableAndSetAutoID(1, 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 b789f60

Please sign in to comment.