Repository: tikv/pd (go)

Issue:
No balance operator even one disk is full  
## Bug Report

<!-- Please answer these questions before submitting your issue. Thanks! -->

### What did you do?
1、config 5 tikvs, 3 tikv has 1.5T capacity and the others has 500G.
2、Continue inject data  until one tikv is full.
  
<!-- If possible, provide a recipe for reproducing the error. -->

### What did you expect to see?

### What did you see instead?

![image](https://user-images.githubusercontent.com/9443637/163311489-ab021c99-527a-4bb9-a087-5db77c1dca63.png)

![image](https://user-images.githubusercontent.com/9443637/163311743-5fc24d65-ff0e-41ac-9ea4-040d4722381c.png)


### What version of PD are you using (`pd-server -V`)?
/ # /pd-server -V
Release Version: v6.0.0
Edition: Community
Git Commit Hash: 71f35735d7f9ff7bfa8057fbd67a039c9ea8cf75
Git Branch: heads/refs/tags/v6.0.0
UTC Build Time:  2022-03-31 11:58:41


Pull request description:
core: change scoreV2 to adapt the higher disk capacity and amp .  (#4837)
This is an automated cherry-pick of #4837

Signed-off-by: bufferflies <1045931706@qq.com>

<!--
Thank you for working on PD! Please read PD's [CONTRIBUTING](https://github.com/tikv/pd/blob/master/CONTRIBUTING.md) document **BEFORE** filing this PR.
PR Title Format:
1. pkg [, pkg2, pkg3]: what's changed
2. *: what's changed


If you want to open the **Challenge Program** pull request, please use the following template:
https://raw.githubusercontent.com/tikv/.github/master/.github/PULL_REQUEST_TEMPLATE/challenge-program.md
You can use it with query parameters: https://github.com/tikv/pd/compare/master...${you branch}?template=challenge-program.md
-->

### What problem does this PR solve?
<!--

Please create an issue first to describe the problem.
There MUST be one line starting with "Issue Number:  " and 
linking the relevant issues via the "close" or "ref".
For more info, check https://github.com/tikv/pd/blob/master/CONTRIBUTING.md#linking-issues.

-->
Issue Number: Close #4805

### What is changed and how it works?
<!--

You could use "commit message" code block to add more description to the final commit message.
For more info, check https://github.com/tikv/pd/blob/master/CONTRIBUTING.md#format-of-the-commit-message.

-->
 if  the biggest store's capacity is more than 2T , the store's score may be closed to the up score as b(1e7). so the smallest store will not be balanced even if they has less available capacity.
```commit-message
```

### Check List

<!-- Remove the items that are not applicable. -->

Tests

<!-- At least one of them must be included. -->

- Unit test

Code changes

Side effects

Related changes

### Release note

<!-- A bugfix or a new feature needs a release note. If there is no need release note, just uncomment the below line. -->

```release-note
None.
```


Patch:
diff --git a/server/core/store.go b/server/core/store.go
index 5e22b9ec0..12972f382 100644
--- a/server/core/store.go
+++ b/server/core/store.go
@@ -308,7 +308,7 @@ func (s *StoreInfo) regionScoreV2(delta int64, deviation int, lowSpaceRatio floa
 	var (
 		K, M float64 = 1, 256 // Experience value to control the weight of the available influence on score
 		F    float64 = 50     // Experience value to prevent some nodes from running out of disk space prematurely.
-		B            = 1e7
+		B            = 1e10
 	)
 	F = math.Max(F, C*(1-lowSpaceRatio))
 	var score float64


Test patch:
diff --git a/server/core/store_test.go b/server/core/store_test.go
index d377506a6..57530396c 100644
--- a/server/core/store_test.go
+++ b/server/core/store_test.go
@@ -124,5 +124,53 @@ func (s *testStoreSuite) TestLowSpaceRatio(c *C) {
 	store.regionCount = 31
 	c.Assert(store.IsLowSpace(0.8), Equals, true)
 	store.rawStats.Available = store.rawStats.Capacity >> 2
-	c.Assert(store.IsLowSpace(0.8), Equals, false)
+	c.Assert(store.IsLowSpace(0.8), IsFalse)
+}
+
+func (s *testStoreSuite) TestLowSpaceScoreV2(c *C) {
+	testdata := []struct {
+		bigger *StoreInfo
+		small  *StoreInfo
+	}{{
+		// store1 and store2 has same store available ratio and store1 less 50gb
+		bigger: NewStoreInfoWithAvailable(1, 20*gb, 100*gb, 1.4),
+		small:  NewStoreInfoWithAvailable(2, 200*gb, 1000*gb, 1.4),
+	}, {
+		// store1 and store2 has same available space and less than 50gb
+		bigger: NewStoreInfoWithAvailable(1, 10*gb, 1000*gb, 1.4),
+		small:  NewStoreInfoWithAvailable(2, 10*gb, 100*gb, 1.4),
+	}, {
+		// store1 and store2 has same available ratio less than 0.2
+		bigger: NewStoreInfoWithAvailable(1, 20*gb, 1000*gb, 1.4),
+		small:  NewStoreInfoWithAvailable(2, 10*gb, 500*gb, 1.4),
+	}, {
+		// store1 and store2 has same available ratio
+		// but the store1 ratio less than store2 ((50-10)/50=0.8<(200-100)/200=0.5)
+		bigger: NewStoreInfoWithAvailable(1, 10*gb, 100*gb, 1.4),
+		small:  NewStoreInfoWithAvailable(2, 100*gb, 1000*gb, 1.4),
+	}, {
+		// store1 and store2 has same usedSize and capacity
+		// but the bigger's amp is bigger
+		bigger: NewStoreInfoWithAvailable(1, 10*gb, 100*gb, 1.5),
+		small:  NewStoreInfoWithAvailable(2, 10*gb, 100*gb, 1.4),
+	}, {
+		// store1 and store2 has same capacity and regionSize（40g)
+		// but store1 has less available space size
+		bigger: NewStoreInfoWithAvailable(1, 60*gb, 100*gb, 1),
+		small:  NewStoreInfoWithAvailable(2, 80*gb, 100*gb, 2),
+	}, {
+		// store1 and store2 has same capacity and store2 (40g) has twice usedSize than store1 (20g)
+		// but store1 has higher amp, so store1(60g) has more regionSize (40g)
+		bigger: NewStoreInfoWithAvailable(1, 80*gb, 100*gb, 3),
+		small:  NewStoreInfoWithAvailable(2, 60*gb, 100*gb, 1),
+	}, {
+		// store1's capacity is less than store2's capacity, but store2 has more available space,
+		bigger: NewStoreInfoWithAvailable(1, 2*gb, 100*gb, 3),
+		small:  NewStoreInfoWithAvailable(2, 100*gb, 10*1000*gb, 3),
+	}}
+	for _, v := range testdata {
+		score1 := v.bigger.regionScoreV2(0, 0.0, 0.8)
+		score2 := v.small.regionScoreV2(0, 0.0, 0.8)
+		c.Assert(score1, Greater, score2)
+	}
 }
diff --git a/server/core/test_util.go b/server/core/test_util.go
index 77e944465..8444c0c32 100644
--- a/server/core/test_util.go
+++ b/server/core/test_util.go
@@ -81,6 +81,24 @@ func NewTestRegionInfo(start, end []byte) *RegionInfo {
 	}}
 }
 
+// NewStoreInfoWithAvailable is created with available and capacity
+func NewStoreInfoWithAvailable(id, available, capacity uint64, amp float64) *StoreInfo {
+	stats := &pdpb.StoreStats{}
+	stats.Capacity = capacity
+	stats.Available = available
+	usedSize := capacity - available
+	regionSize := (float64(usedSize) * amp) / mb
+	store := NewStoreInfo(
+		&metapb.Store{
+			Id: id,
+		},
+		SetStoreStats(stats),
+		SetRegionCount(int(regionSize/96)),
+		SetRegionSize(int64(regionSize)),
+	)
+	return store
+}
+
 // NewStoreInfoWithLabel is create a store with specified labels.
 func NewStoreInfoWithLabel(id uint64, regionCount int, labels map[string]string) *StoreInfo {
 	storeLabels := make([]*metapb.StoreLabel, 0, len(labels))