今天,有个朋友问我,一台服务器上面能不能安装多个MySQL呢?这样我们就可以用不同的代码使用不同的数据库了。我知道肯定是可以的,但是按照以前编译安装的方式好像很麻烦,又重新整理了一版其他安装方式的多实例安装文档,特来记录。但是线上需不需要这个东西,还是要看业务需求。此文当做学习笔记记录操作过程,希望可以帮助其他的朋友。
介绍:MySQL数据库的集中化运维,可以通过在一台服务器上,部署运行多个MySQL服务进程,通过不同的socket监听不同的服务端口来提供各自的服务。各个实例之间是相互独立的,每个实例的datadir, port, socket, pid都是不同的。
2.1 有效利用服务器资源,当单个服务器资源有剩余时,可以充分利用剩余的资源提供更多的服务。
2.2 资源互相抢占问题,当某个服务实例服务并发很高时或者开启慢查询时,会消耗更多的内存、CPU、磁盘IO资源,导致服务器上的其他实例提供服务的质量下降。
必须关闭selinux
[root@node2 local]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@node2 local]# uname -r
3.10.0-1160.11.1.el7.x86_64
[root@MySQL ~]# getenforce
Disabled
4.1 下载 MySQL 5.7 二制包 [ 推荐官方下载 ] 此下载版本大于5.7.5
[root@node2 ~]# wget wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz
4.2 解压 MySQL 5.7 二进制包到指定目录
[root@node2 ~]# tar zxvf mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz -C /usr/local/
4.3 创建 MySQL 软链接
[root@node2 ~]# mv /usr/local/mysql-5.7.18-linux-glibc2.5-x86_64 /usr/local/mysql
4.4 创建 MySQL 用户
[root@node2 ~]# useradd -r -s /sbin/nologin mysql
4.5 在 MySQL 二进制包目录中创建 mysql-files 目录 [MySQL 数据导入/导出数据专放目录]
[root@node2 ~]# mkdir -v /usr/local/mysql/mysql-files
mkdir: created directory `/usr/local/mysql/mysql-files'
4.6 创建多实例数据目录
[root@node2 local]# mkdir -vp /data/mysql/data{3306..3309}
mkdir: 已创建目录 "/data/mysql"
mkdir: 已创建目录 "/data/mysql/data3306"
mkdir: 已创建目录 "/data/mysql/data3307"
mkdir: 已创建目录 "/data/mysql/data3308"
mkdir: 已创建目录 "/data/mysql/data3309"
4.7 修改 MySQL 二进制包目录的所属用户与所属组
[root@node2 local]# chown mysql.mysql /usr/local/mysql/ -R
[root@node2 local]# chown mysql.mysql /data/mysql -R
4.8 配置 MySQL 配置文件 /etc/my.cnf
[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld
mysqladmin = /usr/local/mysql/bin/mysqladmin
log = /tmp/mysql_multi.log
[mysqld3306]
datadir = /data/mysql/data3306 # 设置数据目录 [多实例中一定要不同]
socket = /tmp/mysql-3306.sock # 设置sock存放文件名 [多实例中一定要不同]
port = 3306 # 设置监听开放端口 [多实例中一定要不同]
user = mysql # 设置运行用户
innodb_buffer_pool_size = 32M # 设置innodb 缓存大小
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
[mysqld3307]
datadir = /data/mysql/data3307
socket = /tmp/mysql-3307.sock
port = 3307
user = mysql
innodb_buffer_pool_size = 32M
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
[mysqld3308]
datadir = /data/mysql/data3308
socket = /tmp/mysql-3308.sock
port = 3308
user = mysql
innodb_buffer_pool_size = 32M
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
[mysqld3309]
datadir = /data/mysql/data3309
socket = /tmp/mysql-3309.sock
port = 3309
user = mysql
innodb_buffer_pool_size = 32M
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
4.9 初始化各个实例 [ 初始化完成后会自带随机密码在输出日志中 ]
[root@node2 ~]# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data3306
[root@node2 ~]# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data3307
[root@node2 ~]# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data3308
[root@node2 ~]# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data3309
注意:初始化的时候会输出密码,记录下来:2020-12-25T06:39:00.288011Z 1 [Note] A temporary password is generated for root@localhost: dfIx98z,3fj(
4.10 各实例开启 SSL 连接
[root@node2 ~]# /usr/local/mysql/bin/mysql_ssl_rsa_setup --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data3306
[root@node2 ~]# /usr/local/mysql/bin/mysql_ssl_rsa_setup --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data3307
[root@node2 ~]# /usr/local/mysql/bin/mysql_ssl_rsa_setup --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data3308
[root@node2 ~]# /usr/local/mysql/bin/mysql_ssl_rsa_setup --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data3309
复制多实例脚本到服务管理目录下 [ /etc/init.d/ ]
[root@node2 ~]# cp /usr/local/mysql/support-files/mysqld_multi.server /etc/init.d/mysqld_multi
4.11 添加脚本执行权限
[root@node2 ~]# chmod +x /etc/init.d/mysqld_multi
4.12 添加进service服务管理和配置环境变量
[root@node2 ~]# chkconfig --add mysqld_multi
[root@node2 ~]# echo "export PATH=$PATH:/usr/local/mysql/bin" >>/etc/profile
[root@node2 ~]# source /etc/profile
4.13 启动多实例
[root@node2 local]# /usr/local/mysql/bin/mysqld_multi start #开启多实例
[root@node2 local]# /usr/local/mysql/bin/mysqld_multi report #查看全部实例状态
[root@node2 local]# /usr/local/mysql/bin/mysqld_multi start 3306 #启动单个实例
[root@node2 local]# /usr/local/mysql/bin/mysqld_multi stop 3306 #停止单个实例
[root@node2 local]# /usr/local/mysql/bin/mysqld_multi report
Reporting MySQL servers
MySQL server from group: mysqld3306 is running
MySQL server from group: mysqld3307 is running
MySQL server from group: mysqld3308 is running
MySQL server from group: mysqld3309 is running
4.14 查看实例监听端口
[root@node2 local]# netstat -lntp | grep mysqld
tcp6 0 0 :::3306 :::* LISTEN 8898/mysqld
tcp6 0 0 :::3307 :::* LISTEN 8901/mysqld
tcp6 0 0 :::3308 :::* LISTEN 8904/mysqld
tcp6 0 0 :::3309 :::* LISTEN 8907/mysqld
实例3306测试:
[root@node2 local]# mysql -uroot -p -S /tmp/mysql-3306.sock
Enter password: #输入4.9 初始化输出的密码
Server version: 5.7.18 MySQL Community Server (GPL)
..................
mysql> set password for root@'localhost'=password('123456');
mysql> flush privileges;
mysql> create database test ; #可以看到该实例的data目录下多了一个test库
其他实例连接:
[root@node2 local]# mysql -uroot -p -S /tmp/mysql-3307.sock
[root@node2 local]# mysql -uroot -p -S /tmp/mysql-3308.sock
[root@node2 local]# mysql -uroot -p -S /tmp/mysql-3309.sock
遇到的问题:
/usr/local/mysql/bin/mysqld_multi stop 3306 停止3306实例无效。
解决: 自己写一个脚本来实现启停功能
#先把密码存放到一个安全的文件里面
echo '123456' > /etc/mysql.pass
chmod 600 /etc/mysql.pass
vim /etc/init.d/mysqld_manager #以后就可以通过这个脚本来管理mysql了
#!/bin/bash
tag=$1
port=$2
mysqld_multi="/usr/local/mysql/bin/mysqld_multi"
sql="/usr/local/mysql/bin/mysql"
sqladmin="/usr/local/mysql/bin/mysqladmin"
if [ "$tag" == "start" ] && [ "$port" == '' ];then
$mysqld_multi start
else
case "$tag" in
'start' )
$mysqld_multi start $port
;;
'stop' )
$sqladmin -uroot -p`cat /etc/mysql.pass` -S /tmp/mysql-$port.sock shutdown
;;
'report' )
$mysqld_multi report $port
;;
'restart' )
$sqladmin -uroot -p`cat /etc/mysql.pass` -S /tmp/mysql-$port.sock shutdown
$mysqld_multi start $port
;;
*)
echo "Usage: $0 {start|stop|report|restart}" >&2
;;
esac
fi
#赋权
chmod 755 /etc/init.d/mysqld_manager