对于 MySQL 的多实例,比较常见的一种做法是把一个已经初始化成功的 DATADIR 目录下的 mysql 目录复制到其它实例的 DATADIR 目录下,然后配置参数文件,启动的时候新目录就会自动初始化,这么做数据库是能启起来的,也能连接使用,但是当要开启某些高级特性(例如replication)的时候会报错,因为mysql目录下面有很多.ibd文件,这些文件是不能直接拷贝的。这种做法之所以存在,是因为早期使用的是 MyISAM 存储引擎,可以直接拷贝。现在使用的是 InnoDB 存储引擎,这样做是有瑕疵的,不推荐。下面是推荐的做法:
当前环境
MySQL 软件目录为 /usr/local/mysql/, 在其下已经初始化了一个 data 目录,使用 3306 端口。当前无任何适用于服务端的 my.cnf 配置文件。
初始化 DATADIR
# mkdir -p /data/
# chown -R mysql.mysql /data/
# mysqld --initialize --user=mysql --datadir=/data/3307
# mysqld --initialize --user=mysql --datadir=/data/3308
准备配置文件
可以为每个实例配置单独的参数文件,使用 mysqld_safe 通过 --defaults-file 来启动。
也可以在一个配置文件中配置 [mysqld_multi] 和每个实例的 section。
一个比较精简的示例如下(mysqld后面的数字为GNR, 是该实例的标识):
# vim /etc/my.cnf
[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
log = /var/log/mysqld_multi.log
[mysqld]
log_error = error.log
pid-file = mysql.pid
[mysqld1]
port = 3307
datadir = /data/3307
socket = /tmp/mysql.sock.3307
[mysqld2]
port = 3308
datadir = /data/3308
socket = /tmp/mysql.sock.3308
启动实例
# mysqld_multi report
# mysqld_multi start (之前的3306实例不会启动)
# mysqld_multi start 1
连接实例
# mysql -uroot -p -S /tmp/mysql.sock.3307
# mysql -uroot -h127.0.0.1 -P 3307
## mysql --login-path=xxx
停止实例
# mysqld_multi stop --user=root --password=redhat 2
可以将密码写到 .my.cnf 文件中:
[client]
user=root
password=redhat
这样关闭的时候就不需要提供用户名和密码了:
# mysqld_multi stop 2
如果所有实例的 root 密码都一样,还可以直接关闭所有实例:
# mysqld_multi stop
但也可能实例的 root 密码是不一样的,这就需要一个一个地去关闭实例,如果想一下关闭所有实例,就需要在每个实例中创建一个共同的用户:
mysql> create user 'multi_admin'@'localhost' identified by 'oracle';
mysql> grant shutdown on *.* to 'multi_admin'@'localhost';
这样一来,就可以在 [mysqld_multi] 中配置上用于关闭多实例的用户名和密码了:
[mysqld_multi]
user=multi_admin
pass=oracle
# 官方文档是 password,但在 5.7 中有 bug,如果这儿不配置 user 和 pass ,就会到 [client] 中去找 user 和 password。
多版本共存
本质上还是多实例,以 5.6 为例,在配置文件中为其增加一个 section 即可,这个 section 跟之前的一样,只是多了 basedir 和 plugin_dir 两个参数。
[mysqld3]
port = 3309
basedir = /usr/local/mysql56
datadir = /data/3309
socket = /tmp/mysql.sock.3309
plugin_dir = /usr/local/mysql56/lib/plugin
注意:之前 5.7 版本的 section 也加上 basedir:
basedir = /usr/local/mysql
然后初始化 5.6 的实例(注意方法跟 5.7 不一样):
# cd /usr/local/mysql56
# scripts/mysql_install_db --user=mysql --datadir=/data/3309
启动实例:
# mysqld_multi start 3
使用 root 用户(空密码)连接数据库,设置 root 用户密码并添加多实例管理用户:
mysql> set password=password('oracle');
mysql> create user 'multi_admin'@'localhost' identified by 'oracle';
mysql> grant shutdown on *.* to 'multi_admin'@'localhost';
通过 ps aux 可以看到,5.6运行的是5.6的 mysqld,5.7运行的是 5.7 的,因为我们在每个 section 都指定了 basedir。
此时,仍然还可以使用 /etc/init.d/mysqld 来管理原来的实例启停。