From 17d97bd222ef3f203615abb25060ffc0bb74e3e8 Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Mon, 29 May 2023 19:06:41 +0800 Subject: [PATCH] *: Add test to cover the case that resolving prewrite lock from a stale pessimistic lock written before switching primary (#42990) (#44118) close pingcap/tidb#42937 --- DEPS.bzl | 4 +- go.mod | 2 +- go.sum | 4 +- .../pessimistictest/pessimistic_test.go | 95 +++++++++++++++++++ 4 files changed, 100 insertions(+), 5 deletions(-) diff --git a/DEPS.bzl b/DEPS.bzl index aa3c79cf50e75..843bf395ba647 100644 --- a/DEPS.bzl +++ b/DEPS.bzl @@ -3696,8 +3696,8 @@ def go_deps(): name = "com_github_tikv_client_go_v2", build_file_proto_mode = "disable_global", importpath = "github.com/tikv/client-go/v2", - sum = "h1:vo5g8Fwrzk+m7C82lejJFL4C3XYkWlt8zCQu7zG4zx0=", - version = "v2.0.4-0.20230529034545-a78518eb37da", + sum = "h1:y3Xyj74aCW/5aGsbm7BdP5XphjFOVWWMZM5l6/caGzM=", + version = "v2.0.4-0.20230529083112-3abd6934a6ee", ) go_repository( name = "com_github_tikv_pd_client", diff --git a/go.mod b/go.mod index 2f691be143351..6db497fc6ff4b 100644 --- a/go.mod +++ b/go.mod @@ -89,7 +89,7 @@ require ( github.com/stretchr/testify v1.8.0 github.com/tdakkota/asciicheck v0.1.1 github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 - github.com/tikv/client-go/v2 v2.0.4-0.20230529034545-a78518eb37da + github.com/tikv/client-go/v2 v2.0.4-0.20230529083112-3abd6934a6ee github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 github.com/twmb/murmur3 v1.1.3 diff --git a/go.sum b/go.sum index 98a667beefdf3..fc18f9a57fa75 100644 --- a/go.sum +++ b/go.sum @@ -963,8 +963,8 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2 h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ= github.com/tiancaiamao/appdash v0.0.0-20181126055449-889f96f722a2/go.mod h1:2PfKggNGDuadAa0LElHrByyrz4JPZ9fFx6Gs7nx7ZZU= -github.com/tikv/client-go/v2 v2.0.4-0.20230529034545-a78518eb37da h1:vo5g8Fwrzk+m7C82lejJFL4C3XYkWlt8zCQu7zG4zx0= -github.com/tikv/client-go/v2 v2.0.4-0.20230529034545-a78518eb37da/go.mod h1:MDT4J9LzgS7Bj1DnEq6Gk/puy6mp8TgUC92zGEVVLLg= +github.com/tikv/client-go/v2 v2.0.4-0.20230529083112-3abd6934a6ee h1:y3Xyj74aCW/5aGsbm7BdP5XphjFOVWWMZM5l6/caGzM= +github.com/tikv/client-go/v2 v2.0.4-0.20230529083112-3abd6934a6ee/go.mod h1:mmVCLP2OqWvQJPOIevQPZvGphzh/oq9vv8J5LDfpadQ= github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07 h1:ckPpxKcl75mO2N6a4cJXiZH43hvcHPpqc9dh1TmH1nc= github.com/tikv/pd/client v0.0.0-20221031025758-80f0d8ca4d07/go.mod h1:CipBxPfxPUME+BImx9MUYXCnAVLS3VJUr3mnSJwh40A= github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= diff --git a/tests/realtikvtest/pessimistictest/pessimistic_test.go b/tests/realtikvtest/pessimistictest/pessimistic_test.go index 1bb186817ce8a..64fd5047ca99a 100644 --- a/tests/realtikvtest/pessimistictest/pessimistic_test.go +++ b/tests/realtikvtest/pessimistictest/pessimistic_test.go @@ -3580,3 +3580,98 @@ func TestLazyUniquenessCheckWithSavepoint(t *testing.T) { err := tk.ExecToErr("savepoint s1") require.ErrorContains(t, err, "savepoint is not supported in pessimistic transactions when in-place constraint check is disabled") } + +func mustExecAsync(tk *testkit.TestKit, sql string, args ...interface{}) <-chan struct{} { + ch := make(chan struct{}) + go func() { + defer func() { ch <- struct{}{} }() + tk.MustExec(sql, args...) + }() + return ch +} + +func mustTimeout[T interface{}](t *testing.T, ch <-chan T, timeout time.Duration) { + select { + case res := <-ch: + require.FailNow(t, fmt.Sprintf("received signal when not expected: %v", res)) + case <-time.After(timeout): + } +} + +func mustRecv[T interface{}](t *testing.T, ch <-chan T) T { + select { + case <-time.After(time.Second): + case res := <-ch: + return res + } + require.FailNow(t, "signal not received after waiting for one second") + panic("unreachable") +} + +func TestIssue42937(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk2 := testkit.NewTestKit(t, store) + tk3 := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set @@tidb_enable_async_commit = 0") + tk.MustExec("set @@tidb_enable_1pc = 0") + tk2.MustExec("use test") + tk2.MustExec("set @@tidb_enable_async_commit = 0") + tk2.MustExec("set @@tidb_enable_1pc = 0") + tk3.MustExec("use test") + + tk.MustExec("create table t(id int primary key, v int unique)") + tk.MustExec("insert into t values (1, 10), (2, 20), (3, 30), (4, 40)") + tk.MustExec("create table t2 (id int primary key, v int)") + tk.MustExec("insert into t2 values (1, 1), (2, 2)") + + require.NoError(t, failpoint.Enable("tikvclient/beforeAsyncPessimisticRollback", `return("skip")`)) + require.NoError(t, failpoint.Enable("tikvclient/twoPCRequestBatchSizeLimit", "return")) + defer func() { + require.NoError(t, failpoint.Disable("tikvclient/beforeAsyncPessimisticRollback")) + require.NoError(t, failpoint.Disable("tikvclient/twoPCRequestBatchSizeLimit")) + }() + + tk.MustExec("begin pessimistic") + tk2.MustExec("begin pessimistic") + tk2.MustExec("update t set v = v + 1 where id = 2") + + require.NoError(t, failpoint.Enable("tikvclient/twoPCShortLockTTL", "return")) + require.NoError(t, failpoint.Enable("tikvclient/shortPessimisticLockTTL", "return")) + ch := mustExecAsync(tk, ` + with + c as (select /*+ MERGE() */ v from t2 where id = 1 or id = 2) + update c join t on c.v = t.id set t.v = t.v + 1`) + mustTimeout(t, ch, time.Millisecond*100) + + tk3.MustExec("update t2 set v = v + 2") + tk2.MustExec("commit") + <-ch + + tk.MustQuery("select id, v from t order by id").Check(testkit.Rows("1 10", "2 20", "3 31", "4 41")) + tk.MustExec("update t set v = 0 where id = 1") + + require.NoError(t, failpoint.Enable("tikvclient/beforeCommit", `1*return("delay(500)")`)) + defer func() { + require.NoError(t, failpoint.Disable("tikvclient/beforeCommit")) + }() + + ch = mustExecAsync(tk, "commit") + mustTimeout(t, ch, time.Millisecond*100) + + require.NoError(t, failpoint.Disable("tikvclient/twoPCShortLockTTL")) + require.NoError(t, failpoint.Disable("tikvclient/shortPessimisticLockTTL")) + + tk2.MustExec("insert into t values (5, 11)") + + mustRecv(t, ch) + tk.MustExec("admin check table t") + tk.MustQuery("select * from t order by id").Check(testkit.Rows( + "1 0", + "2 21", + "3 31", + "4 41", + "5 11", + )) +}