From 781252915ce9f28e9eca7c0d5a0c1cfde6d150ed Mon Sep 17 00:00:00 2001 From: Howard Lau Date: Wed, 22 Jul 2020 11:11:19 +0800 Subject: [PATCH] server/core: cherry-pick #2667 Signed-off-by: Howard Lau --- server/core/basic_cluster.go | 7 +++++- server/core/region.go | 48 +++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/server/core/basic_cluster.go b/server/core/basic_cluster.go index 1cf174961b8..0380bdb55c7 100644 --- a/server/core/basic_cluster.go +++ b/server/core/basic_cluster.go @@ -137,9 +137,14 @@ func (bc *BasicCluster) PreCheckPutRegion(region *RegionInfo) (*RegionInfo, erro } r := region.GetRegionEpoch() o := origin.GetRegionEpoch() + + // TiKV reports term after v3.0 + isTermBehind := region.GetTerm() > 0 && region.GetTerm() < origin.GetTerm() + // Region meta is stale, return an error. - if r.GetVersion() < o.GetVersion() || r.GetConfVer() < o.GetConfVer() { + if r.GetVersion() < o.GetVersion() || r.GetConfVer() < o.GetConfVer() || isTermBehind { return origin, ErrRegionIsStale(region.GetMeta(), origin.GetMeta()) } + return origin, nil } diff --git a/server/core/region.go b/server/core/region.go index 18f324f9465..1cc9e91b95e 100644 --- a/server/core/region.go +++ b/server/core/region.go @@ -30,6 +30,7 @@ import ( // RegionInfo records detail region info. // Read-Only once created. type RegionInfo struct { + term uint64 meta *metapb.Region learners []*metapb.Peer voters []*metapb.Peer @@ -87,16 +88,17 @@ func RegionFromHeartbeat(heartbeat *pdpb.RegionHeartbeatRequest) *RegionInfo { } region := &RegionInfo{ - meta: heartbeat.GetRegion(), - leader: heartbeat.GetLeader(), - downPeers: heartbeat.GetDownPeers(), - pendingPeers: heartbeat.GetPendingPeers(), - writtenBytes: heartbeat.GetBytesWritten(), - readBytes: heartbeat.GetBytesRead(), - writtenKeys: heartbeat.GetKeysWritten(), - readKeys: heartbeat.GetKeysRead(), - approximateSize: int64(regionSize), - approximateKeys: int64(heartbeat.GetApproximateKeys()), + term: heartbeat.GetTerm(), + meta: heartbeat.GetRegion(), + leader: heartbeat.GetLeader(), + downPeers: heartbeat.GetDownPeers(), + pendingPeers: heartbeat.GetPendingPeers(), + writtenBytes: heartbeat.GetBytesWritten(), + writtenKeys: heartbeat.GetKeysWritten(), + readBytes: heartbeat.GetBytesRead(), + readKeys: heartbeat.GetKeysRead(), + approximateSize: int64(regionSize), + approximateKeys: int64(heartbeat.GetApproximateKeys()), } classifyVoterAndLearner(region) @@ -115,16 +117,17 @@ func (r *RegionInfo) Clone(opts ...RegionCreateOption) *RegionInfo { } region := &RegionInfo{ - meta: proto.Clone(r.meta).(*metapb.Region), - leader: proto.Clone(r.leader).(*metapb.Peer), - downPeers: downPeers, - pendingPeers: pendingPeers, - writtenBytes: r.writtenBytes, - readBytes: r.readBytes, - writtenKeys: r.writtenKeys, - readKeys: r.readKeys, - approximateSize: r.approximateSize, - approximateKeys: r.approximateKeys, + term: r.term, + meta: proto.Clone(r.meta).(*metapb.Region), + leader: proto.Clone(r.leader).(*metapb.Peer), + downPeers: downPeers, + pendingPeers: pendingPeers, + writtenBytes: r.writtenBytes, + writtenKeys: r.writtenKeys, + readBytes: r.readBytes, + readKeys: r.readKeys, + approximateSize: r.approximateSize, + approximateKeys: r.approximateKeys, } for _, opt := range opts { @@ -134,6 +137,11 @@ func (r *RegionInfo) Clone(opts ...RegionCreateOption) *RegionInfo { return region } +// GetTerm returns the current term of the region +func (r *RegionInfo) GetTerm() uint64 { + return r.term +} + // GetLearners returns the learners. func (r *RegionInfo) GetLearners() []*metapb.Peer { return r.learners