一、about
centos7.3 + mysql5.7.20
MySQL多實例的本質
在一台機器上開啟多個不同的MySQL實例,也就是各實例監聽不同的端口,提供不同的服務。
多個實例公用一套MySQL安裝程序,啟動程序和配置文件可以是一個也可以是多個(推薦多個);各自的數據文件隔離;邏輯上各實例彼此隔離。
為什么要使用多實例?優缺點?
- 物理機性能強大,單個實例無法充分利用硬件資源
- 資源隔離,減少相互影響
- 分擔連接數,MySQL隨着連接數的上升,性能會下降
- 更充分的利用資源,不同業務錯高峰混跑
- 有優點,也有缺點,比如多個實例會存在資源相互搶占的問題,當某個實例的並發較高或者存在慢查詢時,它會消耗更多的硬件資源,這就可能影響到別的實例的性能
多實例的應用場景
- 資金比較緊張的公司
- 並發訪問不大的業務
MySQL多實例常見配置方案
- (推薦)通過多個配置文件及多個啟動程序來實現多實例。
- 單一配置文件方案,即一個配置文件中寫多個實例的配置。
二、必要的准備
目錄規划
1 /opt/software/mysql # MySQL的安裝目錄 2 /data/mysql/ # 所有的MySQL實例的數據目錄、備份目錄、日志目錄,都在該目錄下,各個實例以端口號命名 3 /etc/my.conf # MySQL 3306實例的默認配置文件
依賴下載
1 # 如果你的系統曾經安裝過mariadb,請先卸載 2 yum remove -y mariadb* 3 yum install -y epel-release 4 yum update -y 5 yum install -y cmake gcc-c++ ncurses-devel perl-Data-Dumper boost-doc boost-devel libaio-devel 6 yum install -y net-tools tree bash-completion lrzsz
三、單實例配置
3.1、下載安裝mysql
1 [root@cs ~]# mkdir -p /opt/software && cd /opt/software 2 [root@cs software]# pwd 3 /opt/software 4 [root@cs software]# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz 5 [root@cs software]# tar -xvf mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz 6 [root@cs software]# mv mysql-5.7.20-linux-glibc2.12-x86_64 mysql 7 [root@cs software]# rm -rf mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz && ls 8 mysql
3.2 添加環境變量
1 [root@cs software]# vim /etc/profile 2 3 export PATH=/opt/software/mysql/bin:$PATH 4 5 [root@cs software]# source /etc/profile
3.3 創建相關目錄和MySQL用戶
MySQL服務運行在非root用戶環境,所以,我們先創建一個mysql用戶,然后在創建相關的數據目錄:
創建數據目錄,並且授權更改用戶屬組,MySQL的安裝目錄授權
1 [root@cs software]# useradd mysql 2 [root@cs software]# mkdir -p /data/mysql/330{6,7,8,9}/{data,logs,backup} 3 [root@cs software]# tree /data/mysql/330* 4 /data/mysql/3306 5 ├── backup 6 ├── data 7 └── logs 8 /data/mysql/3307 9 ├── backup 10 ├── data 11 └── logs 12 /data/mysql/3308 13 ├── backup 14 ├── data 15 └── logs 16 /data/mysql/3309 17 ├── backup 18 ├── data 19 └── logs 20 21 12 directories, 0 files 22 [root@cs software]# chown -R mysql:mysql /opt/software/mysql/* 23 [root@cs software]# chown -R mysql:mysql /data/mysql/*
3.4 初始化數據庫
進行初始化,初始化完成后,會默認創建一個本地的root用戶,且無密碼
# 保證存放數據的目錄是空的,避免不必要的問題 [root@cs software]# rm -rf /data/mysql/3306/data/* [root@cs software]# mysqld --initialize-insecure --user=mysql --basedir=/opt/software/mysql --datadir=/data/mysql/3306/data
2021-05-09T09:41:30.343576Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 2021-05-09T09:41:30.557948Z 0 [Warning] InnoDB: New log files created, LSN=45790 2021-05-09T09:41:30.587516Z 0 [Warning] InnoDB: Creating foreign key constraint system tables. 2021-05-09T09:41:30.655073Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: bbcbb587-b0aa-11eb-a2ce-000c295ead38. 2021-05-09T09:41:30.656498Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened. 2021-05-09T09:41:30.656990Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
一堆"Warning",不要管它。
3.5 添加配置文件
1 cat > /etc/my.cnf <<EOF 2 [mysqld] 3 user=mysql 4 basedir=/opt/software/mysql 5 datadir=/data/mysql/3306/data 6 server_id=6 7 port=3306 8 socket=/tmp/mysql.sock 9 log_error=/data/mysql/3306/logs/mysql_error.log 10 [mysql] 11 socket=/tmp/mysql.sock 12 EOF
3.6 使用systemctl管理MySQL服務
1 cat > /etc/systemd/system/mysqld.service <<EOF 2 [Unit] 3 Description=MySQL Server 4 Documentation=man:mysqld(8) 5 Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html 6 After=network.target 7 After=syslog.target 8 [Install] 9 WantedBy=multi-user.target 10 [Service] 11 User=mysql 12 Group=mysql 13 ExecStart=/opt/software/mysql/bin/mysqld --defaults-file=/etc/my.cnf 14 LimitNOFILE = 5000 15 EOF
3.7 systemctl命令來管理MySQL服務
systemctl start/restart/stop/status/enable/disable mysqld
測試下:
[root@cs software]# find / -name mysql.sock [root@cs software]# systemctl start mysqld [root@cs software]# find / -name mysql.sock /tmp/mysql.sock [root@cs software]# netstat -lnp|grep 330 tcp6 0 0 :::3306 :::* LISTEN 8131/mysqld
啟動之后,/tmp
下就有了mysql.sock
文件,后續我們可以通過這個socket文件來連接數據了。如果使用systemctl
停止數據庫,這個文件也沒了。
ok,單台實例創建完畢。
3.8、創建用戶並且授權
1 grant all on *.* to root@'localhost' identified by '123'; 2 grant all on *.* to root@'%' identified by '123'; 3 flush privileges;
四、
配置4.1 必要的准備
1 [root@cs software]# systemctl stop mysqld 2 [root@cs software]# mv /etc/my.cnf /etc/my.cnf.bak
4.2 准備多實例的數據目錄
由於多實例的數據目錄已經在單實例那里創建成功了,這一步就可以略過:
每台實例以端口命名,端口名目錄下存放配置文件,其中的data目錄存放各自的數據。
4.3 為每個實例創建配置文件
我們將每個實例(3306的可配置也可不配置,因為它默認使用的是/etc/my.cnf)的配置文件都放在各自端口目錄的下面,視情況修改下面參數,然后直接拷貝運行即可:
1 cat > /data/mysql/3307/my.cnf <<EOF 2 [mysqld] 3 basedir=/opt/software/mysql 4 datadir=/data/mysql/3307/data 5 socket=/data/mysql/3307/mysql.sock 6 log_error=/data/mysql/3307/logs/mysql_error.log 7 port=3307 8 server_id=7 9 [client] 10 socket=/data/mysql/3307/mysql.sock 11 EOF 12 13 cat > /data/mysql/3308/my.cnf <<EOF 14 [mysqld] 15 basedir=/opt/software/mysql 16 datadir=/data/mysql/3308/data 17 socket=/data/mysql/3308/mysql.sock 18 log_error=/data/mysql/3308/logs/mysql_error.log 19 port=3308 20 server_id=8 21 [client] 22 socket=/data/mysql/3308/mysql.sock 23 EOF 24 25 cat > /data/mysql/3309/my.cnf <<EOF 26 [mysqld] 27 basedir=/opt/software/mysql 28 datadir=/data/mysql/3309/data 29 socket=/data/mysql/3309/mysql.sock 30 log_error=/data/mysql/3309/logs/mysql_error.log 31 port=3309 32 server_id=9 33 [client] 34 socket=/data/mysql/3309/mysql.sock 35 EOF
完事之后,各自的數據目錄下就有了配置文件了:
1 [root@cs software]# ls /data/mysql/3307/ 2 backup data logs my.cnf 3 root@cs software]# cat /data/mysql/3307/my.cnf 4 [mysqld] 5 basedir=/opt/software/mysql 6 datadir=/data/mysql/3307/data 7 socket=/data/mysql/3307/mysql.sock 8 log_error=/data/mysql/3307/logs/mysql_error.log 9 port=3307 10 server_id=7 11 [client] 12 socket=/data/mysql/3307/mysql.sock
4.4 授權
[root@cs software]# chown -R mysql.mysql /data/mysql/*
現在,配置文件完事了,就可以着手進行初始化了。
4.5 多實例的初始化
1 mysqld --initialize-insecure --user=mysql --datadir=/data/mysql/3307/data --basedir=/opt/software/mysql 2 mysqld --initialize-insecure --user=mysql --datadir=/data/mysql/3308/data --basedir=/opt/software/mysql 3 mysqld --initialize-insecure --user=mysql --datadir=/data/mysql/3309/data --basedir=/opt/software/mysql
上面的命令執行時,會有Warning提示,這里不要管它。注意,如果你的服務器內存較小的話,可能后續啟不起來3台實例,不過有個2G內存也差不多了。
4.6 配置systemctl
實際上,下面這幾個配置文件內容都是來自於mysqld.service
文件,然后修改了各自實例的配置文件路徑:

1 cat > /etc/systemd/system/mysqld3307.service <<EOF 2 [Unit] 3 Description=MySQL Server 4 Documentation=man:mysqld(8) 5 Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html 6 After=network.target 7 After=syslog.target 8 [Install] 9 WantedBy=multi-user.target 10 [Service] 11 User=mysql 12 Group=mysql 13 ExecStart=/opt/software/mysql/bin/mysqld --defaults-file=/data/mysql/3307/my.cnf 14 LimitNOFILE = 5000 15 EOF 16 17 cat > /etc/systemd/system/mysqld3308.service <<EOF 18 [Unit] 19 Description=MySQL Server 20 Documentation=man:mysqld(8) 21 Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html 22 After=network.target 23 After=syslog.target 24 [Install] 25 WantedBy=multi-user.target 26 [Service] 27 User=mysql 28 Group=mysql 29 ExecStart=/opt/software/mysql/bin/mysqld --defaults-file=/data/mysql/3308/my.cnf 30 LimitNOFILE = 5000 31 EOF 32 33 cat > /etc/systemd/system/mysqld3309.service <<EOF 34 [Unit] 35 Description=MySQL Server 36 Documentation=man:mysqld(8) 37 Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html 38 After=network.target 39 After=syslog.target 40 [Install] 41 WantedBy=multi-user.target 42 [Service] 43 User=mysql 44 Group=mysql 45 ExecStart=/opt/software/mysql/bin/mysqld --defaults-file=/data/mysql/3309/my.cnf 46 LimitNOFILE = 5000 47 EOF
4.7 啟動
到這里,多實例的配置基本完畢,可以嘗試啟動了
1 systemctl start mysqld3307.service 2 systemctl start mysqld3308.service 3 systemctl start mysqld3309.service
驗證下:
1 [root@cs software]# find / -name mysql.sock 2 /data/mysql/3307/mysql.sock 3 /data/mysql/3308/mysql.sock 4 /data/mysql/3309/mysql.sock 5 [root@cs software]# netstat -lnp|grep 330 6 tcp6 0 0 :::3307 :::* LISTEN 8361/mysqld 7 tcp6 0 0 :::3308 :::* LISTEN 8368/mysqld 8 tcp6 0 0 :::3309 :::* LISTEN 8636/mysqld 9 unix 2 [ ACC ] STREAM LISTENING 55795 8361/mysqld /data/mysql/3307/mysql.sock 10 unix 2 [ ACC ] STREAM LISTENING 30540 8368/mysqld /data/mysql/3308/mysql.sock 11 unix 2 [ ACC ] STREAM LISTENING 74758 8636/mysqld /data/mysql/3309/mysql.sock
恢復單實例的配置文件
1 [root@cs software]# mv /etc/my.cnf.bak /etc/my.cnf
然后啟動3306這台實例,注意,3306的跟其他的實例不太一樣:
1 [root@cs software]# systemctl start mysqld.service 2 [root@cs software]# find / -name mysql.sock 3 /tmp/mysql.sock 4 /data/mysql/3307/mysql.sock 5 /data/mysql/3308/mysql.sock 6 /data/mysql/3309/mysql.sock 7 [root@cs software]# netstat -lnp|grep 330 8 tcp6 0 0 :::3306 :::* LISTEN 8748/mysqld 9 tcp6 0 0 :::3307 :::* LISTEN 8361/mysqld 10 tcp6 0 0 :::3308 :::* LISTEN 8368/mysqld 11 tcp6 0 0 :::3309 :::* LISTEN 8636/mysqld 12 unix 2 [ ACC ] STREAM LISTENING 55795 8361/mysqld /data/mysql/3307/mysql.sock 13 unix 2 [ ACC ] STREAM LISTENING 30540 8368/mysqld /data/mysql/3308/mysql.sock 14 unix 2 [ ACC ] STREAM LISTENING 74758 8636/mysqld /data/mysql/3309/mysql.sock
五、連接管理
現在4個實例都能正常運行后,擺在我們面前的是怎么連接到指定的實例?
有以下兩種方式可以連接到指定數據庫:
1 # 注意,此時的登錄密碼都為空,直接回車即可 2 [root@cs software]# mysql -uroot -p -S /tmp/mysql.sock -e "select @@server_id" 3 Enter password: 4 +-------------+ 5 | @@server_id | 6 +-------------+ 7 | 6 | 8 +-------------+ 9 [root@cs software]# mysql -uroot -p -S /data/mysql/3307/mysql.sock -e "select @@server_id" 10 Enter password: 11 +-------------+ 12 | @@server_id | 13 +-------------+ 14 | 7 | 15 +-------------+ 16 [root@cs software]# mysql -uroot -p -S /data/mysql/3308/mysql.sock -e "select @@server_id" 17 Enter password: 18 +-------------+ 19 | @@server_id | 20 +-------------+ 21 | 8 | 22 +-------------+ 23 [root@cs software]# mysql -uroot -p -S /data/mysql/3309/mysql.sock -e "select @@server_id" 24 Enter password: 25 +-------------+ 26 | @@server_id | 27 +-------------+ 28 | 9 | 29 +-------------+
以上是通過不同的mysql.sock
來來接指定的數據庫實例,除此之外,還可以通過-h -P
參數來連接到指定的數據庫實例
1 [root@cs software]# mysql -uroot -p -h127.0.0.1 -P3306 -e "select @@server_id" 2 Enter password: 3 +-------------+ 4 | @@server_id | 5 +-------------+ 6 | 6 | 7 +-------------+ 8 [root@cs software]# mysql -uroot -p -h127.0.0.1 -P3307 -e "select @@server_id" 9 Enter password: 10 +-------------+ 11 | @@server_id | 12 +-------------+ 13 | 7 | 14 +-------------+ 15 [root@cs software]# mysql -uroot -p -h127.0.0.1 -P3308 -e "select @@server_id" 16 Enter password: 17 +-------------+ 18 | @@server_id | 19 +-------------+ 20 | 8 | 21 +-------------+ 22 [root@cs software]# mysql -uroot -p -h127.0.0.1 -P3309 -e "select @@server_id" 23 Enter password: 24 +-------------+ 25 | @@server_id | 26 +-------------+ 27 | 9 | 28 +-------------+
六 、用戶管理
默認的,上面使用root用戶只有本地的訪問權限,遠程無法使用,且初始化時,我們將初始密碼也設置為空了:
1 [root@cs software]# mysql -uroot -p -h127.0.0.1 -P3306 -e "select user,host from mysql.user" 2 Enter password: 3 +---------------+-----------+ 4 | user | host | 5 +---------------+-----------+ 6 | mysql.session | localhost | 7 | mysql.sys | localhost | 8 | root | localhost | 9 +---------------+-----------+
所以,這里我們創建遠程用戶和創建密碼再配置相關權限:
1 -- 分別登錄到各自的實例中,此時密碼還未空,直接回車,然后執行下面命令,進行創建用戶並授權 2 -- mysql -uroot -p -h127.0.0.1 -P3306 3 -- mysql -uroot -p -h127.0.0.1 -P3307 4 -- mysql -uroot -p -h127.0.0.1 -P3308 5 -- mysql -uroot -p -h127.0.0.1 -P3309 6 7 grant all on *.* to root@'localhost' identified by '123'; 8 grant all on *.* to root@'%' identified by '123'; 9 flush privileges;
注意,上面的創建用戶和授權命令僅適用於MySQL8.0一下,因為從MySQL8.0開始,創建用戶和授權分為兩步操作,這點需要注意。
創建完成后,就可以通過密碼進行登錄了:
1 [root@cs software]# mysql -uroot -p123 -h127.0.0.1 -P3306 -e "select @@server_id" 2 mysql: [Warning] Using a password on the command line interface can be insecure. 3 +-------------+ 4 | @@server_id | 5 +-------------+ 6 | 6 | 7 +-------------+ 8 [root@cs software]# mysql -uroot -p123 -h127.0.0.1 -P3307 -e "select @@server_id" 9 mysql: [Warning] Using a password on the command line interface can be insecure. 10 +-------------+ 11 | @@server_id | 12 +-------------+ 13 | 7 | 14 +-------------+ 15 [root@cs software]# mysql -uroot -p123 -h127.0.0.1 -P3308 -e "select @@server_id" 16 mysql: [Warning] Using a password on the command line interface can be insecure. 17 +-------------+ 18 | @@server_id | 19 +-------------+ 20 | 8 | 21 +-------------+ 22 [root@cs software]# mysql -uroot -p123 -h127.0.0.1 -P3309 -e "select @@server_id" 23 mysql: [Warning] Using a password on the command line interface can be insecure. 24 +-------------+ 25 | @@server_id | 26 +-------------+ 27 | 9 | 28 +-------------+