From 50c70afbbfb8afded1ad1b85bf139f9f2b1520f1 Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Wed, 26 Jun 2024 10:14:51 +0800 Subject: [PATCH] config: fix the panic caused by zero RegionSplitSizeMB (#8324) (#8328) close tikv/pd#8323 Bypass the case that `RegionSplitSizeMB` might be zero in `(*StoreConfig) CheckRegionSize`. Signed-off-by: ti-chi-bot Signed-off-by: JmPotato Co-authored-by: JmPotato --- pkg/utils/typeutil/size_test.go | 16 ++++++++++++---- server/config/store_config.go | 9 +++++++-- server/config/store_config_test.go | 6 ++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/pkg/utils/typeutil/size_test.go b/pkg/utils/typeutil/size_test.go index 57c246953e4..f05e1521281 100644 --- a/pkg/utils/typeutil/size_test.go +++ b/pkg/utils/typeutil/size_test.go @@ -40,6 +40,8 @@ func TestSizeJSON(t *testing.T) { } func TestParseMbFromText(t *testing.T) { + const defaultValue = 2 + t.Parallel() re := require.New(t) testCases := []struct { @@ -47,18 +49,24 @@ func TestParseMbFromText(t *testing.T) { size uint64 }{{ body: []string{"10Mib", "10MiB", "10M", "10MB"}, - size: uint64(10), + size: 10, }, { body: []string{"10GiB", "10Gib", "10G", "10GB"}, - size: uint64(10 * units.GiB / units.MiB), + size: 10 * units.GiB / units.MiB, + }, { + body: []string{"1024KiB", "1048576"}, + size: 1, + }, { + body: []string{"100KiB", "1023KiB", "1048575", "0"}, + size: 0, }, { body: []string{"10yiB", "10aib"}, - size: uint64(1), + size: defaultValue, }} for _, testCase := range testCases { for _, b := range testCase.body { - re.Equal(int(testCase.size), int(ParseMBFromText(b, 1))) + re.Equal(testCase.size, ParseMBFromText(b, defaultValue)) } } } diff --git a/server/config/store_config.go b/server/config/store_config.go index 8f4baa91522..b7ad34a6b51 100644 --- a/server/config/store_config.go +++ b/server/config/store_config.go @@ -164,9 +164,14 @@ func (c *StoreConfig) CheckRegionSize(size, mergeSize uint64) error { if size < c.GetRegionMaxSize() { return nil } - + // This could happen when the region split size is set to a value less than 1MiB, + // which is a very extreme case, we just pass the check here to prevent panic. + regionSplitSize := c.GetRegionSplitSize() + if regionSplitSize == 0 { + return nil + } // the smallest of the split regions can not be merge again, so it's size should less merge size. - if smallSize := size % c.GetRegionSplitSize(); smallSize <= mergeSize && smallSize != 0 { + if smallSize := size % regionSplitSize; smallSize <= mergeSize && smallSize != 0 { log.Debug("region size is too small", zap.Uint64("size", size), zap.Uint64("merge-size", mergeSize), zap.Uint64("small-size", smallSize)) return errs.ErrCheckerMergeAgain.FastGenByArgs("the smallest region of the split regions is less than max-merge-region-size, " + "it will be merged again") diff --git a/server/config/store_config_test.go b/server/config/store_config_test.go index 05fb43ab5f6..b78ddd42377 100644 --- a/server/config/store_config_test.go +++ b/server/config/store_config_test.go @@ -23,6 +23,7 @@ import ( "github.com/docker/go-units" "github.com/stretchr/testify/require" + "github.com/tikv/pd/pkg/utils/typeutil" ) func TestTiKVConfig(t *testing.T) { @@ -165,4 +166,9 @@ func TestMergeCheck(t *testing.T) { re.Error(config.CheckRegionKeys(v.keys, v.mergeKeys)) } } + // Test CheckRegionSize when the region split size is 0. + config.RegionSplitSize = "100KiB" + config.RegionSplitSizeMB = typeutil.ParseMBFromText(config.RegionSplitSize, defaultRegionSplitSize) + re.Empty(config.GetRegionSplitSize()) + re.NoError(config.CheckRegionSize(defaultRegionMaxSize, 50)) }