Skip to content

Commit

Permalink
Set limits on binlog size, fixes #233
Browse files Browse the repository at this point in the history
  • Loading branch information
AMecea committed Feb 19, 2019
1 parent 6aff2da commit cbfaba6
Showing 1 changed file with 80 additions and 36 deletions.
116 changes: 80 additions & 36 deletions pkg/internal/mysqlcluster/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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 {
Expand Down Expand Up @@ -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

Expand All @@ -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
}

0 comments on commit cbfaba6

Please sign in to comment.