diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go index d52ad7f412f95..f06a4b1c19c94 100644 --- a/ddl/db_integration_test.go +++ b/ddl/db_integration_test.go @@ -29,6 +29,7 @@ import ( _ "github.com/pingcap/tidb/autoid_service" "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/ddl/schematracker" + "github.com/pingcap/tidb/ddl/util" "github.com/pingcap/tidb/ddl/util/callback" "github.com/pingcap/tidb/domain" "github.com/pingcap/tidb/errno" @@ -4418,3 +4419,68 @@ func TestReorganizePartitionWarning(t *testing.T) { tk.MustExec("alter table t reorganize partition p0 into (partition p01 values less than (10), partition p02 values less than (20));") tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 The statistics of related partitions will be outdated after reorganizing partitions. Please use 'ANALYZE TABLE' statement if you want to update it now")) } + +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")) + ti := tbl.Meta() + require.NoError(t, err) + 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() + tbl1, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("issue52680")) + require.NoError(t, err) + ti1 := tbl1.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")) +} diff --git a/ddl/table.go b/ddl/table.go index 191d102f60dd8..0ca8ab6c4a7c5 100644 --- a/ddl/table.go +++ b/ddl/table.go @@ -533,7 +533,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) } diff --git a/meta/meta.go b/meta/meta.go index 02e99d0f106d2..b5fde687bb21d 100644 --- a/meta/meta.go +++ b/meta/meta.go @@ -761,17 +761,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) } diff --git a/meta/meta_test.go b/meta/meta_test.go index 747d64073064c..1db032fe87fdb 100644 --- a/meta/meta_test.go +++ b/meta/meta_test.go @@ -394,7 +394,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)