diff --git a/pkg/internal/mysqlcluster/defaults.go b/pkg/internal/mysqlcluster/defaults.go index 7b4f48ecd..d7aa0803c 100644 --- a/pkg/internal/mysqlcluster/defaults.go +++ b/pkg/internal/mysqlcluster/defaults.go @@ -18,10 +18,13 @@ package mysqlcluster import ( "fmt" + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + api "github.com/presslabs/mysql-operator/pkg/apis/mysql/v1alpha1" "github.com/presslabs/mysql-operator/pkg/options" ) @@ -34,7 +37,6 @@ const ( ) // SetDefaults set defaults from options -// nolint: gocyclo func (cluster *MysqlCluster) SetDefaults(opt *options.Options) { // set default image pull policy if len(cluster.Spec.PodSpec.ImagePullPolicy) == 0 { @@ -66,49 +68,43 @@ func (cluster *MysqlCluster) SetDefaults(opt *options.Options) { // https://www.percona.com/blog/2018/03/26/mysql-8-0-innodb_dedicated_server-variable-optimizes-innodb/ // set innodb-buffer-pool-size if not set - if _, ok := cluster.Spec.MysqlConf["innodb-buffer-pool-size"]; !ok { - if mem := cluster.Spec.PodSpec.Resources.Requests.Memory(); mem != nil { - var bufferSize int64 - if mem.Value() < gb { - // RAM < 1G => buffer size set to 128M - bufferSize = 128 * mb - } else if mem.Value() <= 4*gb { - // RAM <= 4gb => buffer size set to RAM * 0.5 - bufferSize = int64(float64(mem.Value()) * 0.5) - } else { - // RAM > 4gb => buffer size set to RAM * 0.75 - bufferSize = int64(float64(mem.Value()) * 0.75) - } + if mem := cluster.Spec.PodSpec.Resources.Requests.Memory(); mem != nil { + bufferSize := humanizeSize(computeInnodbBufferPoolSize(mem)) + setConfigIfNotSet(cluster.Spec.MysqlConf, "innodb-buffer-pool-size", bufferSize) + } - cluster.Spec.MysqlConf["innodb-buffer-pool-size"] = humanizeSize(bufferSize) - } + if mem := cluster.Spec.PodSpec.Resources.Requests.Memory(); mem != nil { + logFileSize := humanizeSize(computeInnodbLogFileSize(mem)) + setConfigIfNotSet(cluster.Spec.MysqlConf, "innodb-log-file-size", logFileSize) } - if _, ok := cluster.Spec.MysqlConf["innodb-log-file-size"]; !ok { - if mem := cluster.Spec.PodSpec.Resources.Requests.Memory(); mem != nil { - var logFileSize int64 - if mem.Value() < gb { - // RAM < 1G - logFileSize = 48 * mb - } else if mem.Value() <= 4*gb { - // RAM <= 4gb - logFileSize = 128 * mb - } else if mem.Value() <= 8*gb { - // RAM <= 8gb - logFileSize = 512 * mb - } else if mem.Value() <= 16*gb { - // RAM <= 16gb - logFileSize = 1 * gb - } else { - // RAM > 16gb - logFileSize = 2 * gb + if pvc := cluster.Spec.VolumeSpec.PersistentVolumeClaim; pvc != nil { + if space := getStorage(pvc.Resources.Requests); space != nil { + binlogSpaceLimit := 50 / 100 * space.Value() + maxBinlogSize := min(25/100*binlogSpaceLimit, 1*gb) + if space.Value() < 2*gb { + binlogSpaceLimit = 33 / 100 * space.Value() + maxBinlogSize = min(33/100*binlogSpaceLimit, 1*gb) } - - cluster.Spec.MysqlConf["innodb-log-file-size"] = humanizeSize(logFileSize) + setConfigIfNotSet(cluster.Spec.MysqlConf, "max-binlog-size", humanizeSize(maxBinlogSize)) + setConfigIfNotSet(cluster.Spec.MysqlConf, "binlog-space-limit", humanizeSize(binlogSpaceLimit)) } } } +func setConfigIfNotSet(conf api.MysqlConf, option string, value intstr.IntOrString) { + if _, ok := conf[option]; !ok { + conf[option] = value + } +} + +func getStorage(rl core.ResourceList) *resource.Quantity { + if val, ok := rl[core.ResourceStorage]; ok { + return &val + } + return nil +} + func humanizeSize(value int64) intstr.IntOrString { var unit string @@ -122,3 +118,51 @@ func humanizeSize(value int64) intstr.IntOrString { return intstr.FromString(fmt.Sprintf("%d%s", value, unit)) } + +// computeInnodbLogFileSize returns a computed value, to configure MySQL, based on requested memory. +func computeInnodbLogFileSize(mem *resource.Quantity) int64 { + var logFileSize int64 + if mem.Value() < gb { + // RAM < 1G + logFileSize = 48 * mb + } else if mem.Value() <= 4*gb { + // RAM <= 4gb + logFileSize = 128 * mb + } else if mem.Value() <= 8*gb { + // RAM <= 8gb + logFileSize = 512 * mb + } else if mem.Value() <= 16*gb { + // RAM <= 16gb + logFileSize = 1 * gb + } else { + // RAM > 16gb + logFileSize = 2 * gb + } + + return logFileSize +} + +// computeInnodbBufferPoolSize returns a computed value, to configure MySQL, based on requested +// memory. +func computeInnodbBufferPoolSize(mem *resource.Quantity) int64 { + var bufferSize int64 + if mem.Value() < gb { + // RAM < 1G => buffer size set to 128M + bufferSize = 128 * mb + } else if mem.Value() <= 4*gb { + // RAM <= 4gb => buffer size set to RAM * 0.5 + bufferSize = int64(float64(mem.Value()) * 0.5) + } else { + // RAM > 4gb => buffer size set to RAM * 0.75 + bufferSize = int64(float64(mem.Value()) * 0.75) + } + + return bufferSize +} + +func min(a, b int64) int64 { + if a <= b { + return a + } + return b +}