Skip to content

Commit e45572d

Browse files
committed
cluster,config,sidecar,utils: support the MySQL8.0 #176
1 parent 49384da commit e45572d

File tree

8 files changed

+160
-89
lines changed

8 files changed

+160
-89
lines changed

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ docker-build: test ## Build docker image with the manager.
7373
docker build -t ${IMG} .
7474
docker build -f Dockerfile.sidecar -t ${SIDECAR_IMG} .
7575
docker build -f hack/xenon/Dockerfile -t ${XENON_IMG} hack/xenon
76-
76+
mysql8-sidecar:
77+
docker build --build-arg XTRABACKUP_PKG=percona-xtrabackup-80 -f Dockerfile.sidecar -t ${SIDECAR_IMG} .
7778
docker-push: ## Push docker image with the manager.
7879
docker push ${IMG}
7980
docker push ${SIDECAR_IMG}

mysqlcluster/mysqlcluster.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ func (c *MysqlCluster) Validate() error {
7070
if utils.StringInArray(c.Spec.MysqlOpts.User, []string{"root", utils.ReplicationUser, utils.OperatorUser, utils.MetricsUser}) {
7171
return fmt.Errorf("spec.mysqlOpts.user cannot be root|%s|%s|%s", utils.ReplicationUser, utils.OperatorUser, utils.MetricsUser)
7272
}
73-
73+
// MySQL8 do not support TokuDB
74+
// https://www.percona.com/blog/2021/05/21/tokudb-support-changes-and-future-removal-from-percona-server-for-mysql-8-0/
75+
if c.Spec.MysqlVersion == "8.0" && c.Spec.MysqlOpts.InitTokuDB {
76+
return fmt.Errorf("TokuDB is not supported in MySQL 8.0 any more, the value in Cluster.spec.mysqlOpts.initTokuDB should be set false")
77+
}
7478
// https://github.com/percona/percona-docker/blob/main/percona-server-5.7/ps-entry.sh#L159
7579
// ERROR 1396 (HY000): Operation CREATE USER failed for 'root'@'127.0.0.1'.
7680
if c.Spec.MysqlOpts.RootHost == "127.0.0.1" {

mysqlcluster/mysqlcluster_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ func TestGetMySQLVersion(t *testing.T) {
139139
testCase := MysqlCluster{
140140
&testMysqlCluster,
141141
}
142-
want := utils.InvalidMySQLVersion
142+
want := "8.0.25"
143143
assert.Equal(t, want, testCase.GetMySQLVersion())
144144
}
145145
// MySQLTagsToSemVer 5.7 -> 5.7.34

mysqlcluster/syncer/config_map.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,13 @@ func NewConfigMapSyncer(cli client.Client, c *mysqlcluster.MysqlCluster) syncer.
5151
return fmt.Errorf("failed to create mysql configs: %s", err)
5252
}
5353

54+
data_special, err := buildSpecialMysqlConf(c)
55+
if err != nil {
56+
return fmt.Errorf("failed to create mysql special configs: %s", err)
57+
}
5458
cm.Data = map[string]string{
55-
"my.cnf": data,
59+
"my.cnf": data,
60+
"special.cnf": data_special,
5661
}
5762

5863
return nil
@@ -65,7 +70,10 @@ func buildMysqlConf(c *mysqlcluster.MysqlCluster) (string, error) {
6570
sec := cfg.Section("mysqld")
6671

6772
c.EnsureMysqlConf()
68-
73+
if c.Spec.MysqlVersion == "8.0" {
74+
delete(mysqlCommonConfigs, "query_cache_size")
75+
delete(mysqlStaticConfigs, "query_cache_type")
76+
}
6977
addKVConfigsToSection(sec, mysqlSysConfigs, mysqlCommonConfigs, mysqlStaticConfigs, c.Spec.MysqlOpts.MysqlConf)
7078

7179
if c.Spec.MysqlOpts.InitTokuDB {
@@ -86,6 +94,20 @@ func buildMysqlConf(c *mysqlcluster.MysqlCluster) (string, error) {
8694
return data, nil
8795
}
8896

97+
// Build the Special Cnf file.
98+
func buildSpecialMysqlConf(c *mysqlcluster.MysqlCluster) (string, error) {
99+
cfg := ini.Empty(ini.LoadOptions{IgnoreInlineComment: true})
100+
sec := cfg.Section("mysqld")
101+
102+
addKVConfigsToSection(sec, mysqlSpecialConfig)
103+
data, err := writeConfigs(cfg)
104+
if err != nil {
105+
return "", err
106+
}
107+
108+
return data, nil
109+
}
110+
89111
// addKVConfigsToSection add a map[string]string to a ini.Section
90112
func addKVConfigsToSection(s *ini.Section, extraMysqld ...map[string]string) {
91113
for _, extra := range extraMysqld {

mysqlcluster/syncer/variables.go

Lines changed: 65 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,86 +17,92 @@ limitations under the License.
1717
package syncer
1818

1919
import (
20-
logf "sigs.k8s.io/controller-runtime/pkg/log"
21-
2220
"github.com/radondb/radondb-mysql-kubernetes/utils"
21+
logf "sigs.k8s.io/controller-runtime/pkg/log"
2322
)
2423

2524
// log is for logging in this package.
2625
var log = logf.Log.WithName("mysqlcluster.syncer")
2726

2827
// mysqlSysConfigs is the map of mysql system configs.
2928
var mysqlSysConfigs = map[string]string{
30-
"default-time-zone": "+08:00",
31-
"slow_query_log_file": "/var/log/mysql/mysql-slow.log",
32-
"read_only": "ON",
33-
"binlog_format": "row",
34-
"plugin-load": "\"semisync_master.so;semisync_slave.so;audit_log.so;connection_control.so\"",
35-
"log-bin": "/var/lib/mysql/mysql-bin",
36-
"log-timestamps": "SYSTEM",
37-
"innodb_open_files": "655360",
38-
"open_files_limit": "655360",
39-
"rpl_semi_sync_master_enabled": "OFF",
40-
"rpl_semi_sync_slave_enabled": "ON",
41-
"rpl_semi_sync_master_wait_no_slave": "ON",
42-
"rpl_semi_sync_master_timeout": "1000000000000000000",
43-
"gtid-mode": "ON",
44-
"enforce-gtid-consistency": "ON",
45-
"slave_parallel_type": "LOGICAL_CLOCK",
46-
"relay_log": "/var/lib/mysql/mysql-relay-bin",
47-
"relay_log_index": "/var/lib/mysql/mysql-relay-bin.index",
48-
"master_info_repository": "TABLE",
49-
"relay_log_info_repository": "TABLE",
50-
"relay_log_recovery": "ON",
51-
"slow_query_log": "1",
52-
"tmp_table_size": "32M",
53-
"tmpdir": "/var/lib/mysql",
54-
"audit_log_file": "/var/log/mysql/mysql-audit.log",
55-
"audit_log_exclude_accounts": "\"root@localhost,root@127.0.0.1," + utils.ReplicationUser + "@%," + utils.MetricsUser + "@%\"",
56-
"audit_log_buffer_size": "16M",
29+
"default-time-zone": "+08:00",
30+
"slow_query_log_file": "/var/log/mysql/mysql-slow.log",
31+
"read_only": "ON",
32+
"binlog_format": "row",
33+
"log-bin": "/var/lib/mysql/mysql-bin",
34+
"log-timestamps": "SYSTEM",
35+
"innodb_open_files": "655360",
36+
"open_files_limit": "655360",
37+
38+
"gtid-mode": "ON",
39+
"enforce-gtid-consistency": "ON",
40+
"slave_parallel_type": "LOGICAL_CLOCK",
41+
"relay_log": "/var/lib/mysql/mysql-relay-bin",
42+
"relay_log_index": "/var/lib/mysql/mysql-relay-bin.index",
43+
"master_info_repository": "TABLE",
44+
"relay_log_info_repository": "TABLE",
45+
"slow_query_log": "1",
46+
"tmp_table_size": "32M",
47+
"tmpdir": "/var/lib/mysql",
5748
}
5849

59-
// mysqlCommonConfigs is the map of the mysql common configs.
60-
var mysqlCommonConfigs = map[string]string{
61-
"character_set_server": "utf8mb4",
62-
"interactive_timeout": "3600",
63-
"default-time-zone": "+08:00",
64-
"expire_logs_days": "7",
65-
"key_buffer_size": "33554432",
66-
"log_bin_trust_function_creators": "1",
67-
"long_query_time": "3",
68-
"binlog_cache_size": "32768",
69-
"binlog_stmt_cache_size": "32768",
70-
"max_connections": "1024",
71-
"max_connect_errors": "655360",
72-
"query_cache_size": "0",
73-
"sync_master_info": "1000",
74-
"sync_relay_log": "1000",
75-
"sync_relay_log_info": "1000",
76-
"table_open_cache": "2000",
77-
"thread_cache_size": "128",
78-
"wait_timeout": "3600",
79-
"group_concat_max_len": "1024",
80-
"slave_rows_search_algorithms": "INDEX_SCAN,HASH_SCAN",
81-
"max_allowed_packet": "1073741824",
82-
"event_scheduler": "OFF",
83-
"innodb_print_all_deadlocks": "0",
84-
"autocommit": "1",
85-
"transaction-isolation": "READ-COMMITTED",
50+
var mysqlSpecialConfig = map[string]string{
51+
"plugin-load": "\"semisync_master.so;semisync_slave.so;audit_log.so;connection_control.so\"",
52+
"audit_log_file": "/var/log/mysql/mysql-audit.log",
53+
"audit_log_exclude_accounts": "\"root@localhost,root@127.0.0.1," + utils.ReplicationUser + "@%," + utils.MetricsUser + "@%\"",
54+
"audit_log_buffer_size": "16M",
55+
"rpl_semi_sync_master_enabled": "OFF",
56+
"rpl_semi_sync_slave_enabled": "ON",
57+
"rpl_semi_sync_master_wait_no_slave": "ON",
58+
"rpl_semi_sync_master_timeout": "1000000000000000000",
59+
"audit-log": "ON",
8660
"audit_log_policy": "NONE",
8761
"audit_log_rotate_on_size": "104857600",
8862
"audit_log_rotations": "6",
63+
"audit_log_format": "OLD",
8964
"connection_control_failed_connections_threshold": "3",
9065
"connection_control_min_connection_delay": "1000",
9166
"connection_control_max_connection_delay": "2147483647",
92-
"explicit_defaults_for_timestamp": "0",
93-
"innodb_adaptive_hash_index": "0",
67+
"default-authentication-plugin": "mysql_native_password",
68+
}
69+
70+
// mysqlCommonConfigs is the map of the mysql common configs.
71+
var mysqlCommonConfigs = map[string]string{
72+
"character_set_server": "utf8mb4",
73+
"interactive_timeout": "3600",
74+
"default-time-zone": "+08:00",
75+
"expire_logs_days": "7",
76+
"key_buffer_size": "33554432",
77+
"log_bin_trust_function_creators": "1",
78+
"long_query_time": "3",
79+
"binlog_cache_size": "32768",
80+
"binlog_stmt_cache_size": "32768",
81+
"max_connections": "1024",
82+
"max_connect_errors": "655360",
83+
"query_cache_size": "0",
84+
"sync_master_info": "1000",
85+
"sync_relay_log": "1000",
86+
"sync_relay_log_info": "1000",
87+
"table_open_cache": "2000",
88+
"thread_cache_size": "128",
89+
"wait_timeout": "3600",
90+
"group_concat_max_len": "1024",
91+
"slave_rows_search_algorithms": "INDEX_SCAN,HASH_SCAN",
92+
"max_allowed_packet": "1073741824",
93+
"event_scheduler": "OFF",
94+
"innodb_print_all_deadlocks": "0",
95+
"autocommit": "1",
96+
"transaction-isolation": "READ-COMMITTED",
97+
98+
"explicit_defaults_for_timestamp": "0",
99+
"innodb_adaptive_hash_index": "0",
94100
}
95101

96102
// mysqlStaticConfigs is the map of the mysql static configs.
97103
// The mysql need restart, if modify the config.
98104
var mysqlStaticConfigs = map[string]string{
99-
"audit_log_format": "OLD",
105+
100106
"default-storage-engine": "InnoDB",
101107
"back_log": "2048",
102108
"ft_min_word_len": "4",

sidecar/config.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -363,23 +363,43 @@ func (cfg *Config) buildInitSql() []byte {
363363
sql := fmt.Sprintf(`SET @@SESSION.SQL_LOG_BIN=0;
364364
CREATE DATABASE IF NOT EXISTS %s;
365365
DROP user IF EXISTS 'root'@'127.0.0.1';
366-
GRANT ALL ON *.* TO 'root'@'127.0.0.1' IDENTIFIED BY '%s' with grant option;
366+
CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY '%s';
367+
GRANT ALL ON *.* TO 'root'@'127.0.0.1' with grant option;
367368
DROP user IF EXISTS 'root'@'%%';
368-
GRANT ALL ON *.* TO 'root'@'%%' IDENTIFIED BY '%s' with grant option;
369+
CREATE USER 'root'@'%%' IDENTIFIED BY '%s';
370+
GRANT ALL ON *.* TO 'root'@'%%' with grant option;
369371
DROP user IF EXISTS '%s'@'%%';
370-
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO '%s'@'%%' IDENTIFIED BY '%s';
372+
CREATE USER '%s'@'%%' IDENTIFIED BY '%s';
373+
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO '%s'@'%%';
371374
DROP user IF EXISTS '%s'@'%%';
372-
GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO '%s'@'%%' IDENTIFIED BY '%s';
375+
CREATE USER '%s'@'%%' IDENTIFIED BY '%s';
376+
GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO '%s'@'%%';
373377
DROP user IF EXISTS '%s'@'%%';
374-
GRANT SUPER, PROCESS, RELOAD, CREATE, SELECT ON *.* TO '%s'@'%%' IDENTIFIED BY '%s';
378+
CREATE USER '%s'@'%%' IDENTIFIED BY '%s';
379+
GRANT SUPER, PROCESS, RELOAD, CREATE, SELECT ON *.* TO '%s'@'%%';
375380
DROP user IF EXISTS '%s'@'%%';
376-
GRANT ALL ON %s.* TO '%s'@'%%' IDENTIFIED BY '%s';
381+
CREATE USER '%s'@'%%' IDENTIFIED BY '%s';
382+
GRANT ALL ON %s.* TO '%s'@'%%' ;
377383
FLUSH PRIVILEGES;
378-
RESET SLAVE ALL;
379-
`, cfg.Database, cfg.RootPassword, cfg.InternalRootPassword, cfg.ReplicationUser, cfg.ReplicationUser, cfg.ReplicationPassword,
380-
cfg.MetricsUser, cfg.MetricsUser, cfg.MetricsPassword, cfg.OperatorUser, cfg.OperatorUser,
381-
cfg.OperatorPassword, cfg.User, cfg.Database, cfg.User, cfg.Password)
382-
384+
SET SLAVE ALL;
385+
`, cfg.Database, //database
386+
cfg.RootPassword,
387+
cfg.InternalRootPassword,
388+
cfg.ReplicationUser, //drop user
389+
cfg.ReplicationUser, cfg.ReplicationPassword, //create user
390+
cfg.ReplicationUser, //grant REPLICATION
391+
392+
cfg.MetricsUser, //drop user MetricsUser
393+
cfg.MetricsUser, cfg.MetricsPassword, //create user
394+
cfg.MetricsUser, //grant
395+
396+
cfg.OperatorUser, //drop user
397+
cfg.OperatorUser, cfg.OperatorPassword, //create
398+
cfg.OperatorUser, //grant
399+
400+
cfg.User, //drop user
401+
cfg.User, cfg.Password, //create user
402+
cfg.Database, cfg.User) //grant
383403
return utils.StringToBytes(sql)
384404
}
385405

sidecar/init.go

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -109,26 +109,25 @@ func runCloneAndInit(cfg *Config) error {
109109
// runInitCommand do some initialization operations.
110110
func runInitCommand(cfg *Config) error {
111111
var err error
112+
// Get the mysql user.
113+
user, err := user.Lookup("mysql")
114+
if err != nil {
115+
return fmt.Errorf("failed to get mysql user: %s", err)
116+
}
117+
uid, err := strconv.Atoi(user.Uid)
118+
if err != nil {
119+
return fmt.Errorf("failed to get mysql user uid: %s", err)
120+
}
121+
gid, err := strconv.Atoi(user.Gid)
122+
if err != nil {
123+
return fmt.Errorf("failed to get mysql user gid: %s", err)
124+
}
112125

113126
if exists, _ := checkIfPathExists(dataPath); exists {
114127
// remove lost+found.
115128
if err := os.RemoveAll(dataPath + "/lost+found"); err != nil {
116129
return fmt.Errorf("removing lost+found: %s", err)
117130
}
118-
119-
// Get the mysql user.
120-
user, err := user.Lookup("mysql")
121-
if err != nil {
122-
return fmt.Errorf("failed to get mysql user: %s", err)
123-
}
124-
uid, err := strconv.Atoi(user.Uid)
125-
if err != nil {
126-
return fmt.Errorf("failed to get mysql user uid: %s", err)
127-
}
128-
gid, err := strconv.Atoi(user.Gid)
129-
if err != nil {
130-
return fmt.Errorf("failed to get mysql user gid: %s", err)
131-
}
132131
// chown -R mysql:mysql /var/lib/mysql.
133132
if err = os.Chown(dataPath, uid, gid); err != nil {
134133
return fmt.Errorf("failed to chown %s: %s", dataPath, err)
@@ -155,7 +154,24 @@ func runInitCommand(cfg *Config) error {
155154
return fmt.Errorf("error mkdir %s: %s", extraConfPath, err)
156155
}
157156
}
157+
// chown -R mysql:mysql /var/lib/mysql.
158+
if err = os.Chown(extraConfPath, uid, gid); err != nil {
159+
return fmt.Errorf("failed to chown %s: %s", dataPath, err)
160+
}
158161

162+
if err = copyFile(path.Join(configMapPath, "special.cnf"), path.Join(initFilePath, "special.cnf")); err != nil {
163+
return fmt.Errorf("failed to copy special.cnf: %s", err)
164+
}
165+
166+
if err = os.Chmod(path.Join(initFilePath, "special.cnf"), 0755); err != nil {
167+
return fmt.Errorf("failed to chmod special.cnf : %s", err)
168+
}
169+
// Create shell `cp path.Join(initFilePath, "special.cnf") extraConfPath; chmod extraConfPath/special.cnf`
170+
special_sh := "cp " + path.Join(initFilePath, "special.cnf ") + extraConfPath + "; "
171+
special_sh += "chmod 755 " + extraConfPath + "/special.cnf"
172+
if err = ioutil.WriteFile(initFilePath+"/special.sh", []byte(special_sh), 0755); err != nil {
173+
return fmt.Errorf("failed to write special: %s", err)
174+
}
159175
// Run reset master in init-mysql container.
160176
if err = ioutil.WriteFile(initFilePath+"/reset.sql", []byte("reset master;"), 0644); err != nil {
161177
return fmt.Errorf("failed to write reset.sql: %s", err)

utils/constants.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@ var (
2828
// MySQLTagsToSemVer maps simple version to semver versions
2929
MySQLTagsToSemVer = map[string]string{
3030
"5.7": "5.7.34",
31+
"8.0": "8.0.25",
3132
}
3233

3334
// MysqlImageVersions is a map of supported mysql version and their image
3435
MysqlImageVersions = map[string]string{
3536
"5.7.33": "percona/percona-server:5.7.33",
3637
"5.7.34": "percona/percona-server:5.7.34",
38+
"8.0.25": "percona/percona-server:8.0.25",
3739
"0.0.0": "errimage",
3840
}
3941

0 commit comments

Comments
 (0)