Skip to content

Commit

Permalink
Recommend default_toast_compression=lz4 & jit=off
Browse files Browse the repository at this point in the history
- Added to "misc" group
- Only provide recommendation on supported versions
  • Loading branch information
matthewmcnew committed Nov 7, 2024
1 parent ac20bcd commit 173fd73
Show file tree
Hide file tree
Showing 4 changed files with 249 additions and 109 deletions.
79 changes: 53 additions & 26 deletions pkg/pgtune/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ const (
AutovacuumNaptimeKey = "autovacuum_naptime"
EffectiveIOKey = "effective_io_concurrency" // linux only

// nonnumeric
DefaultToastCompression = "default_toast_compression"
Jit = "jit"

checkpointDefault = "0.9"
statsTargetDefault = "100"
randomPageCostDefault = "1.1"
Expand All @@ -31,6 +35,8 @@ const (
// https://www.postgresql.org/message-id/20210422195232.GA25061%40momjian.us
effectiveIODefaultOldVersions = "200"
effectiveIODefault = "256"
lz4Compression = "lz4"
off = "off"

// If you want to lower this value, consider that Patroni will not accept anything less than 25 as
// a valid max_connections and will replace it with 100, per
Expand Down Expand Up @@ -59,12 +65,18 @@ func getMaxConns(totalMemory uint64) uint64 {
}
}

func getValueForVersion(currentVersion string, oldVersions []string, oldVersionValue, newVersionValue string) string {
for _, ov := range oldVersions {
if ov == currentVersion {
return oldVersionValue
}
}
return newVersionValue
}

func getEffectiveIOConcurrency(pgMajorVersion string) string {
switch pgMajorVersion {
case pgutils.MajorVersion96,
pgutils.MajorVersion10,
pgutils.MajorVersion11,
pgutils.MajorVersion12:
case pgutils.MajorVersion96, pgutils.MajorVersion10, pgutils.MajorVersion11, pgutils.MajorVersion12:
return effectiveIODefaultOldVersions
}
return effectiveIODefault
Expand All @@ -90,7 +102,10 @@ var MiscKeys = []string{
MaxLocksPerTxKey,
AutovacuumMaxWorkersKey,
AutovacuumNaptimeKey,
EffectiveIOKey,
DefaultToastCompression,
Jit,

EffectiveIOKey, //linux only
}

// MiscRecommender gives recommendations for MiscKeys based on system resources.
Expand All @@ -113,37 +128,49 @@ func (r *MiscRecommender) IsAvailable() bool {
// Recommend returns the recommended PostgreSQL formatted value for the conf
// file for a given key.
func (r *MiscRecommender) Recommend(key string) string {
var val string
if key == CheckpointKey {
val = checkpointDefault
} else if key == StatsTargetKey {
val = statsTargetDefault
} else if key == MaxConnectionsKey {
conns := getMaxConns(r.totalMemory)
switch key {
case CheckpointKey:
return checkpointDefault
case StatsTargetKey:
return statsTargetDefault
case AutovacuumMaxWorkersKey:
return autovacuumMaxWorkersDefault
case AutovacuumNaptimeKey:
return autovacuumNaptimeDefault
case RandomPageCostKey:
return randomPageCostDefault
case EffectiveIOKey:
return getValueForVersion(r.pgMajorVersion, []string{
pgutils.MajorVersion96, pgutils.MajorVersion10, pgutils.MajorVersion11, pgutils.MajorVersion12},
effectiveIODefaultOldVersions, effectiveIODefault,
)
case DefaultToastCompression:
return getValueForVersion(r.pgMajorVersion, []string{
pgutils.MajorVersion96, pgutils.MajorVersion10, pgutils.MajorVersion11, pgutils.MajorVersion12, pgutils.MajorVersion13},
NoRecommendation, lz4Compression,
)
case Jit:
return getValueForVersion(r.pgMajorVersion, []string{
pgutils.MajorVersion96, pgutils.MajorVersion10, pgutils.MajorVersion11},
NoRecommendation, off,
)
case MaxConnectionsKey:
if r.maxConns != 0 {
conns = r.maxConns
return fmt.Sprintf("%d", r.maxConns)
}
val = fmt.Sprintf("%d", conns)
} else if key == RandomPageCostKey {
val = randomPageCostDefault
} else if key == MaxLocksPerTxKey {
return fmt.Sprintf("%d", getMaxConns(r.totalMemory))
case MaxLocksPerTxKey:
for i := len(maxLocksValues) - 1; i >= 1; i-- {
limit := uint64(math.Pow(2.0, float64(2+i)))
if r.totalMemory >= limit*parse.Gigabyte {
return maxLocksValues[i]
}
}
return maxLocksValues[0]
} else if key == AutovacuumMaxWorkersKey {
val = autovacuumMaxWorkersDefault
} else if key == AutovacuumNaptimeKey {
val = autovacuumNaptimeDefault
} else if key == EffectiveIOKey {
val = getEffectiveIOConcurrency(r.pgMajorVersion)
} else {
val = NoRecommendation
}
return val

//unknown key no recommendation
return NoRecommendation
}

// MiscSettingsGroup is the SettingsGroup to represent settings that do not fit in other SettingsGroups.
Expand Down
64 changes: 63 additions & 1 deletion pkg/pgtune/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,68 @@ func TestGetEffectiveIOConcurrency(t *testing.T) {
}
}

func TestDefaultToastCompression(t *testing.T) {
cases := []struct {
pgMajorVersions []string
want string
}{
{
[]string{pgutils.MajorVersion96, pgutils.MajorVersion10, pgutils.MajorVersion11, pgutils.MajorVersion12, pgutils.MajorVersion13},
NoRecommendation,
},
{
[]string{pgutils.MajorVersion14, pgutils.MajorVersion15, pgutils.MajorVersion16, pgutils.MajorVersion17,
"18", //future versions
},
"lz4",
},
}
for _, c := range cases {
for _, v := range c.pgMajorVersions {
t.Run("default_toast_compression:"+v, func(t *testing.T) {
r := NewMiscRecommender(1000, 32, v)

rec := r.Recommend(DefaultToastCompression)
if rec != c.want {
t.Errorf("wanted %s got: %s", c.want, rec)
}

})
}
}
}

func TestJIT(t *testing.T) {
cases := []struct {
pgMajorVersions []string
want string
}{
{
[]string{pgutils.MajorVersion96, pgutils.MajorVersion10, pgutils.MajorVersion11},
NoRecommendation,
},
{
[]string{pgutils.MajorVersion12, pgutils.MajorVersion13, pgutils.MajorVersion14, pgutils.MajorVersion15, pgutils.MajorVersion16, pgutils.MajorVersion17,
"18", //future versions
},
"off",
},
}
for _, c := range cases {
for _, v := range c.pgMajorVersions {
t.Run("default_toast_compression:"+v, func(t *testing.T) {
r := NewMiscRecommender(1000, 32, v)

rec := r.Recommend(Jit)
if rec != c.want {
t.Errorf("wanted %s got: %s", c.want, rec)
}

})
}
}
}

func TestNewMiscRecommender(t *testing.T) {
for i := 0; i < 1000000; i++ {
mem := rand.Uint64()
Expand All @@ -173,7 +235,7 @@ func TestNewMiscRecommender(t *testing.T) {
func TestMiscRecommenderRecommend(t *testing.T) {
for totalMemory, outerMatrix := range miscSettingsMatrix {
for maxConns, matrix := range outerMatrix {
r := &MiscRecommender{totalMemory, maxConns, pgutils.MajorVersion12}
r := &MiscRecommender{totalMemory, maxConns, pgutils.MajorVersion10}
testRecommender(t, r, MiscKeys, matrix)
}
}
Expand Down
23 changes: 16 additions & 7 deletions pkg/tstune/tuner.go
Original file line number Diff line number Diff line change
Expand Up @@ -444,26 +444,35 @@ func checkIfShouldShowSetting(keys []string, parseResults map[string]*tunablePar

rv := pgtune.GetFloatParser(recommender)

// get and parse our recommendation; fail if for we can't
rec := recommender.Recommend(k)

switch {
case rec == pgtune.NoRecommendation:
// don't bother adding it to the map. no recommendation
continue
case r.commented:
show[k] = true
case r.value == rec:
// don't bother adding it to the map. no recommendation
continue

}

// parse the value already there; if unparseable, should show our rec
curr, err := rv.ParseFloat(k, r.value)
if err != nil {
show[k] = true
continue
}

// get and parse our recommendation; fail if for we can't
rec := recommender.Recommend(k)
if rec == pgtune.NoRecommendation {
// don't bother adding it to the map. no recommendation
continue
}
target, err := rv.ParseFloat(k, rec)
if err != nil {
return nil, fmt.Errorf("unexpected parsing problem: %v", err)
}

// only show if our recommendation is significantly different, or config is commented
if !isCloseEnough(curr, target, fudgeFactor) || r.commented {
if !isCloseEnough(curr, target, fudgeFactor) {
show[k] = true
}
}
Expand Down
Loading

0 comments on commit 173fd73

Please sign in to comment.