更好的学习MySQL——从MySQL在Linux系统上的多实例安装部署开始【测试成功】

艺帆风顺 发布于 2025-04-03 20 次阅读


前言

一般来说,我们在学习MySQL开始,安装时可能是直接使用镜像源安装,也就是使用apt-get或者yum安装MySQL服务端和客户端之后再使用,这是最不需要动脑经以及动手的操作。

但是其实对于我(作为一个小白而言),这样的安装感觉许多东西都被系统“隐藏”了,因为这样的安装方式有点类似于Windows上我们在安装软件时的“默认安装”,众所周知,“默认安装”总会把很多东西放入C盘,这是我们不希望看到的,所以“高手”总是自定义安装,我们要向高手看齐~

作为MySQL初学者,我建议我们自己去安装,当然除非你是对于Linux系统非常熟悉或者至少已经入门的人。因为使用镜像源安装之后,可能我们会遇到一些比如:配置文件在哪?数据文件在哪?如何修改成你自己想要的配置?我想要查看我的日志,如何找到我的日志文件?等等诸如此类的问题,而去了解配置文件、数据库文件、日志文件对于学习MySQL是有很大的帮助的~

  1. 配置文件决定了MySQL启动之后的所有默认功能;

  2. 数据文件存储了表文件及数据,不同数据库引擎,每个表的扩展名也不一样,例如MyISAM引擎用".MYD"作为扩展名,InnoDB用".ibd",CSV使用".csv"扩展名

  3. 日志文件主要记录了数据库操作信息和错误信息,常用的日志文件包括错误日志,二进制日志,查询日志和InnoDB引擎在线Redo日志等

所以,这里我强烈推荐在Linux系统上(Ubuntu和CentOS)“自定义”安装MySQL,也就是实例安装,这样,在学习过程中,我们可以非常轻松的查找、删除或修改任何我们所需要的文件和数据

多实例

多实例也就是在你一台电脑上可以开启多个MySQL服务器,这些服务器可以由端口号区分。不必担心,每一个实例(即单实例)其实就是一个正常的MySQL服务器,所以多实例也就是指安装了多个(或者说重复的,一模一样的)单实例MySQL服务,单实例和多实例没有本质区别,只是安装步骤重复罢了。

安装准备

在开始安装之前,也就是写这篇文章的此时此刻,我重新安装了一个CentOS系统,所以完全是从零开始的安装,因为这样我在安装过程中就会尽可能遇到更多的问题,然后尝试去解决,给大家提供尽可能广泛的参考意见

Linux系统

这里我使用的是CentOS 8,我的主机名称是lwz,我的当前普通用户名称也是 lwz,所以在下文中如果你有需要复制某一行代码,注意替换即可,下面是我的测试系统:

[lwz@lwz ~]$ cat /proc/version
Linux version 4.18.0-193.el8.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC)) #1 SMP Fri May 8 10:59:10 UTC 2020

VIM编辑[1](非必需)

本文所有有关文本编辑我都是使用的VIM编辑,例如打开一个文件我会直接用vim命令,如果你不是使用的vim编辑器,那么使用其它文本编辑是一样的,看个人习惯,你可以使用gedit打开文本,甚至鼠标双击也行,因为文本其实就是.txt文件

vim虽然入门都比较难(相较于其它),主要“归功于”超多的编辑模式、命令模式和一个晦涩的可视模式,但是我想,我们在开始可以只学几个基本的动作,几个基本的快捷键,也能满足日常需求了,等慢慢熟悉了,可以再补充学习其它快捷键

安装依赖

切换至root超级管理员,安装MySQL启动时必要的依赖:

[root@lwz ~]# yum install libtinfo.so.5
[root@lwz ~]# yum install ncurses-compat-libs

如果你在使用yum安装时可能会报如下错误

CentOS-8 - AppStream 60 B/s | 38 B 00:00 
Error: Failed to download metadata for repo 'AppStream': Cannot prepare internal mirrorlist: No URLs in mirrorlist

因为我是从零开始的系统,所以一定会报这个错误,如果你在此之前已经更改了yum镜像源,那么跳过下列步骤

这是因为CentOS自去年开始已经停止维护(这是系统的问题,不是你的问题,不要慌~)导致无法下载这些依赖,我们需要更改一下系统本身的配置,修改一下CentOS的镜像下载源,如果你不熟悉Linux环境,那么你只需要按照顺序执行下列操作即可

[root@lwz ~]# cd /etc/yum.repos.d/
[root@lwz yum.repos.d]# vim CentOS-AppStream.repo

打开文件之后将下列内容替换原有的[AppStream]的所有内容

[AppStream]
name=CentOS Linux $releasever - AppStream
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=AppStream&infra=$infra
#baseurl=http://mirror.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
baseurl=https://vault.centos.org/centos/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

再打开另一个文件

[root@lwz yum.repos.d]# vim CentOS-Base.repo

打开文件之后将下列内容替换原有的[BaseOS]的所有内容

[BaseOS]
name=CentOS Linux $releasever - BaseOS
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=BaseOS&infra=$infra
#baseurl=http://mirror.centos.org/$contentdir/$releasever/BaseOS/$basearch/os/
baseurl=https://vault.centos.org/centos/$releasever/BaseOS/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

上述是基于CentOS系统的,可能比较麻烦(大概率下你是需要换源的),但是如果你是Ubuntu系统,那么只需要使用下面两行代码就可以安装完成所需依赖:

sudo apt-get install libaio1
sudo apt-get install libtinfo5

下载安装包

从官网下载安装包,官网下载地址:Download MySQL Community Server (Archived Versions)

下载地址会根据你的当前系统,自动帮你跳转到符合你系统的下载路径,注意选择,如果你当前是Ubuntu系统,选择Ubuntu Linux即可
本次测试的是MySQL 8.0,如果你需要MySQL 5.6,在当前页面有相应的MySQL的版本选择

由于当前使用的是CentOS 64位的系统,我当前的选择是:

  1. 安装包名称:Linux - Generic (glibc 2.12) (x86, 64-bit), Compressed TAR Archive

  2. 安装包大小:1148.5M

  3. 安装包发布日期:Dec 18, 2021

注意64位和32位的区分

下载压缩包应该会默认保存在你的家目录下的Downloads目录,当然你也可以在下载在自己指定的目录下

官网下载窗口

解压安装包

安装包是 .tar.xz 格式的压缩包,使用下列tar命令解压

[lwz@lwz Downloads]$ tar -xvf mysql-8.0.28-linux-glibc2.12-x86_64.tar.xz

重命名安装包

为了安装过程方便一点,我们把这个解压之后的安装包重命名一下,这里我重命名之后的安装包名为mysql,你们可以随意

[lwz@lwz Downloads]$ mv mysql-8.0.28-linux-glibc2.12-x86_64 mysql

因为Downloads目录只是我存放下载安装包的目录(例如MySQL Router和MySQL Workbench,如果有机会的话,我也会再写关于这两个MySQL管理软件的文章),所以为了后续测试方便,我把mysql包移动到我的家目录下的Public目录

[lwz@lwz Downloads]$ mv mysql /home/lwz/Public/

如果你是第一次安装,那么我建议你和我一样,和我放在相同的路径下,这样你就可以方便的复制我的代码,当然用户名还是需要改成你自己的系统用户名称

让我们去看看安装包里有什么东西

[lwz@lwz mysql]$ pwd
/home/lwz/Public/mysql
[lwz@lwz mysql]$ ll
total 288
drwxr-xr-x. 2 lwz lwz 4096 Dec 18 02:28 bin
drwxr-xr-x. 2 lwz lwz 55 Dec 18 02:28 docs
drwxr-xr-x. 3 lwz lwz 4096 Dec 18 02:28 include
drwxr-xr-x. 6 lwz lwz 201 Dec 18 02:28 lib
-rw-r--r--. 1 lwz lwz 276595 Dec 18 00:07 LICENSE
drwxr-xr-x. 4 lwz lwz 30 Dec 18 02:28 man
-rw-r--r--. 1 lwz lwz 666 Dec 18 00:07 README
drwxr-xr-x. 28 lwz lwz 4096 Dec 18 02:28 share
drwxr-xr-x. 2 lwz lwz 77 Dec 18 02:28 support-files

创建数据目录

在mysql包内创建三个文件夹,这里我分别命名为3306,3307和3308,这里文件夹的名称是需要和后面的配置文件相对应的,你可以暂且和我一样

[lwz@lwz mysql]$ mkdir 3306
[lwz@lwz mysql]$ mkdir 3307
[lwz@lwz mysql]$ mkdir 3308

3306,3307和3308文件夹就是分别放置我们每个实例(MySQL服务器)中的所有数据库、数据表和一些日志文件的地方,每一个文件夹你可以看作是一个MySQL服务器

开始安装

添加配置文件

在mysql包内新建一个文件,这里我把这个文件自定义命名为 my.cnf,从此以后(划重点),my.cnf就是我们一直要使用的配置文件,这个文件非常重要,但这是我们自定义的,是我们亲手创造的,所以一切尽在我们的掌握之中~

[lwz@lwz mysql]$ touch my.cnf

使用文本编辑器(这里我用的是VIM,你也可以使用gedit)打开文件

[lwz@lwz mysql]$ vim my.cnf

打开my.cnf配置文件之后,将下列代码复制进入my.cnf文件中,可以暂时先不需要理解这些内容:

[mysqld]
basedir = /home/lwz/Public/mysql

[mysqld_multi]
mysqld=/home/lwz/Public/mysql/bin/mysqld_safe
mysqladmin=/home/lwz/Public/mysql/bin/mysqladmin
log=/home/lwz/Public/mysql/mysqld_multi.log

# 这是实例3306
[mysqld3306]
mysqld=mysqld
mysqladmin=mysqladmin
datadir=/home/lwz/Public/mysql/3306/data
port=3306
server-id=1
socket=/home/lwz/Public/mysql/mysql_3306.sock

# 这是实例3307
[mysqld3307]
mysqld=mysqld
mysqladmin=mysqladmin
datadir=/home/lwz/Public/mysql/3307/data
port=3307
server-id=2
socket=/home/lwz/Public/mysql/mysql_3307.sock

# 这是实例3308
[mysqld3308]
mysqld=mysqld
mysqladmin=mysqladmin
datadir=/home/lwz/Public/mysql/3308/data
port=3308
server-id=3
socket=/home/lwz/Public/mysql/mysql_3308.sock

这里你需要更改成你自己的系统中安装路径,如果你和我一样mysql包放在在家目录下的Public目录,那么你只需要将我的配置文件中的lwz换成你的用户名即可。

其次,这个配置文件中已经计划开启三个实例,根据端口号分我们把分别把他们称为3306,3307和3308,大致的示意图为

配置文件

MySQL的默认端口是3306,但我们可以自定义设置,只要不和系统冲突即可,一般来说,不会冲突

配置MySQL的PATH

在Linux系统中,MySQL的命令还不能直接使用,如果你之前使用过命令安装,那么你对下列命令一定不陌生

$ mysql -u root -p

因为我们这次是实例安装,所以一切都需要我们自己动手配置,也就是说,我们目前还不能直接在终端(bash窗口)使用MySQL的二进制命令,所以我们需要配置自己家目录下的.bashrc文件,将MySQL的二进制文件加入PATH中

[lwz@lwz mysql]$ echo PATH=/home/lwz/Public/mysql/bin:$PATH >> /home/lwz/.bashrc 
[lwz@lwz mysql]$ source /home/lwz/.bashrc

再次提醒,这里是我的路径,你需要更改成自己的路径,然后,你也不是必须理解这两行代码的意思,除非你了解过一丁点Linux中二进制命令的使用

安装实例

每一个实例相当于一个MySQL服务器,你可以通过配置文件控制实例的数量,如果使用多实例安装,那么你可以搭建一个较有规模的数据库集群

安装实例3306

使用mysqld命令安装

[lwz@lwz mysql]$ mysqld --defaults-file=/home/lwz/Public/mysql/my.cnf --initialize --basedir=/home/lwz/Public/mysql/ --datadir=/home/lwz/Public/mysql/3306/data/
2022-05-11T13:44:29.476733Z 0 [System] [MY-013169] [Server] /home/lwz/Public/mysql/bin/mysqld (mysqld 8.0.28) initializing of server in progress as process 3407
2022-05-11T13:44:29.487318Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-05-11T13:44:31.571469Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-05-11T13:44:33.753198Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: eh;lAdf?S4lG

安装过程的最后,最后一行会显示root账户的初始密码:eh;lAdf?S4lG

这里建议初始密码复制出来待用,因为密码复杂不好记,万一窗口不小心被关了就麻烦了
这里需要注意,执行命令时,路径前面不能有空格,例如--defaults-file=/home/lwz/Public/mysql/my.cnf的/home/lwz/Public/mysql/my.cnf和前面的等号”=“之间不能有空格

安装实例3307

相同的安装方法,注意安装到3307文件夹,记一下初始密码

[lwz@lwz mysql]$ mysqld --defaults-file=/home/lwz/Public/mysql/my.cnf --initialize --basedir=/home/lwz/Public/mysql/ --datadir=/home/lwz/Public/mysql/3307/data/
2022-05-11T14:23:12.110767Z 0 [System] [MY-013169] [Server] /home/lwz/Public/mysql/bin/mysqld (mysqld 8.0.28) initializing of server in progress as process 3963
2022-05-11T14:23:12.123124Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-05-11T14:23:12.991333Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-05-11T14:23:14.911427Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: mX7dfytAYZ(f

安装实例3308

[lwz@lwz mysql]$ mysqld --defaults-file=/home/lwz/Public/mysql/my.cnf --initialize --basedir=/home/lwz/Public/mysql/ --datadir=/home/lwz/Public/mysql/3308/data/
2022-05-11T14:26:47.766004Z 0 [System] [MY-013169] [Server] /home/lwz/Public/mysql/bin/mysqld (mysqld 8.0.28) initializing of server in progress as process 4040
2022-05-11T14:26:47.777953Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2022-05-11T14:26:49.084286Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2022-05-11T14:26:51.322333Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: mt#Ak%bzo9NR

查看多实例

使用mysqld_multi命令查看这些MySQL服务是否开启

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf report
Reporting MySQL servers
MySQL server from group: mysqld3306 is not running
MySQL server from group: mysqld3307 is not running
MySQL server from group: mysqld3308 is not running

可以看到显示的是 not running 的状态,说明这些MySQL服务还没开启,暂时还不能使用

开启多实例

使用mysqld_multi命令开启实例

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf start 3306,3307,3308

这里一次性同时开启了三个实例

假设你只想要单独开启某一个实例3306,那么只需要start 3306即可

再次查看多实例(mysqld_multi命令)

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf 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

可以看到显示的是 is running 的状态,说明这些MySQL服务已经开启,成功开启多实例之后,在mysql目录下,可以发现多了若干个socket文件,socket文件的后缀为.sock

[lwz@lwz mysql]$ ll | grep sock
srwxrwxrwx. 1 lwz lwz 0 May 11 22:34 mysql_3306.sock
-rw-------. 1 lwz lwz 5 May 11 22:34 mysql_3306.sock.lock
srwxrwxrwx. 1 lwz lwz 0 May 11 22:34 mysql_3307.sock
-rw-------. 1 lwz lwz 5 May 11 22:34 mysql_3307.sock.lock
srwxrwxrwx. 1 lwz lwz 0 May 11 22:34 mysql_3308.sock
-rw-------. 1 lwz lwz 5 May 11 22:34 mysql_3308.sock.lock

如果没有这些socket[2]文件,说明MySQL服务没有开启,生成这些socket文件才是我们的最终目的

socket方式登录

现在终于可以使用mysql命令进行服务器登录,使用socket的方式登录,必须使用-S参数,并且在后面加上.sock文件的位置,需要注意的是,之后每一次登录,都需要使用这种-S方式进行登录

[root@lwz ~]# mysql -u root -p -S /home/lwz/Public/mysql/mysql_3306.sock
Enter password:

这里我首先使用的是3306的socket连接登录,,系统会提示输入密码,我们将上面记录好的初始密码输入,密码输入后,跳出如下界面,则说明MySQL安装成功!

[root@lwz ~]# mysql -u root -p -S /home/lwz/Public/mysql/mysql_3306.sock
Enter password:
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 9
Server version: 8.0.28

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql>

更改root的密码

使用初始密码登录之后的root用户,会强制要求你更改你自己的密码才能操作数据库,为了后续方便学习,我将这个3306端口的服务器的密码设置为3306,所以我会使用下列代码更改密码,请你更改你自己需要的root密码

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '3306';
Query OK, 0 rows affected (0.01 sec)

至此,完成了MySQL 8.0的全部安装,上面登录成功的是连接端口为3306的MySQL服务,大家可以重复上述步骤完成3307和3308的登录并且修改密码

最后的注意点

关机之后

由于我们使用的是socket登录,系统关闭之后,端口的服务会自动断开,所以每次开机之后我们都需要先使用mysqld_multi命令开启实例,虽然比较麻烦,好在不影响我们的主从复制,如果有机会,我会写一篇主从复制的搭建

更改配置文件之后

由于我们使用的是二进制安装,没有服务重启的功能,所以我们更改了配置文件之后,想要新的配置文件生效,目前我只有一种方法:

第一步:首先使用ps命令找到MySQL服务进程,例如

[lwz@lwz ~]$ ps aux | grep mysqld
lwz 4174 0.3 9.9 2154208 397904 pts/0 Sl May11 0:26 mysqld --datadir=/home/lwz/Public/mysql/3306/data --port=3306 --server-id=1 --socket=/home/lwz/Public/mysql/mysql_3306.sock
lwz 4177 0.3 10.0 2287320 401468 pts/0 Sl May11 0:26 mysqld --datadir=/home/lwz/Public/mysql/3307/data --port=3307 --server-id=2 --socket=/home/lwz/Public/mysql/mysql_3307.sock
lwz 4180 0.3 9.9 2154212 396860 pts/0 Sl May11 0:26 mysqld --datadir=/home/lwz/Public/mysql/3308/data --port=3308 --server-id=3 --socket=/home/lwz/Public/mysql/mysql_3308.sock
root 34208 0.0 0.0 12132 1212 pts/0 S+ 00:41 0:00 grep --color=auto mysqld

第二步:使用kill命令杀掉进程

[lwz@lwz ~]$ kill 4174 4177 4180

杀死这些进程之后,你会发现那些socket文件也被删除了

第三步:重新开启

[lwz@lwz ~]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf start 3306,3307,3308

大家习惯的MySQL服务重启可能是systemctl restart这种方式,一行代码搞定,相比较多实例安装下MySQL重启确实要比传统的安装方式麻烦很多,但是现在我也习惯了,因为经常需要修改配置文件的内容,所以有点轻车熟路,再不济写个脚本吧.....如果你有好的方法,欢迎你告诉我~~

后续更新....

日志文件及数据

最后,回到我们最初关心的问题,我们自定义安装之后,那些我们需要的文件和数据在哪,现在我们可以一一找到,以其中一个实例(3306)为例

问:我的配置文件在哪?

当然就是我们在准备阶段自己创建的my.cnf文件了,可以直接使用文本编辑器打开查看或修改(修改之后需要重启服务)。相比于那些默认安装在/etc下的配置文件,我更喜欢自己掌控~

友情提示:如果你使用apt-get或者yum安装的MySQL服务器,那么你的默认的官方配置文件所在路径为/etc/mysql/mysql.cnf.d/mysqld.cnf

问:我的MySQL启动日志在哪?

答:启动日志记录了MySQL启动时的状态,如果你启动失败可以查看该日志,可以使用最普通的文本编辑器打开,根据ERROR信息进行必要的调整。由于我们的配置文件my.cnf指定了生成路径,该日志在MySQL服务启动后自动生成在你的mysql包内,全称为mysqld_multi.log

问:二进制文件在哪?

二进制文件主要记录MySQL数据库的变化,包含了所有更新了数据或者潜在更新了数据(例如没有匹配任何一行的UPDATE)的语句;还包含了每个更新数据库的语句的执行时间信息,使用二进制日志的目的是最大可能的恢复数据库,因为二进制日志包含备份后进行的所有更新,而且二进制文件是主从复制的重要桥梁和关键所在

我们的二进制文件就在我们最初创建的3306文件夹内,具体路径是mysql/3306/data,使用 mysqlbinlog查看二进制文件

[lwz@lwz data]$ pwd
/home/lwz/Public/mysql/3306/data
[lwz@lwz data]$ mysqlbinlog binlog.000001

每次重启服务器,都会新生成一个二进制日志,后缀以.000001开始递增

关于二进制文件的操作(数据恢复,删除,主从等)有机会的话我会新开一个文章详细描述

问:其它日志文件在哪?

答:其它日志包括慢查询日志,通用查询日志和错误日志,这些日志在这种安装方式下默认是不开启的,而且入门的话也是不需要用到的,新手阶段请跳过......

在对配置文件和MySQL有一定了解之后,我们可以通过修改我们的my.cnf配置文件或者MySQL命令来开启,例如,如果我们在配置文件中加上一行代码,就可以开启错误日志,当MySQL需要记录错误发生时,就会保存在我们设置的路径上的日志中

# log_error记录了错误日志所在位置
log_error = /home/lwz/Public/mysql/3306/data/my_error.log

如果我们需要开启通用查询日志,可以在MySQL中使用命令开启

mysql> set @@global.general_log = 1;
Query OK, 0 rows affected (0.01 sec)

执行成功之后,我们就会在我们的mysql/3306/data目录下新增一个.log的日志文件

如果我们需要开启慢羊羊日志,那么在MySQL中使用命令

mysql> set @@global.slow_query_log = 1;
Query OK, 0 rows affected (0.01 sec)

执行成功之后,我们就会在我们的mysql/3306/data目录下新增一个-slow.log的日志文件

问:我的数据文件在哪?

答:当然在mysql/3306/data目录下,所有创建的数据库,数据表,索引表.....都在我们一开始创建的3306包内

友情提示,如果你使用apt-get或者yum安装的MySQL服务器,那么你的数据库,数据表,binlog日志等所在路径为/var/lib/mysql,而且你会发现这个mysql及其子目录是锁住的状态

综上,只要我们学会了实例安装MySQL,每一个日志文件和数据文件都可以被我们指定存放所在位置,不需要我们去寻找它们的身影,属实方便,只要我们愿意,我们可以把它们一起放在我们触手可及的地方~

番外篇——多实例解耦

在上文中,我们把若干个实例的配置信息放在同一个配置文件my.cnf中,如果若干个实例都是通过同一个配置文件启动,那么耦合性就太高了,试想一下,当我们同时开启了若干个实例,例如同时开启了3306,3307和3308MySQL服务,而在中途突然需要改变一下3306服务的配置,那么修改配置文件之后进行MySQL服务的重启,又因为服务重启是通过配置文件启动的,而其它实例的配置内容又在同一份文件中,那么有可能在对3306修改时造成对其它实例的影响

一般而言,耦合度是越低越好,这样每个实例的修改不受其它实例的影响,也不会去影响其它实例

基于上述问题,为了降低MySQL各个服务的耦合度,我们可以通过创建多个配置文件来生成多个实例,通俗一点说,一个单独的MySQL服务就有一个单独的配置文件,这样,每一个MySQL服务之间就被分割开了,单独的修改配置,不会对其它服务造成影响,以此降低耦合

为了测试,我直接删除了原先的mysql安装包,在/home/lwz/Public/目录下放了一个新的安装包,和上面一样新建三个文件夹3306,3307和3308

配置文件

在上文中,我们只创建了一个配置文件my.cnf,然后通过一个配置文件生成三个MySQL实例,现在不一样,我们需要创建三个配置文件来创建三个MySQL实例,每一个实例都有自己的配置文件,为了方便起见,我将三个配置文件分别命名为3306.cnf,3307.cnf和3308.cnf

[lwz@lwz mysql]$ touch 3306.cnf
[lwz@lwz mysql]$ touch 3307.cnf
[lwz@lwz mysql]$ touch 3308.cnf

然后在3306.cnf配置文件中添加下列内容:

[mysqld]
basedir = /home/lwz/Public/mysql

[mysqld_multi]
mysqld=/home/lwz/Public/mysql/bin/mysqld_safe
mysqladmin=/home/lwz/Public/mysql/bin/mysqladmin
log=/home/lwz/Public/mysql/mysqld_multi.log

# 这是实例3306
[mysqld3306]
mysqld=mysqld
mysqladmin=mysqladmin
datadir=/home/lwz/Public/mysql/3306/data
port=3306
server-id=1
socket=/home/lwz/Public/mysql/mysql_3306.sock

在3307.cnf配置文件中添加下列内容:

[mysqld]
basedir = /home/lwz/Public/mysql

[mysqld_multi]
mysqld=/home/lwz/Public/mysql/bin/mysqld_safe
mysqladmin=/home/lwz/Public/mysql/bin/mysqladmin
log=/home/lwz/Public/mysql/mysqld_multi.log

# 这是实例3307
[mysqld3307]
mysqld=mysqld
mysqladmin=mysqladmin
datadir=/home/lwz/Public/mysql/3307/data
port=3307
server-id=2
socket=/home/lwz/Public/mysql/mysql_3307.sock

在3308.cnf配置文件中添加下列内容:

[mysqld]
basedir = /home/lwz/Public/mysql

[mysqld_multi]
mysqld=/home/lwz/Public/mysql/bin/mysqld_safe
mysqladmin=/home/lwz/Public/mysql/bin/mysqladmin
log=/home/lwz/Public/mysql/mysqld_multi.log

# 这是实例3308
[mysqld3308]
mysqld=mysqld
mysqladmin=mysqladmin
datadir=/home/lwz/Public/mysql/3308/data
port=3308
server-id=3
socket=/home/lwz/Public/mysql/mysql_3308.sock

不难发现,我们只是对先前的my.cnf文件内容进行了分割,保持[mysqld]与[mysqld_multi]的内容不变,将[mysqld3306],[mysqld3307]和[mysqld3308]分别写入3306.cnf,3307.cnf和3308.cnf三个配置文件中

解耦之后,配置文件与实例的关系变成这样了:

配置文件,解耦

安装实例

安装实例3306

[lwz@lwz mysql]$ mysqld --defaults-file=/home/lwz/Public/mysql/3306.cnf --initialize --basedir=/home/lwz/Public/mysql/ --datadir=/home/lwz/Public/mysql/3306/data/

安装实例3307

[lwz@lwz mysql]$ mysqld --defaults-file=/home/lwz/Public/mysql/3307.cnf --initialize --basedir=/home/lwz/Public/mysql/ --datadir=/home/lwz/Public/mysql/3307/data/

安装实例3308

[lwz@lwz mysql]$ mysqld --defaults-file=/home/lwz/Public/mysql/3308.cnf --initialize --basedir=/home/lwz/Public/mysql/ --datadir=/home/lwz/Public/mysql/3308/data/

查看多实例

使用mysqld_multi命令单独查看每个实例是否开启

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3306.cnf report
Reporting MySQL servers
MySQL server from group: mysqld3306 is not running

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3307.cnf report
Reporting MySQL servers
MySQL server from group: mysqld3307 is not running

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3308.cnf report
Reporting MySQL servers
MySQL server from group: mysqld3308 is not running

可以看到3306,3307,3308实例均没有开启(is not running)

开启多实例

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3306.cnf start 3306
[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3307.cnf start 3307
[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3308.cnf start 3308

开启多实例之后再次查看

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3306.cnf report
Reporting MySQL servers
MySQL server from group: mysqld3306 is running

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3307.cnf report
Reporting MySQL servers
MySQL server from group: mysqld3307 is running

[lwz@lwz mysql]$ mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3308.cnf report
Reporting MySQL servers
MySQL server from group: mysqld3308 is running

可以看到显示的是is running的状态,说明这些MySQL服务已经开启,成功开启多实例之后,在mysql目录下,可以发现多了若干个socket文件,socket文件的后缀为.sock

socket方式登录

[root@lwz ~]# mysql -u root -p -S /home/lwz/Public/mysql/mysql_3306.sock
Enter password:

更改root的密码

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '3306';
Query OK, 0 rows affected (0.01 sec)

至此,又一次完成了MySQL 8.0的全部安装,上面登录成功的是连接端口为3306的MySQL服务,大家可以重复上述步骤完成3307和3308的登录并且修改密码

附:脚本代码(非必需)

文中说到修改配置文件之后需要强制关闭mysqld进程之后再重新开启,这里提供一个脚本(仅作参考)可以快速进行MySQL服务重启

#!/bin/bash
# 封装MySQL开启功能
function mysql_start()
{
mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/3306.cnf start 3306
return 0;
}
mysql_port=$( ps aux | grep mysql | awk -F " " '/3306/{ print $2 }' )
# 杀死进程
if [ ${mysql_port}"x" = "x" ]
then
echo "数据库尚未启动"
# 询问是否需要开启
read -p "是否要开启数据库(Y|N):" -t 60 user_input
if [ $user_input = "y" -o $user_input = "Y" ]
then
mysql_start
else
echo "不开启MySQL"
exit
fi
else
kill $mysql_port
echo "MySQL端口关闭,等待重新开启"
fi

结束

欢迎大家讨论补充,如有不对或者哪里有描述不准确或歧义的地方,敬请指正,感谢~~对了,你知道这样的安装方式怎么卸载MySQL吗[doge]

[lwz@lwz Public]$ rm -rf mysql/

不用担心在系统内有任何残留哦~

常见报错排查:

1、多实例启动命令无报错,但是启动成功无响应,仍然是not running?

    [root@cheliangweb mysql]# mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf start 3306,3307,3308[root@cheliangweb mysql]# pwd/home/lwz/Public/mysql[root@cheliangweb mysql]# ls -alh /home/lwz/Public/mysql/my.cnf-rw-r--r--. 1 root root 733 12月 19 16:23 /home/lwz/Public/mysql/my.cnf[root@cheliangweb mysql]# mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf start 3306,3307,3308[root@cheliangweb mysql]# mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf reportReporting MySQL serversMySQL server from group: mysqld3306 is not runningMySQL server from group: mysqld3307 is not runningMySQL server from group: mysqld3308 is not running

    解决:尝试单独启动实例,并查看具体报错信息。

      mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf start 3306mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf start 3307mysqld_multi --defaults-extra-file=/home/lwz/Public/mysql/my.cnf start 3308

      2、单实例启动报错,如何排查?

        [root@cheliangweb mysql]# tail -f mysqld_multi.log 2023-12-19T08:31:23.458519Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).2023-12-19T08:31:23.458636Z 0 [Note] --secure-file-priv is set to NULL. Operations related to importing and exporting data are disabled2023-12-19T08:31:23.458680Z 0 [Note] mysqld (mysqld 5.7.40) starting as process 21829 ...2023-12-19T08:31:23.458711Z 0 [ERROR] Can't find error-message file '/usr/local/mysql/share/errmsg.sys'. Check error-message file location and 'lc-messages-dir' configuration directive.2023-12-19T08:31:23.460702Z 0 [ERROR] Fatal error: Please read "Security" section of the manual to find out how to run mysqld as root!
        2023-12-19T08:31:23.460742Z 0 [ERROR] Aborting
        2023-12-19T08:31:23.460765Z 0 [Note] Binlog end2023-12-19T08:31:23.460955Z 0 [Note]

            (1)解决:处理错误:Fatal error: Please read "Security" section of the manual to find out how to run mysqld as root!

            这个错误表明 MySQL 正在以 root 用户身份运行。根据 MySQL 的最佳实践,为了增加安全性,不应以 root 用户身份运行 MySQL 服务。

            应该创建一个专用的用户(例如 'mysql'),并以该用户的身份运行 MySQL 服务。确保你的 MySQL 配置文件中没有使用 user = root 这样的配置项。修改配置文件,将 user 配置项更改为 mysql 或其他非特权用户:

             useradd -r -g mysql -s /bin/bash mysql

             chown -R mysql:mysql   数据库路径

            (2)提示:TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).

            这个提示表明在创建表时使用了 TIMESTAMP 类型而没有指定默认值,这在新版本的 MySQL 中被认为是不安全的。为了避免这个提示,可以在启动 MySQL 时添加 --explicit_defaults_for_timestamp 选项

          user = mysqlexplicit_defaults_for_timestamp = true

            版权声明:本文内容来自知乎:小小小LOLLOL,遵循CC 4.0 BY-SA版权协议上原文接及本声明。本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进许可。原文链接:https://zhuanlan.zhihu.com/p/512767074如有涉及到侵权,请联系,将立即予以删除处理。在此特别鸣谢原作者的创作。此篇文章的所有版权归原作者所有,与本公众号无关,商业转载建议请联系原作者,非商业转载请注明出处。