Skip to content

Commit b789f60

Browse files
authored
meta,ddl: fix duplicate entry error when insert after drop and recover table (#52761) (#53186)
close #52680
1 parent e1067d1 commit b789f60

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed

ddl/db_integration_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/pingcap/tidb/config"
3131
"github.com/pingcap/tidb/ddl"
3232
"github.com/pingcap/tidb/ddl/schematracker"
33+
"github.com/pingcap/tidb/ddl/util"
3334
"github.com/pingcap/tidb/domain"
3435
"github.com/pingcap/tidb/errno"
3536
"github.com/pingcap/tidb/infoschema"
@@ -4276,3 +4277,68 @@ func TestRegexpFunctionsGeneratedColumn(t *testing.T) {
42764277

42774278
tk.MustExec("drop table if exists reg_like")
42784279
}
4280+
4281+
func TestIssue52680(t *testing.T) {
4282+
store, dom := testkit.CreateMockStoreAndDomain(t)
4283+
tk := testkit.NewTestKit(t, store)
4284+
tk.MustExec("use test;")
4285+
tk.MustExec("create table issue52680 (id bigint primary key auto_increment) auto_id_cache=1;")
4286+
tk.MustExec("insert into issue52680 values(default),(default);")
4287+
tk.MustQuery("select * from issue52680").Check(testkit.Rows("1", "2"))
4288+
4289+
is := dom.InfoSchema()
4290+
tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("issue52680"))
4291+
require.NoError(t, err)
4292+
ti := tbl.Meta()
4293+
dbInfo, ok := is.SchemaByName(model.NewCIStr("test"))
4294+
require.True(t, ok)
4295+
4296+
util.EmulatorGCDisable()
4297+
defer util.EmulatorGCEnable()
4298+
4299+
// For mocktikv, safe point is not initialized, we manually insert it for snapshot to use.
4300+
safePointName := "tikv_gc_safe_point"
4301+
safePointValue := "20060102-15:04:05 -0700"
4302+
safePointComment := "All versions after safe point can be accessed. (DO NOT EDIT)"
4303+
updateSafePoint := fmt.Sprintf(`INSERT INTO mysql.tidb VALUES ('%[1]s', '%[2]s', '%[3]s')
4304+
ON DUPLICATE KEY
4305+
UPDATE variable_value = '%[2]s', comment = '%[3]s'`, safePointName, safePointValue, safePointComment)
4306+
tk.MustExec(updateSafePoint)
4307+
4308+
testSteps := []struct {
4309+
sql string
4310+
expect meta.AutoIDGroup
4311+
}{
4312+
{sql: "", expect: meta.AutoIDGroup{RowID: 0, IncrementID: 4000, RandomID: 0}},
4313+
{sql: "drop table issue52680", expect: meta.AutoIDGroup{RowID: 0, IncrementID: 0, RandomID: 0}},
4314+
{sql: "recover table issue52680", expect: meta.AutoIDGroup{RowID: 0, IncrementID: 4000, RandomID: 0}},
4315+
}
4316+
for _, step := range testSteps {
4317+
if step.sql != "" {
4318+
tk.MustExec(step.sql)
4319+
}
4320+
4321+
txn, err := store.Begin()
4322+
require.NoError(t, err)
4323+
m := meta.NewMeta(txn)
4324+
idAcc := m.GetAutoIDAccessors(dbInfo.ID, ti.ID)
4325+
ids, err := idAcc.Get()
4326+
require.NoError(t, err)
4327+
require.Equal(t, ids, step.expect)
4328+
txn.Rollback()
4329+
}
4330+
4331+
tk.MustQuery("show table issue52680 next_row_id").Check(testkit.Rows(
4332+
"test issue52680 id 1 _TIDB_ROWID",
4333+
"test issue52680 id 3 AUTO_INCREMENT",
4334+
))
4335+
4336+
is = dom.InfoSchema()
4337+
tbl, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("issue52680"))
4338+
require.NoError(t, err)
4339+
ti1 := tbl.Meta()
4340+
require.Equal(t, ti1.ID, ti.ID)
4341+
4342+
tk.MustExec("insert into issue52680 values(default);")
4343+
tk.MustQuery("select * from issue52680").Check(testkit.Rows("1", "2", "3"))
4344+
}

ddl/table.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ func (w *worker) recoverTable(t *meta.Meta, job *model.Job, recoverInfo *Recover
528528
tableInfo := recoverInfo.TableInfo.Clone()
529529
tableInfo.State = model.StatePublic
530530
tableInfo.UpdateTS = t.StartTS
531-
err = t.CreateTableAndSetAutoID(recoverInfo.SchemaID, tableInfo, recoverInfo.AutoIDs.RowID, recoverInfo.AutoIDs.RandomID)
531+
err = t.CreateTableAndSetAutoID(recoverInfo.SchemaID, tableInfo, recoverInfo.AutoIDs)
532532
if err != nil {
533533
return ver, errors.Trace(err)
534534
}

meta/meta.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -699,17 +699,23 @@ func (m *Meta) GetMetadataLock() (enable bool, isNull bool, err error) {
699699

700700
// CreateTableAndSetAutoID creates a table with tableInfo in database,
701701
// and rebases the table autoID.
702-
func (m *Meta) CreateTableAndSetAutoID(dbID int64, tableInfo *model.TableInfo, autoIncID, autoRandID int64) error {
702+
func (m *Meta) CreateTableAndSetAutoID(dbID int64, tableInfo *model.TableInfo, autoIDs AutoIDGroup) error {
703703
err := m.CreateTableOrView(dbID, tableInfo)
704704
if err != nil {
705705
return errors.Trace(err)
706706
}
707-
_, err = m.txn.HInc(m.dbKey(dbID), m.autoTableIDKey(tableInfo.ID), autoIncID)
707+
_, err = m.txn.HInc(m.dbKey(dbID), m.autoTableIDKey(tableInfo.ID), autoIDs.RowID)
708708
if err != nil {
709709
return errors.Trace(err)
710710
}
711711
if tableInfo.AutoRandomBits > 0 {
712-
_, err = m.txn.HInc(m.dbKey(dbID), m.autoRandomTableIDKey(tableInfo.ID), autoRandID)
712+
_, err = m.txn.HInc(m.dbKey(dbID), m.autoRandomTableIDKey(tableInfo.ID), autoIDs.RandomID)
713+
if err != nil {
714+
return errors.Trace(err)
715+
}
716+
}
717+
if tableInfo.SepAutoInc() && tableInfo.GetAutoIncrementColInfo() != nil {
718+
_, err = m.txn.HInc(m.dbKey(dbID), m.autoIncrementIDKey(tableInfo.ID), autoIDs.IncrementID)
713719
if err != nil {
714720
return errors.Trace(err)
715721
}

meta/meta_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ func TestMeta(t *testing.T) {
320320
ID: 3,
321321
Name: model.NewCIStr("tbl3"),
322322
}
323-
err = m.CreateTableAndSetAutoID(1, tbInfo3, 123, 0)
323+
err = m.CreateTableAndSetAutoID(1, tbInfo3, meta.AutoIDGroup{RowID: 123, IncrementID: 0})
324324
require.NoError(t, err)
325325
id, err := m.GetAutoIDAccessors(1, tbInfo3.ID).RowID().Get()
326326
require.NoError(t, err)

0 commit comments

Comments
 (0)