Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 79 additions & 35 deletions pkg/internal/mysqlcluster/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ 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"
)

Expand Down Expand Up @@ -76,49 +78,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 := getRequestedStorage(pvc); space != nil {
binlogSpaceLimit := space.Value() / 2
maxBinlogSize := min(binlogSpaceLimit/4, 1*gb)
if space.Value() < 2*gb {
binlogSpaceLimit = space.Value() / 3
maxBinlogSize = min(binlogSpaceLimit/3, 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 getRequestedStorage(pvc *core.PersistentVolumeClaimSpec) *resource.Quantity {
if val, ok := pvc.Resources.Requests[core.ResourceStorage]; ok {
return &val
}
return nil
}

func humanizeSize(value int64) intstr.IntOrString {
var unit string

Expand All @@ -132,3 +128,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
}