Skip to content

Commit

Permalink
txn: Add test for BatchResolveLock meeting pessimistic lock whose pri…
Browse files Browse the repository at this point in the history
…mary has changed (#43898) (#43945)

ref #43243
  • Loading branch information
ti-chi-bot authored May 30, 2023
1 parent 09be022 commit 23bc4d3
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 5 deletions.
4 changes: 2 additions & 2 deletions DEPS.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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:y3Xyj74aCW/5aGsbm7BdP5XphjFOVWWMZM5l6/caGzM=",
version = "v2.0.4-0.20230529083112-3abd6934a6ee",
sum = "h1:W2qQy1lwmooEdvWWV3ORyy1qrs4LEzvOsPbBri7GDLA=",
version = "v2.0.4-0.20230529120907-22ecfce6dfe8",
)
go_repository(
name = "com_github_tikv_pd_client",
Expand Down
8 changes: 8 additions & 0 deletions domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,14 @@ func (do *Domain) GetEtcdClient() *clientv3.Client {
return do.etcdClient
}

// GetPDClient returns the PD client.
func (do *Domain) GetPDClient() pd.Client {
if store, ok := do.store.(kv.StorageWithPD); ok {
return store.GetPDClient()
}
return nil
}

// LoadPrivilegeLoop create a goroutine loads privilege tables in a loop, it
// should be called only once in BootstrapSession.
func (do *Domain) LoadPrivilegeLoop(sctx sessionctx.Context) error {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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.20230529083112-3abd6934a6ee
github.com/tikv/client-go/v2 v2.0.4-0.20230529120907-22ecfce6dfe8
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
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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.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/client-go/v2 v2.0.4-0.20230529120907-22ecfce6dfe8 h1:W2qQy1lwmooEdvWWV3ORyy1qrs4LEzvOsPbBri7GDLA=
github.com/tikv/client-go/v2 v2.0.4-0.20230529120907-22ecfce6dfe8/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=
Expand Down
2 changes: 2 additions & 0 deletions tests/realtikvtest/pessimistictest/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ go_test(
"//sessionctx/variable",
"//sessiontxn",
"//store/driver/error",
"//store/gcworker",
"//store/mockstore",
"//tablecodec",
"//testkit",
Expand All @@ -35,6 +36,7 @@ go_test(
"@com_github_stretchr_testify//require",
"@com_github_tikv_client_go_v2//oracle",
"@com_github_tikv_client_go_v2//testutils",
"@com_github_tikv_client_go_v2//tikv",
"@com_github_tikv_client_go_v2//txnkv/transaction",
],
)
89 changes: 89 additions & 0 deletions tests/realtikvtest/pessimistictest/pessimistic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/sessiontxn"
storeerr "github.com/pingcap/tidb/store/driver/error"
"github.com/pingcap/tidb/store/gcworker"
"github.com/pingcap/tidb/store/mockstore"
"github.com/pingcap/tidb/tablecodec"
"github.com/pingcap/tidb/testkit"
Expand All @@ -50,6 +51,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/tikv/client-go/v2/oracle"
"github.com/tikv/client-go/v2/testutils"
"github.com/tikv/client-go/v2/tikv"
"github.com/tikv/client-go/v2/txnkv/transaction"
)

Expand Down Expand Up @@ -3608,6 +3610,93 @@ func mustRecv[T interface{}](t *testing.T, ch <-chan T) T {
panic("unreachable")
}

func TestIssue43243(t *testing.T) {
store, domain := realtikvtest.CreateMockStoreAndDomainAndSetup(t)

if *realtikvtest.WithRealTiKV {
// Disable in-memory pessimistic lock since it cannot be scanned in current implementation.
// TODO: Remove this after supporting scan lock for in-memory pessimistic lock.
tkcfg := testkit.NewTestKit(t, store)
res := tkcfg.MustQuery("show config where name = 'pessimistic-txn.in-memory' and type = 'tikv'").Rows()
if len(res) > 0 && res[0][3].(string) == "true" {
tkcfg.MustExec("set config tikv `pessimistic-txn.in-memory`=\"false\"")
tkcfg.MustQuery("show warnings").Check(testkit.Rows())
defer func() {
tkcfg.MustExec("set config tikv `pessimistic-txn.in-memory`=\"true\"")
}()
time.Sleep(time.Second)
} else {
t.Log("skip disabling in-memory pessimistic lock, current config:", res)
}
}

tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t1 (id int primary key, v int)")
tk.MustExec("create table t2 (id int primary key, v int)")
tk.MustExec("insert into t1 values (1, 1), (2, 2)")
tk.MustExec("insert into t2 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)")
tk.MustExec("set @@tidb_enable_async_commit=0")
tk.MustExec("set @@tidb_enable_1pc=0")

// Split region
{
tableID, err := strconv.ParseInt(tk.MustQuery(`select tidb_table_id from information_schema.tables where table_schema = "test" and table_name = "t2"`).Rows()[0][0].(string), 10, 64)
require.NoError(t, err)
key := tablecodec.EncodeTablePrefix(tableID)
_, err = domain.GetPDClient().SplitRegions(context.Background(), [][]byte{key})
require.NoError(t, err)
}

tk2 := testkit.NewTestKit(t, store)
tk2.MustExec("use test")
tk3 := testkit.NewTestKit(t, store)
tk3.MustExec("use test")

require.NoError(t, failpoint.Enable("tikvclient/beforeAsyncPessimisticRollback", `return("skip")`))
require.NoError(t, failpoint.Enable("tikvclient/beforeCommitSecondaries", `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/beforeCommitSecondaries"))
require.NoError(t, failpoint.Disable("tikvclient/twoPCRequestBatchSizeLimit"))
}()

tk.MustExec("begin pessimistic")
tk2.MustExec("begin pessimistic")
tk2.MustExec("update t2 set v = v + 1 where id = 2")
ch := make(chan struct{})
go func() {
tk.MustExec(`
with
c as (select /*+ MERGE() */ v from t1 where id in (1, 2))
update c join t2 on c.v = t2.id set t2.v = t2.v + 10`)
ch <- struct{}{}
}()
// tk blocked on row 2
mustTimeout(t, ch, time.Millisecond*100)
// Change the rows that should be locked by tk.
tk3.MustExec("update t1 set v = v + 3")
// Release row 2 and resume tk.
tk2.MustExec("commit")
mustRecv(t, ch)

// tk should have updated row 4 and row 5, and 4 should be the primary.
// At the same time row 1 should be the old primary, row2 points to row 1.
// Add another secondary that's smaller than the current primary.
tk.MustExec("update t2 set v = v + 10 where id = 3")
tk.MustExec("commit")

// Simulate a later GC that should resolve all stale lock produced in above steps.
currentTS, err := store.CurrentVersion(kv.GlobalTxnScope)
require.NoError(t, err)
_, err = gcworker.RunResolveLocks(context.Background(), store.(tikv.Storage), domain.GetPDClient(), currentTS.Ver, "gc-worker-test-issue43243", 1, false)
require.NoError(t, err)

// Check data consistency
tk.MustQuery("select * from t2 order by id").Check(testkit.Rows("1 1", "2 3", "3 13", "4 14", "5 15"))
}

func TestIssue42937(t *testing.T) {
store := realtikvtest.CreateMockStoreAndSetup(t)
tk := testkit.NewTestKit(t, store)
Expand Down

0 comments on commit 23bc4d3

Please sign in to comment.