Skip to content

Commit 861da72

Browse files
authored
deps,version,logservice: bump client-go for nextgen 202603 (#5311)
ref #5206
1 parent 2966f35 commit 861da72

5 files changed

Lines changed: 215 additions & 14 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ require (
6666
github.com/spf13/pflag v1.0.7
6767
github.com/stretchr/testify v1.11.1
6868
github.com/thanhpk/randstr v1.0.6
69-
github.com/tikv/client-go/v2 v2.0.8-0.20260609065146-a68b42e6aab4
69+
github.com/tikv/client-go/v2 v2.0.8-0.20260610130222-a41cab3aaf31
7070
github.com/tikv/pd v1.1.0-beta.0.20240407022249-7179657d129b
7171
github.com/tikv/pd/client v0.0.0-20250901035025-22b7ce6d4993
7272
github.com/tinylib/msgp v1.5.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,8 +2348,8 @@ github.com/tidwall/rtred v0.1.2 h1:exmoQtOLvDoO8ud++6LwVsAMTu0KPzLTUrMln8u1yu8=
23482348
github.com/tidwall/rtred v0.1.2/go.mod h1:hd69WNXQ5RP9vHd7dqekAz+RIdtfBogmglkZSRxCHFQ=
23492349
github.com/tidwall/tinyqueue v0.1.1 h1:SpNEvEggbpyN5DIReaJ2/1ndroY8iyEGxPYxoSaymYE=
23502350
github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw=
2351-
github.com/tikv/client-go/v2 v2.0.8-0.20260609065146-a68b42e6aab4 h1:AgCJtDAdJ095IMwZLZYZXsRPc6G+KyHGURpwhPnq9XI=
2352-
github.com/tikv/client-go/v2 v2.0.8-0.20260609065146-a68b42e6aab4/go.mod h1:bXoQc3Fv0S3TGGUQ4T5cjzJ6upBxZE1JAzMpIfibttI=
2351+
github.com/tikv/client-go/v2 v2.0.8-0.20260610130222-a41cab3aaf31 h1:5iQPAzGudgcIj0xAeOSKSo4thBHnOcl+lmM4knGiqt4=
2352+
github.com/tikv/client-go/v2 v2.0.8-0.20260610130222-a41cab3aaf31/go.mod h1:bXoQc3Fv0S3TGGUQ4T5cjzJ6upBxZE1JAzMpIfibttI=
23532353
github.com/tikv/pd v1.1.0-beta.0.20240407022249-7179657d129b h1:t2XoZp4UHrkPpYPsxbRTRVExJnriWlh+ZsDIfpYyd98=
23542354
github.com/tikv/pd v1.1.0-beta.0.20240407022249-7179657d129b/go.mod h1:7HJMdb0O5umNpZIFt8e/wKAcEmH99n2HsYgXX+vZj3k=
23552355
github.com/tikv/pd/client v0.0.0-20250901035025-22b7ce6d4993 h1:3YlTVl4n/u9oWpt6O5d28XA6Lm73CbVQS2to8O/KWqE=

logservice/txnutil/lock_resolver.go

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,32 @@ func NewLockerResolver() LockResolver {
4444

4545
const scanLockLimit = 1024
4646

47+
func resolveScanLockInfos(lockInfos []*kvrpcpb.LockInfo, resolve func([]*txnkv.Lock) (int64, error)) ([]*txnkv.Lock, int64, error) {
48+
locks := make([]*txnkv.Lock, 0, len(lockInfos))
49+
for _, lockInfo := range lockInfos {
50+
sharedLockInfos := lockInfo.GetSharedLockInfos()
51+
if len(sharedLockInfos) > 0 {
52+
for _, sharedLockInfo := range sharedLockInfos {
53+
locks = append(locks, txnkv.NewLock(sharedLockInfo))
54+
}
55+
continue
56+
}
57+
locks = append(locks, txnkv.NewLock(lockInfo))
58+
}
59+
if len(locks) == 0 {
60+
return locks, 0, nil
61+
}
62+
ttl, err := resolve(locks)
63+
return locks, ttl, err
64+
}
65+
66+
func nextScanLockKey(locEndKey []byte, locks []*txnkv.Lock, ttl int64) []byte {
67+
if ttl > 0 || len(locks) < scanLockLimit {
68+
return locEndKey
69+
}
70+
return locks[len(locks)-1].Key
71+
}
72+
4773
func (r *resolver) Resolve(ctx context.Context, keyspaceID uint32, regionID uint64, maxVersion uint64) (err error) {
4874
var totalLocks []*txnkv.Lock
4975

@@ -132,21 +158,15 @@ func (r *resolver) Resolve(ctx context.Context, keyspaceID uint32, regionID uint
132158
return errors.Errorf("unexpected scanlock error: %s", locksResp)
133159
}
134160
locksInfo := locksResp.GetLocks()
135-
locks := make([]*txnkv.Lock, len(locksInfo))
136-
for i := range locksInfo {
137-
locks[i] = txnkv.NewLock(locksInfo[i])
138-
}
161+
locks, ttl, err1 := resolveScanLockInfos(locksInfo, func(locks []*txnkv.Lock) (int64, error) {
162+
return kvStorage.GetLockResolver().ResolveLocks(bo, 0, locks)
163+
})
139164
totalLocks = append(totalLocks, locks...)
140165

141-
_, err1 := kvStorage.GetLockResolver().ResolveLocks(bo, 0, locks)
142166
if err1 != nil {
143167
return errors.Trace(err1)
144168
}
145-
if len(locks) < scanLockLimit {
146-
key = loc.EndKey
147-
} else {
148-
key = locks[len(locks)-1].Key
149-
}
169+
key = nextScanLockKey(loc.EndKey, locks, ttl)
150170

151171
if len(key) == 0 || (len(loc.EndKey) != 0 && bytes.Compare(key, loc.EndKey) >= 0) {
152172
break
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright 2026 PingCAP, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package txnutil
15+
16+
import (
17+
"context"
18+
"fmt"
19+
"testing"
20+
21+
"github.com/pingcap/kvproto/pkg/kvrpcpb"
22+
"github.com/stretchr/testify/require"
23+
"github.com/tikv/client-go/v2/tikv"
24+
"github.com/tikv/client-go/v2/txnkv"
25+
"github.com/tikv/client-go/v2/txnkv/txnlock"
26+
)
27+
28+
func TestDirectSharedLockWrapperResolveFails(t *testing.T) {
29+
wrapper := &kvrpcpb.LockInfo{
30+
Key: []byte("shared-wrapper"),
31+
LockVersion: 100,
32+
LockType: kvrpcpb.Op_SharedLock,
33+
SharedLockInfos: []*kvrpcpb.LockInfo{
34+
{
35+
Key: []byte("shared-wrapper"),
36+
PrimaryLock: []byte("primary-1"),
37+
LockVersion: 101,
38+
LockType: kvrpcpb.Op_Lock,
39+
},
40+
},
41+
}
42+
lock := txnkv.NewLock(wrapper)
43+
44+
_, err := txnlock.NewLockResolver(nil).ResolveLocks(
45+
tikv.NewBackoffer(context.Background(), 1),
46+
0,
47+
[]*txnkv.Lock{lock},
48+
)
49+
50+
require.Error(t, err)
51+
require.Contains(t, err.Error(), "trying to resolve a shared lock directly")
52+
}
53+
54+
func TestResolveScanLockInfosExpandsSharedLockWrapper(t *testing.T) {
55+
sharedLock1 := &kvrpcpb.LockInfo{
56+
Key: []byte("shared-key"),
57+
PrimaryLock: []byte("primary-1"),
58+
LockVersion: 101,
59+
LockType: kvrpcpb.Op_Lock,
60+
}
61+
sharedLock2 := &kvrpcpb.LockInfo{
62+
Key: []byte("shared-key"),
63+
PrimaryLock: []byte("primary-2"),
64+
LockVersion: 102,
65+
LockType: kvrpcpb.Op_PessimisticLock,
66+
}
67+
ordinaryLock := &kvrpcpb.LockInfo{
68+
Key: []byte("ordinary-key"),
69+
PrimaryLock: []byte("ordinary-primary"),
70+
LockVersion: 103,
71+
LockType: kvrpcpb.Op_Lock,
72+
}
73+
wrapper := &kvrpcpb.LockInfo{
74+
Key: []byte("shared-key"),
75+
LockVersion: 100,
76+
LockType: kvrpcpb.Op_SharedLock,
77+
SharedLockInfos: []*kvrpcpb.LockInfo{sharedLock1, sharedLock2},
78+
}
79+
var resolvedLocks []*txnkv.Lock
80+
81+
locks, ttl, err := resolveScanLockInfos([]*kvrpcpb.LockInfo{wrapper, ordinaryLock}, func(locks []*txnkv.Lock) (int64, error) {
82+
for _, lock := range locks {
83+
if lock.LockType == kvrpcpb.Op_SharedLock {
84+
return 0, fmt.Errorf("unexpected shared lock wrapper")
85+
}
86+
}
87+
resolvedLocks = append(resolvedLocks, locks...)
88+
return 42, nil
89+
})
90+
91+
require.NoError(t, err)
92+
require.Equal(t, int64(42), ttl)
93+
require.Len(t, locks, 3)
94+
require.Equal(t, locks, resolvedLocks)
95+
require.Equal(t, []uint64{101, 102, 103}, []uint64{locks[0].TxnID, locks[1].TxnID, locks[2].TxnID})
96+
require.Equal(t, []kvrpcpb.Op{kvrpcpb.Op_Lock, kvrpcpb.Op_PessimisticLock, kvrpcpb.Op_Lock},
97+
[]kvrpcpb.Op{locks[0].LockType, locks[1].LockType, locks[2].LockType})
98+
require.Equal(t, [][]byte{[]byte("shared-key"), []byte("shared-key"), []byte("ordinary-key")},
99+
[][]byte{locks[0].Key, locks[1].Key, locks[2].Key})
100+
}
101+
102+
func TestResolveScanLockInfosKeepsOrdinaryLocks(t *testing.T) {
103+
ordinaryLock := &kvrpcpb.LockInfo{
104+
Key: []byte("ordinary-key"),
105+
PrimaryLock: []byte("ordinary-primary"),
106+
LockVersion: 103,
107+
LockType: kvrpcpb.Op_Lock,
108+
}
109+
var resolvedLocks []*txnkv.Lock
110+
111+
locks, ttl, err := resolveScanLockInfos([]*kvrpcpb.LockInfo{ordinaryLock}, func(locks []*txnkv.Lock) (int64, error) {
112+
resolvedLocks = append(resolvedLocks, locks...)
113+
return 0, nil
114+
})
115+
116+
require.NoError(t, err)
117+
require.Equal(t, int64(0), ttl)
118+
require.Len(t, locks, 1)
119+
require.Equal(t, locks, resolvedLocks)
120+
require.Equal(t, uint64(103), locks[0].TxnID)
121+
require.Equal(t, []byte("ordinary-key"), locks[0].Key)
122+
require.Equal(t, kvrpcpb.Op_Lock, locks[0].LockType)
123+
}
124+
125+
func TestNextScanLockKeyStopsAtRegionEndWhenFullPageHasLiveLocks(t *testing.T) {
126+
locks := make([]*txnkv.Lock, scanLockLimit)
127+
for i := range locks {
128+
locks[i] = &txnkv.Lock{Key: []byte("shared-key")}
129+
}
130+
131+
key := nextScanLockKey([]byte("region-end"), locks, 1)
132+
133+
require.Equal(t, []byte("region-end"), key)
134+
}
135+
136+
func TestNextScanLockKeyContinuesFromLastLockWhenFullPageHasNoLiveLocks(t *testing.T) {
137+
locks := make([]*txnkv.Lock, scanLockLimit)
138+
for i := range locks {
139+
locks[i] = &txnkv.Lock{Key: []byte("shared-key")}
140+
}
141+
locks[len(locks)-1].Key = []byte("last-lock")
142+
143+
key := nextScanLockKey([]byte("region-end"), locks, 0)
144+
145+
require.Equal(t, []byte("last-lock"), key)
146+
}
147+
148+
func TestNextScanLockKeyStopsAtRegionEndWhenPageIsNotFull(t *testing.T) {
149+
locks := []*txnkv.Lock{{Key: []byte("last-lock")}}
150+
151+
key := nextScanLockKey([]byte("region-end"), locks, 0)
152+
153+
require.Equal(t, []byte("region-end"), key)
154+
}
155+
156+
func TestSharedLockFullPageUsesResolveTTLForNextScanKey(t *testing.T) {
157+
sharedLockInfos := make([]*kvrpcpb.LockInfo, scanLockLimit)
158+
for i := range sharedLockInfos {
159+
sharedLockInfos[i] = &kvrpcpb.LockInfo{
160+
Key: []byte("shared-key"),
161+
PrimaryLock: []byte(fmt.Sprintf("primary-%d", i)),
162+
LockVersion: uint64(i + 1),
163+
LockType: kvrpcpb.Op_Lock,
164+
}
165+
}
166+
wrapper := &kvrpcpb.LockInfo{
167+
Key: []byte("shared-key"),
168+
LockType: kvrpcpb.Op_SharedLock,
169+
SharedLockInfos: sharedLockInfos,
170+
}
171+
172+
locks, ttl, err := resolveScanLockInfos([]*kvrpcpb.LockInfo{wrapper}, func(locks []*txnkv.Lock) (int64, error) {
173+
require.Len(t, locks, scanLockLimit)
174+
return 1, nil
175+
})
176+
177+
require.NoError(t, err)
178+
require.Equal(t, int64(1), ttl)
179+
require.Equal(t, []byte("region-end"), nextScanLockKey([]byte("region-end"), locks, ttl))
180+
require.Equal(t, []byte("shared-key"), nextScanLockKey([]byte("region-end"), locks, 0))
181+
}

pkg/version/check.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ var (
5050
MinTiKVVersion = semver.New("7.5.0-alpha")
5151
// maxTiKVVersion is the version of the maximum compatible TiKV.
5252
// Compatible versions are in [MinTiKVVersion, maxTiKVVersion)
53-
maxTiKVVersion = semver.New("15.0.0")
53+
maxTiKVVersion = semver.New("26.4.0")
5454

5555
// New Arch Starts From 9.0.0,
5656
// we use the minimal release version as default.

0 commit comments

Comments
 (0)