From 1a3841a347ce5c115034915f38a492d3298fd4d5 Mon Sep 17 00:00:00 2001 From: Yu Shuaipeng Date: Tue, 28 Aug 2018 13:50:33 +0800 Subject: [PATCH 1/5] Only rebase auto ID when needed. --- executor/write.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/executor/write.go b/executor/write.go index f1bc187617d85..b4120333189d4 100644 --- a/executor/write.go +++ b/executor/write.go @@ -73,26 +73,26 @@ func updateRecord(ctx sessionctx.Context, h int64, oldData, newData []types.Datu return false, handleChanged, newHandle, 0, errors.Trace(err) } } - // Rebase auto increment id if the field is changed. - if mysql.HasAutoIncrementFlag(col.Flag) { - if newData[i].IsNull() { - return false, handleChanged, newHandle, 0, table.ErrColumnCantNull.GenByArgs(col.Name) - } - val, errTI := newData[i].ToInt64(sc) - if errTI != nil { - return false, handleChanged, newHandle, 0, errors.Trace(errTI) - } - lastInsertID = uint64(val) - err := t.RebaseAutoID(ctx, val, true) - if err != nil { - return false, handleChanged, newHandle, 0, errors.Trace(err) - } - } cmp, err := newData[i].CompareDatum(sc, &oldData[i]) if err != nil { return false, handleChanged, newHandle, 0, errors.Trace(err) } if cmp != 0 { + // Rebase auto increment id if the field is changed. + if mysql.HasAutoIncrementFlag(col.Flag) { + if newData[i].IsNull() { + return false, handleChanged, newHandle, 0, table.ErrColumnCantNull.GenByArgs(col.Name) + } + val, errTI := newData[i].ToInt64(sc) + if errTI != nil { + return false, handleChanged, newHandle, 0, errors.Trace(errTI) + } + lastInsertID = uint64(val) + err := t.RebaseAutoID(ctx, val, true) + if err != nil { + return false, handleChanged, newHandle, 0, errors.Trace(err) + } + } changed = true modified[i] = true if col.IsPKHandleColumn(t.Meta()) { From 455b37bdf73483d4414f13bbda0aae1310f252cf Mon Sep 17 00:00:00 2001 From: Yu Shuaipeng Date: Tue, 28 Aug 2018 14:20:20 +0800 Subject: [PATCH 2/5] add a test case --- executor/write_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/executor/write_test.go b/executor/write_test.go index c7476e9a8b3ae..f39d3cc19773d 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -2031,3 +2031,23 @@ func (s *testSuite) TestReplaceLog(c *C) { tk.MustQuery(`admin cleanup index testLog b;`).Check(testkit.Rows("1")) } + +func (s *testSuite) TestRebaseIfNeeded(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec(`create table t (a int not null primary key auto_increment, b int unique key);`) + tk.MustExec(`insert into t (b) values (1);`) + + s.ctx = mock.NewContext() + s.ctx.Store = s.store + tbl, err := s.domain.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) + c.Assert(err, IsNil) + c.Assert(s.ctx.NewTxn(), IsNil) + _, err = tbl.AddRecord(s.ctx, types.MakeDatums(30001, 2), false) + c.Assert(err, IsNil) + c.Assert(s.ctx.Txn().Commit(context.Background()), IsNil) + + tk.MustExec(`update t set b = 3 where a = 30001;`) + tk.MustExec(`insert into t (b) values (4);`) + tk.MustQuery(`select a from t where b = 4;`).Check(testkit.Rows("2")) +} From 4a9a6aebe09e8aa353c695c55289ae2fb31e8650 Mon Sep 17 00:00:00 2001 From: Yu Shuaipeng Date: Tue, 28 Aug 2018 14:59:05 +0800 Subject: [PATCH 3/5] fix CI --- executor/write.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/executor/write.go b/executor/write.go index b4120333189d4..537e46f07e94d 100644 --- a/executor/write.go +++ b/executor/write.go @@ -77,22 +77,24 @@ func updateRecord(ctx sessionctx.Context, h int64, oldData, newData []types.Datu if err != nil { return false, handleChanged, newHandle, 0, errors.Trace(err) } - if cmp != 0 { - // Rebase auto increment id if the field is changed. - if mysql.HasAutoIncrementFlag(col.Flag) { - if newData[i].IsNull() { - return false, handleChanged, newHandle, 0, table.ErrColumnCantNull.GenByArgs(col.Name) - } - val, errTI := newData[i].ToInt64(sc) - if errTI != nil { - return false, handleChanged, newHandle, 0, errors.Trace(errTI) - } - lastInsertID = uint64(val) + // Rebase auto increment id if the field is changed. + if mysql.HasAutoIncrementFlag(col.Flag) { + if newData[i].IsNull() { + return false, handleChanged, newHandle, 0, table.ErrColumnCantNull.GenByArgs(col.Name) + } + val, errTI := newData[i].ToInt64(sc) + if errTI != nil { + return false, handleChanged, newHandle, 0, errors.Trace(errTI) + } + lastInsertID = uint64(val) + if cmp != 0 { err := t.RebaseAutoID(ctx, val, true) if err != nil { return false, handleChanged, newHandle, 0, errors.Trace(err) } } + } + if cmp != 0 { changed = true modified[i] = true if col.IsPKHandleColumn(t.Meta()) { From 908193d7fe125f245e85cc3c6bfb0c35e9c22b91 Mon Sep 17 00:00:00 2001 From: Yu Shuaipeng Date: Tue, 28 Aug 2018 16:06:27 +0800 Subject: [PATCH 4/5] Address comments. --- executor/write_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/executor/write_test.go b/executor/write_test.go index f39d3cc19773d..bdc5d5e96c6bd 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -2032,6 +2032,9 @@ func (s *testSuite) TestReplaceLog(c *C) { tk.MustQuery(`admin cleanup index testLog b;`).Check(testkit.Rows("1")) } +// For issue 7422. +// There is no need to do the rebase when updating a record if the auto-increment ID not changed. +// This could make the auto ID increasing speed slower. func (s *testSuite) TestRebaseIfNeeded(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") @@ -2043,6 +2046,8 @@ func (s *testSuite) TestRebaseIfNeeded(c *C) { tbl, err := s.domain.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) c.Assert(err, IsNil) c.Assert(s.ctx.NewTxn(), IsNil) + // AddRecord directly here will skip to rebase the auto ID in the insert statement, + // which could simulate another TiDB adds a large auto ID. _, err = tbl.AddRecord(s.ctx, types.MakeDatums(30001, 2), false) c.Assert(err, IsNil) c.Assert(s.ctx.Txn().Commit(context.Background()), IsNil) From 61c7e11629167771e8214454c3c5b04843eb5d4e Mon Sep 17 00:00:00 2001 From: Yu Shuaipeng Date: Thu, 30 Aug 2018 14:48:50 +0800 Subject: [PATCH 5/5] address comments --- executor/write_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/executor/write_test.go b/executor/write_test.go index e3ccb769b6588..30fa336e9d296 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -2045,4 +2045,12 @@ func (s *testSuite) TestRebaseIfNeeded(c *C) { tk.MustExec(`update t set b = 3 where a = 30001;`) tk.MustExec(`insert into t (b) values (4);`) tk.MustQuery(`select a from t where b = 4;`).Check(testkit.Rows("2")) + + tk.MustExec(`insert into t set b = 3 on duplicate key update a = a;`) + tk.MustExec(`insert into t (b) values (5);`) + tk.MustQuery(`select a from t where b = 5;`).Check(testkit.Rows("4")) + + tk.MustExec(`insert into t set b = 3 on duplicate key update a = a + 1;`) + tk.MustExec(`insert into t (b) values (6);`) + tk.MustQuery(`select a from t where b = 6;`).Check(testkit.Rows("30003")) }