Skip to content

Commit

Permalink
pkg/core, cluster: save kv and cache if region flashback (tikv#6911)
Browse files Browse the repository at this point in the history
ref tikv#6912, close tikv/tikv#15258

TiKV Region merge checks region in operator and in local strictly,
and drops commit merge if there is a mismatch between them.

This change is necessary to prevent flashback from blocking
Region merge. For more details, see tikv/tikv#15258.

Signed-off-by: Neil Shen <overvenus@gmail.com>

Co-authored-by: ti-chi-bot[bot] <108142056+ti-chi-bot[bot]@users.noreply.github.com>
  • Loading branch information
overvenus and ti-chi-bot[bot] committed Aug 15, 2023
1 parent adf0402 commit d486317
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
2 changes: 1 addition & 1 deletion server/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ func (c *RaftCluster) processRegionHeartbeat(region *core.RegionInfo) error {
c.coordinator.CheckTransferWitnessLeader(region)

hasRegionStats := c.regionStats != nil
// Save to storage if meta is updated.
// Save to storage if meta is updated, except for flashback.
// Save to cache if meta or leader is updated, or contains any down/pending peer.
// Mark isNew if the region in cache does not have leader.
isNew, saveKV, saveCache, needSync := regionGuide(region, origin)
Expand Down
10 changes: 10 additions & 0 deletions server/cluster/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,16 @@ func TestRegionHeartbeat(t *testing.T) {
regions[i] = region
re.NoError(cluster.processRegionHeartbeat(region))
checkRegions(re, cluster.core, regions[:i+1])

// Flashback
region = region.Clone(core.WithFlashback(true, 1))
regions[i] = region
re.NoError(cluster.processRegionHeartbeat(region))
checkRegions(re, cluster.core, regions[:i+1])
region = region.Clone(core.WithFlashback(false, 0))
regions[i] = region
re.NoError(cluster.processRegionHeartbeat(region))
checkRegions(re, cluster.core, regions[:i+1])
}

regionCounts := make(map[uint64]int)
Expand Down
13 changes: 13 additions & 0 deletions server/core/region.go
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,11 @@ func (r *RegionInfo) GetReplicationStatus() *replication_modepb.RegionReplicatio
return r.replicationStatus
}

// IsFlashbackChanged returns true if flashback changes.
func (r *RegionInfo) IsFlashbackChanged(l *RegionInfo) bool {
return r.meta.FlashbackStartTs != l.meta.FlashbackStartTs || r.meta.IsInFlashback != l.meta.IsInFlashback
}

// IsFromHeartbeat returns whether the region info is from the region heartbeat.
func (r *RegionInfo) IsFromHeartbeat() bool {
return r.fromHeartbeat
Expand Down Expand Up @@ -689,6 +694,14 @@ func GenerateRegionGuideFunc(enableLog bool) RegionGuideFunc {
(region.GetReplicationStatus().GetState() != origin.GetReplicationStatus().GetState() ||
region.GetReplicationStatus().GetStateId() != origin.GetReplicationStatus().GetStateId()) {
saveCache = true
return
}
// Do not save to kv, because 1) flashback will be eventually set to
// false, 2) flashback changes almost all regions in a cluster.
// Saving kv may downgrade PD performance when there are many regions.
if region.IsFlashbackChanged(origin) {
saveCache = true
return
}
if !origin.IsFromHeartbeat() {
isNew = true
Expand Down
8 changes: 8 additions & 0 deletions server/core/region_option.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,14 @@ func WithDecConfVer() RegionCreateOption {
}
}

// WithFlashback set region flashback states.
func WithFlashback(isInFlashback bool, flashbackTS uint64) RegionCreateOption {
return func(region *RegionInfo) {
region.meta.FlashbackStartTs = flashbackTS
region.meta.IsInFlashback = isInFlashback
}
}

// SetCPUUsage sets the CPU usage of the region.
func SetCPUUsage(v uint64) RegionCreateOption {
return func(region *RegionInfo) {
Expand Down

0 comments on commit d486317

Please sign in to comment.