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 21, 2019
1 parent eba4af7 commit 959692b
Showing 1 changed file with 79 additions and 35 deletions.
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
}

0 comments on commit 959692b

Please sign in to comment.