Skip to content

Commit 1d25006

Browse files
authored
Validate ts only for stale read (#1607)
ref pingcap/tidb#59402 Signed-off-by: ekexium <[email protected]>
1 parent 34130b7 commit 1d25006

File tree

5 files changed

+23
-40
lines changed

5 files changed

+23
-40
lines changed

internal/locate/region_request_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,8 @@ func (s *testRegionRequestToSingleStoreSuite) TestRegionRequestValidateReadTS()
962962
testImpl(getTS, true, nil)
963963
testImpl(func() uint64 { return addTS(getTS(), -time.Minute) }, false, nil)
964964
testImpl(func() uint64 { return addTS(getTS(), -time.Minute) }, true, nil)
965-
testImpl(func() uint64 { return addTS(getTS(), +time.Minute) }, false, oracle.ErrFutureTSRead{})
965+
// check is skipped for normal read
966+
testImpl(func() uint64 { return addTS(getTS(), +time.Minute) }, false, nil)
966967
testImpl(func() uint64 { return addTS(getTS(), +time.Minute) }, true, oracle.ErrFutureTSRead{})
967968
testImpl(func() uint64 { return math.MaxUint64 }, false, nil)
968969
testImpl(func() uint64 { return math.MaxUint64 }, true, oracle.ErrLatestStaleRead{})

oracle/oracles/local.go

+1-19
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,9 @@ package oracles
3636

3737
import (
3838
"context"
39-
"math"
4039
"sync"
4140
"time"
4241

43-
"github.com/pingcap/errors"
4442
"github.com/tikv/client-go/v2/oracle"
4543
)
4644

@@ -152,22 +150,6 @@ func (l *localOracle) GetExternalTimestamp(ctx context.Context) (uint64, error)
152150
}
153151

154152
func (l *localOracle) ValidateReadTS(ctx context.Context, readTS uint64, isStaleRead bool, opt *oracle.Option) error {
155-
if readTS == math.MaxUint64 {
156-
if isStaleRead {
157-
return oracle.ErrLatestStaleRead{}
158-
}
159-
return nil
160-
}
161-
162-
currentTS, err := l.GetTimestamp(ctx, opt)
163-
if err != nil {
164-
return errors.Errorf("fail to validate read timestamp: %v", err)
165-
}
166-
if currentTS < readTS {
167-
return oracle.ErrFutureTSRead{
168-
ReadTS: readTS,
169-
CurrentTS: currentTS,
170-
}
171-
}
153+
// local oracle is not supposed to be used
172154
return nil
173155
}

oracle/oracles/mock.go

-18
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ package oracles
3636

3737
import (
3838
"context"
39-
"math"
4039
"sync"
4140
"time"
4241

@@ -139,23 +138,6 @@ func (o *MockOracle) SetLowResolutionTimestampUpdateInterval(time.Duration) erro
139138
}
140139

141140
func (o *MockOracle) ValidateReadTS(ctx context.Context, readTS uint64, isStaleRead bool, opt *oracle.Option) error {
142-
if readTS == math.MaxUint64 {
143-
if isStaleRead {
144-
return oracle.ErrLatestStaleRead{}
145-
}
146-
return nil
147-
}
148-
149-
currentTS, err := o.GetTimestamp(ctx, opt)
150-
if err != nil {
151-
return errors.Errorf("fail to validate read timestamp: %v", err)
152-
}
153-
if currentTS < readTS {
154-
return oracle.ErrFutureTSRead{
155-
ReadTS: readTS,
156-
CurrentTS: currentTS,
157-
}
158-
}
159141
return nil
160142
}
161143

oracle/oracles/pd.go

+15
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,22 @@ func (o *pdOracle) getCurrentTSForValidation(ctx context.Context, opt *oracle.Op
662662
}
663663
}
664664

665+
// ValidateReadTSForTidbSnapshot is a flag in context, indicating whether the read ts is for tidb_snapshot.
666+
// This is a special approach for release branches to minimize code changes to reduce risks.
667+
type ValidateReadTSForTidbSnapshot struct{}
668+
665669
func (o *pdOracle) ValidateReadTS(ctx context.Context, readTS uint64, isStaleRead bool, opt *oracle.Option) error {
670+
// For a mistake we've seen
671+
if readTS >= math.MaxInt64 && readTS < math.MaxUint64 {
672+
return errors.Errorf("MaxInt64 <= readTS < MaxUint64, readTS=%v", readTS)
673+
}
674+
675+
// only check stale reads and reads using `tidb_snapshot`
676+
forTidbSnapshot := ctx.Value(ValidateReadTSForTidbSnapshot{}) != nil
677+
if !forTidbSnapshot && !isStaleRead {
678+
return nil
679+
}
680+
666681
if readTS == math.MaxUint64 {
667682
if isStaleRead {
668683
return oracle.ErrLatestStaleRead{}

oracle/oracles/pd_test.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,6 @@ func TestValidateReadTS(t *testing.T) {
403403
}
404404

405405
testImpl(true)
406-
testImpl(false)
407406
}
408407

409408
type MockPDClientWithPause struct {
@@ -572,8 +571,9 @@ func TestValidateReadTSForNormalReadDoNotAffectUpdateInterval(t *testing.T) {
572571
mustNoNotify()
573572

574573
// It loads `ts + 3` and `ts + 4` from the mock PD, and the check cannot pass.
574+
// Updated: 2025-03-12, the non-stale read check is temporarily skipped.
575575
err = o.ValidateReadTS(ctx, ts+5, false, opt)
576-
assert.Error(t, err)
576+
assert.NoError(t, err)
577577
mustNoNotify()
578578

579579
// Do the check again. It loads `ts + 5` from the mock PD, and the check passes.
@@ -618,6 +618,9 @@ func TestSetLastTSAlwaysPushTS(t *testing.T) {
618618
}
619619

620620
func TestValidateReadTSFromDifferentSource(t *testing.T) {
621+
// Updated: 2025-03-12, the non-stale read check is temporarily skipped.
622+
t.Skip()
623+
621624
// If a ts is fetched from a different client to the same cluster, the ts might not be cached by the low resolution
622625
// ts. In this case, the validation should not be false positive.
623626
util.EnableFailpoints()

0 commit comments

Comments
 (0)