From 592f3e9d4d828e37c021c5b38d497bf38f7d4b56 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Fri, 19 Apr 2024 17:05:09 +0800 Subject: [PATCH 1/7] meta,ddl: fix duplicate entry error when insert after drop and recover table --- pkg/ddl/db_integration_test.go | 62 ++++++++++++++++++++++++++++++++++ pkg/ddl/table.go | 2 +- pkg/meta/meta.go | 12 +++++-- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/pkg/ddl/db_integration_test.go b/pkg/ddl/db_integration_test.go index f41de8b89b20..15227ec69d94 100644 --- a/pkg/ddl/db_integration_test.go +++ b/pkg/ddl/db_integration_test.go @@ -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" @@ -3014,3 +3015,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 + }{ + {"", meta.AutoIDGroup{0, 4000, 0}}, + {"drop table issue52680", meta.AutoIDGroup{0, 0, 0}}, + {"recover table issue52680", meta.AutoIDGroup{0, 4000, 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.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/pkg/ddl/table.go b/pkg/ddl/table.go index c679353f00f3..2705f18974c0 100644 --- a/pkg/ddl/table.go +++ b/pkg/ddl/table.go @@ -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) } diff --git a/pkg/meta/meta.go b/pkg/meta/meta.go index 3eb5f6e11247..5b592c8e4643 100644 --- a/pkg/meta/meta.go +++ b/pkg/meta/meta.go @@ -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() { + _, err = m.txn.HInc(m.dbKey(dbID), m.autoIncrementIDKey(tableInfo.ID), autoIDs.IncrementID) if err != nil { return errors.Trace(err) } From 2c88a6143226bfd4b3802a98bf02ee16b68ab8dd Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Fri, 19 Apr 2024 19:32:29 +0800 Subject: [PATCH 2/7] address comment --- pkg/meta/meta.go | 2 +- pkg/meta/meta_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/meta/meta.go b/pkg/meta/meta.go index 5b592c8e4643..a231a0168206 100644 --- a/pkg/meta/meta.go +++ b/pkg/meta/meta.go @@ -828,7 +828,7 @@ func (m *Meta) CreateTableAndSetAutoID(dbID int64, dbName string, tableInfo *mod return errors.Trace(err) } } - if tableInfo.SepAutoInc() { + 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/pkg/meta/meta_test.go b/pkg/meta/meta_test.go index 3d46085e685b..31abb03fe7c6 100644 --- a/pkg/meta/meta_test.go +++ b/pkg/meta/meta_test.go @@ -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) From e931f23c6a4a000085407cdccae665dd17549fb3 Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Fri, 19 Apr 2024 19:59:19 +0800 Subject: [PATCH 3/7] make lint check happy --- pkg/ddl/db_integration_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/ddl/db_integration_test.go b/pkg/ddl/db_integration_test.go index 15227ec69d94..9fc2cb0dff8e 100644 --- a/pkg/ddl/db_integration_test.go +++ b/pkg/ddl/db_integration_test.go @@ -3044,10 +3044,11 @@ func TestIssue52680(t *testing.T) { sql string expect meta.AutoIDGroup }{ - {"", meta.AutoIDGroup{0, 4000, 0}}, - {"drop table issue52680", meta.AutoIDGroup{0, 0, 0}}, - {"recover table issue52680", meta.AutoIDGroup{0, 4000, 0}}, + {sql: "", expect: meta.AutoIDGroup{0, 4000, 0}}, + {sql: "drop table issue52680", expect: meta.AutoIDGroup{0, 0, 0}}, + {sql: "recover table issue52680", expect: meta.AutoIDGroup{0, 4000, 0}}, } + for _, step := range testSteps { if step.sql != "" { tk.MustExec(step.sql) From 4ce6d4b667342d2e53109ee9d1a85d3363691dbe Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 22 Apr 2024 12:25:32 +0800 Subject: [PATCH 4/7] go vet --- pkg/ddl/db_integration_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/ddl/db_integration_test.go b/pkg/ddl/db_integration_test.go index 9fc2cb0dff8e..156f73761e0c 100644 --- a/pkg/ddl/db_integration_test.go +++ b/pkg/ddl/db_integration_test.go @@ -3044,9 +3044,9 @@ func TestIssue52680(t *testing.T) { sql string expect meta.AutoIDGroup }{ - {sql: "", expect: meta.AutoIDGroup{0, 4000, 0}}, - {sql: "drop table issue52680", expect: meta.AutoIDGroup{0, 0, 0}}, - {sql: "recover table issue52680", expect: meta.AutoIDGroup{0, 4000, 0}}, + {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 { From d361f1c08e94c23f2248e730c4da1b4bed86f87d Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 22 Apr 2024 14:19:36 +0800 Subject: [PATCH 5/7] make golint happy --- pkg/ddl/db_integration_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/ddl/db_integration_test.go b/pkg/ddl/db_integration_test.go index 156f73761e0c..061d10142dd5 100644 --- a/pkg/ddl/db_integration_test.go +++ b/pkg/ddl/db_integration_test.go @@ -3072,6 +3072,7 @@ func TestIssue52680(t *testing.T) { 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);") From 05767c8bc18bfa264b5fdb2c4f91423050a2b07b Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 22 Apr 2024 14:50:12 +0800 Subject: [PATCH 6/7] make lint happy --- pkg/ddl/db_integration_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/ddl/db_integration_test.go b/pkg/ddl/db_integration_test.go index 061d10142dd5..4fef6badd96f 100644 --- a/pkg/ddl/db_integration_test.go +++ b/pkg/ddl/db_integration_test.go @@ -3048,7 +3048,6 @@ func TestIssue52680(t *testing.T) { {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) From 3326091057451a578d9f450b099c3b47ff788bae Mon Sep 17 00:00:00 2001 From: tiancaiamao Date: Mon, 22 Apr 2024 16:02:49 +0800 Subject: [PATCH 7/7] make bazel lint check happy ... damn! --- pkg/ddl/db_integration_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/ddl/db_integration_test.go b/pkg/ddl/db_integration_test.go index 4fef6badd96f..42eb0c897af5 100644 --- a/pkg/ddl/db_integration_test.go +++ b/pkg/ddl/db_integration_test.go @@ -3061,7 +3061,6 @@ func TestIssue52680(t *testing.T) { require.NoError(t, err) require.Equal(t, ids, step.expect) txn.Rollback() - } tk.MustQuery("show table issue52680 next_row_id").Check(testkit.Rows(