Skip to content

Commit 4b6e8ee

Browse files
authored
meta,ddl: fix duplicate entry error when insert after drop and recover table (#52761)
close #52680
1 parent 8f138d5 commit 4b6e8ee

File tree

4 files changed

+73
-5
lines changed

4 files changed

+73
-5
lines changed

pkg/ddl/db_integration_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
_ "github.com/pingcap/tidb/pkg/autoid_service"
3030
"github.com/pingcap/tidb/pkg/config"
3131
"github.com/pingcap/tidb/pkg/ddl/schematracker"
32+
ddlutil "github.com/pingcap/tidb/pkg/ddl/util"
3233
"github.com/pingcap/tidb/pkg/ddl/util/callback"
3334
"github.com/pingcap/tidb/pkg/domain"
3435
"github.com/pingcap/tidb/pkg/errno"
@@ -3014,3 +3015,64 @@ func TestOptimizeTable(t *testing.T) {
30143015
tk := testkit.NewTestKit(t, store)
30153016
tk.MustGetErrMsg("optimize table t", "[ddl:8200]OPTIMIZE TABLE is not supported")
30163017
}
3018+
3019+
func TestIssue52680(t *testing.T) {
3020+
store, dom := testkit.CreateMockStoreAndDomain(t)
3021+
tk := testkit.NewTestKit(t, store)
3022+
tk.MustExec("use test;")
3023+
tk.MustExec("create table issue52680 (id bigint primary key auto_increment) auto_id_cache=1;")
3024+
tk.MustExec("insert into issue52680 values(default),(default);")
3025+
tk.MustQuery("select * from issue52680").Check(testkit.Rows("1", "2"))
3026+
3027+
is := dom.InfoSchema()
3028+
ti, err := is.TableInfoByName(model.NewCIStr("test"), model.NewCIStr("issue52680"))
3029+
require.NoError(t, err)
3030+
3031+
ddlutil.EmulatorGCDisable()
3032+
defer ddlutil.EmulatorGCEnable()
3033+
3034+
// For mocktikv, safe point is not initialized, we manually insert it for snapshot to use.
3035+
safePointName := "tikv_gc_safe_point"
3036+
safePointValue := "20060102-15:04:05 -0700"
3037+
safePointComment := "All versions after safe point can be accessed. (DO NOT EDIT)"
3038+
updateSafePoint := fmt.Sprintf(`INSERT INTO mysql.tidb VALUES ('%[1]s', '%[2]s', '%[3]s')
3039+
ON DUPLICATE KEY
3040+
UPDATE variable_value = '%[2]s', comment = '%[3]s'`, safePointName, safePointValue, safePointComment)
3041+
tk.MustExec(updateSafePoint)
3042+
3043+
testSteps := []struct {
3044+
sql string
3045+
expect meta.AutoIDGroup
3046+
}{
3047+
{sql: "", expect: meta.AutoIDGroup{RowID: 0, IncrementID: 4000, RandomID: 0}},
3048+
{sql: "drop table issue52680", expect: meta.AutoIDGroup{RowID: 0, IncrementID: 0, RandomID: 0}},
3049+
{sql: "recover table issue52680", expect: meta.AutoIDGroup{RowID: 0, IncrementID: 4000, RandomID: 0}},
3050+
}
3051+
for _, step := range testSteps {
3052+
if step.sql != "" {
3053+
tk.MustExec(step.sql)
3054+
}
3055+
3056+
txn, err := store.Begin()
3057+
require.NoError(t, err)
3058+
m := meta.NewMeta(txn)
3059+
idAcc := m.GetAutoIDAccessors(ti.DBID, ti.ID)
3060+
ids, err := idAcc.Get()
3061+
require.NoError(t, err)
3062+
require.Equal(t, ids, step.expect)
3063+
txn.Rollback()
3064+
}
3065+
3066+
tk.MustQuery("show table issue52680 next_row_id").Check(testkit.Rows(
3067+
"test issue52680 id 1 _TIDB_ROWID",
3068+
"test issue52680 id 3 AUTO_INCREMENT",
3069+
))
3070+
3071+
is = dom.InfoSchema()
3072+
ti1, err := is.TableInfoByName(model.NewCIStr("test"), model.NewCIStr("issue52680"))
3073+
require.NoError(t, err)
3074+
require.Equal(t, ti1.ID, ti.ID)
3075+
3076+
tk.MustExec("insert into issue52680 values(default);")
3077+
tk.MustQuery("select * from issue52680").Check(testkit.Rows("1", "2", "3"))
3078+
}

pkg/ddl/table.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ func (w *worker) recoverTable(t *meta.Meta, job *model.Job, recoverInfo *Recover
560560
tableInfo := recoverInfo.TableInfo.Clone()
561561
tableInfo.State = model.StatePublic
562562
tableInfo.UpdateTS = t.StartTS
563-
err = t.CreateTableAndSetAutoID(recoverInfo.SchemaID, recoverInfo.OldSchemaName, tableInfo, recoverInfo.AutoIDs.RowID, recoverInfo.AutoIDs.RandomID)
563+
err = t.CreateTableAndSetAutoID(recoverInfo.SchemaID, recoverInfo.OldSchemaName, tableInfo, recoverInfo.AutoIDs)
564564
if err != nil {
565565
return ver, errors.Trace(err)
566566
}

pkg/meta/meta.go

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

814814
// CreateTableAndSetAutoID creates a table with tableInfo in database,
815815
// and rebases the table autoID.
816-
func (m *Meta) CreateTableAndSetAutoID(dbID int64, dbName string, tableInfo *model.TableInfo, autoIncID, autoRandID int64) error {
816+
func (m *Meta) CreateTableAndSetAutoID(dbID int64, dbName string, tableInfo *model.TableInfo, autoIDs AutoIDGroup) error {
817817
err := m.CreateTableOrView(dbID, dbName, tableInfo)
818818
if err != nil {
819819
return errors.Trace(err)
820820
}
821-
_, err = m.txn.HInc(m.dbKey(dbID), m.autoTableIDKey(tableInfo.ID), autoIncID)
821+
_, err = m.txn.HInc(m.dbKey(dbID), m.autoTableIDKey(tableInfo.ID), autoIDs.RowID)
822822
if err != nil {
823823
return errors.Trace(err)
824824
}
825825
if tableInfo.AutoRandomBits > 0 {
826-
_, err = m.txn.HInc(m.dbKey(dbID), m.autoRandomTableIDKey(tableInfo.ID), autoRandID)
826+
_, err = m.txn.HInc(m.dbKey(dbID), m.autoRandomTableIDKey(tableInfo.ID), autoIDs.RandomID)
827+
if err != nil {
828+
return errors.Trace(err)
829+
}
830+
}
831+
if tableInfo.SepAutoInc() && tableInfo.GetAutoIncrementColInfo() != nil {
832+
_, err = m.txn.HInc(m.dbKey(dbID), m.autoIncrementIDKey(tableInfo.ID), autoIDs.IncrementID)
827833
if err != nil {
828834
return errors.Trace(err)
829835
}

pkg/meta/meta_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ func TestMeta(t *testing.T) {
360360
ID: 3,
361361
Name: model.NewCIStr("tbl3"),
362362
}
363-
err = m.CreateTableAndSetAutoID(1, dbInfo.Name.L, tbInfo3, 123, 0)
363+
err = m.CreateTableAndSetAutoID(1, dbInfo.Name.L, tbInfo3, meta.AutoIDGroup{RowID: 123, IncrementID: 0})
364364
require.NoError(t, err)
365365
id, err := m.GetAutoIDAccessors(1, tbInfo3.ID).RowID().Get()
366366
require.NoError(t, err)

0 commit comments

Comments
 (0)