二进制安装 MySQL 2.0

二进制安装 MySQL 2.0

vate_room 228 2022-12-23

二进制安装 MySQL8.0(v2.0)

时隔几个月后,又重新装了一遍 MySQL 思路比之前清晰多了。虽然还有不足之处,但比之前好多了,写个教程备忘一下。此教程已经写的尽量详细了,但读者最好还是有一点点 Linux 基础。

如果想省事情,可以直接选择用包管理器一键安装。apt install mysql yum install mysql

文件准备

下载文件

官方下载地址

image-1671769926600

确认glibc 版本

确保自己的 glibc 版本高于 软件包标识的版本

比如,我图里安装包的glibc 版本是2.12。那么系统的glibc必须高于 2.12。

如果系统的glibc 太低就不要下了。建议换个新一点的系统,或者找旧一点的二进制包。

#查看 glibc 版本
$> ldd --version
#下载安装包:
$> wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz

解压文件

#解压之前下载的MySQL二进制文件 
$> tar -xvf mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz

#文件夹名改成mysql
$> mv mysql-8.0.30-linux-glibc2.12-x86_64 mysql

#将下载的包移到指定目录
$> mv mysql /usr/local/mysql

#打扫一下战场,把压缩包删了
$> rm -f mysql-8.0.30-linux-glibc2.12-x86_64.tar.xz

#进入刚刚解压出来的 MySQL 文件夹
$> cd /usr/local/mysql	

环境准备

解决依赖问题:

#先进到mysql/bin目录里
$> cd /usr/local/mysql/bin

#查看缺少的依赖,如果没输出就说明都不缺
$> ldd mysqld mysql | grep "not found"
        
        libnuma.so.1 => not found
        libtinfo.so.5 => not found

我这里缺了 libnuma libtinfo 这俩个依赖,这里拿我缺少的俩个依赖举一下例子,大家要根据实际情况缺什么补什么。

解决 llibnuma.so.1 缺少问题

#搜索一下包
$> apt search libnuma

libnuma1/stable 2.0.12-1+b1 amd64

#可以看到搜索到的包名叫libnuma1 
#根据搜索到底结果安装
$> apt install libnuma1 

同理:

解决 libtinfo.so.5 缺少问题

#没有的话就找一下包
$> apt search libtinfo

libtinfo5/stable 6.2+20201114-2 amd64
libtinfo6/stable,now 6.2+20201114-2 amd64 [installed]
 

#可以看到搜索到的包有libtinfo5 和libtinfo6 
#我们缺少libtinfo.so.5 就安装 libtinfo5
apt install libtinfo5

创建用户和文件

目录规划

要确保mysql用户有对应文件夹的权限(都放在一起是为了好找、好删,不太规范,不要学我)

目录/文件作用
/etc/my.cnfMySQL全局配置文件
/usr/local/mysqlbasedir(MySQL主程序目录)
/usr/local/mysql/data/datadirdatadir(数据目录)
/usr/local/mysql/data/binlogbinary logs(顾名思义,binlog文件目录)
/usr/local/mysql/data/backup备份文件目录
/tmp/mysqltmpdir(临时文件目录)
/usr/local/mysql/data/mysql.socksocket (socke文件地址,登录用的)
/usr/local/mysql/data/error.loglog_error(错误日志)
/usr/lib/systemd/system/mysqld.service存放进程守护配置文件

创建mysql用户

创建mysql用户组mysql用户

#创建 MySQL 用户组
$> groupadd mysql

#创建 MySQL 用户
$> useradd -r -g mysql -s /bin/false -d /dev/null mysql 				

创建文件夹

创建存数据的文件夹,并赋权!!!赋权很重要。权限不够初始化会失败

#创建用来存放数据的文件夹
$> mkdir -p /usr/local/mysql/data/binlog /usr/local/mysql/data/backup  /usr/local/mysql/data/datadir /tmp/mysql

#修改 改文件夹的所属用户和组
$> chown  -R mysql:mysql /usr/local/mysql/data /tmp/mysql 

#修改 改文件夹的权限
$> chmod 755 -R /usr/local/mysql/data /tmp/mysql 		

编写my.cnf配置文件

编写MySQL配置文件

$> vim /etc/my.cnf


[client]
socket=/usr/local/mysql/data/mysql.sock
[mysqld]
#user 指定要使用的系统用户
user=mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data/datadir
socket=/usr/local/mysql/data/mysql.sock
port=3306

character-set-server=UTF8MB4
default_time_zone="+8:00"
secure_file_priv=/tmp/mysql
tmpdir=/tmp/mysql
log_error=/usr/local/mysql/data/error.log
slow_query_log=1
log_bin=/usr/local/mysql/data/binlog

要确认 my.cnf 里配置文件中涉及到的目录,是否存在,有没有权限

添加环境变量

#把bin目录添加到环境变量
#这里用到了echo输出,和>>追加文本到文件末尾的命令。
#echo+单引号号表示原样输出字符串,不进行转义或取变量
$> echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile	

$> source /etc/profile

初始化和相关配置

初始化数据库

$> /usr/local/mysql/bin/mysqld --initialize --user=mysql

查看默认密码

最后一行 A temporary password 后面跟的就是默认密码。如果没用看到密码,可以跳到后面看解决方法。大概率是初始化失败,请看看 error.log有没有报错信息。

$> cat /usr/local/mysql/data/error.log 

#以下为输出结果
[System] [MY-013169] [Server] /usr/local/mysql/bin/mysqld (mysqld 8.0.30) initializing of server in progress as process 116775

[System] [MY-013576] [InnoDB] InnoDB initialization has started.

[System] [MY-013577] [InnoDB] InnoDB initialization has ended.

[Note] [MY-010454] [Server] A temporary password is generated for root@localhost: qnKSg%d/p3A#

启动前创建一下证书(可选)

#创建 SSL证书和密钥文件,文件在datadir
$> /usr/local/mysql/bin/mysql_ssl_rsa_setup

初始化之后MySQL是没启动的,要重新运行一下 mysqld

#& 表示在后台运行
$> /usr/local/mysql/mysqld &

登录并改密码

恭喜你已经到了这一步了,就快要结束了。

#登录MySQL
$> mysql -uroot -p

#改密码,password换成你自己的密码
mysql> ALTER user 'root'@'localhost' IDENTIFIED BY 'password';

#没什么用,礼貌性刷新一下权限
mysql> FLUSH PRIVILEGES; 

进程守护

mysqld_safe 和 systemd 冲突俩个请不要一起用。

创建systemd进程守护

编辑进程守护(systemd)文件

vim /usr/lib/systemd/system/mysqld.service

[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
User=mysql
Group=mysql

# Have mysqld write its state to the systemd notify socket
Type=notify

# Disable service start and stop timeout logic of systemd for mysqld service.
TimeoutSec=0

# Start main service
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf $MYSQLD_OPTS 

# Use this to switch malloc implementation
#可以指定内存管理程序,debian11没这个目录,可以自行指定目录和文件
#EnvironmentFile=-/etc/sysconfig/mysql

# Sets open_files_limit
LimitNOFILE = 10000

Restart=on-failure

RestartPreventExitStatus=1

# Set environment variable MYSQLD_PARENT_PID. This is required for restart.
Environment=MYSQLD_PARENT_PID=1

PrivateTmp=false

改完以后要重载一下配置

#重载进程守护
$> systemctl daemon-reload

#关闭mysqld进程,以下任选其一

#方式一:用 MySQL 自带的命令
$> mysql -uroot -p -e 'shutdown'

#方式二:暴力关闭(杀进程)
$> pkill mysqld
$> killall -KILL mysql mysqld_safe mysqld

#注:在使用systemctl 启动mysqld 之前,如果mysqld已经启动会导致systemctl卡死,所以要先把mysql退出

systemd 使用扩展

基本命令

#重载进程守护
systemctl daemon-reload

#创建开机启动
systemctl enable mysqld
#禁用开机启动
systemctl disable mysqld

#查看MySQL进程状态
systemctl status mysqld

#重启、启动、停止 
systemctl restart mysqld
systemctl start mysqld
systemctl stop mysqld

MYSQLD_OPTS 系统变量

在不直接修改systemd配置文件的情况下为mysqld指定启动参数。例如:

#设置 mysqld 的启动参数
$> systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"

#清空设置 mysqld 的启动参数
$> systemctl unset-environment MYSQLD_OPTS

注:这里的 MYSQLD_OPTS对应的是 /usr/lib/systemd/system/mysqld.service 文件中 ExecStart 最后面跟的变量名。大概意思设置启动参数。

设置完启动参数重启一下就能生效

$> systemctl restart mysqld

卸载 MySQL

参考一下上文的目录规划

要删除或修改的文件和目录

目录/文件作用
/etc/my.cnfMySQL全局配置文件
/tmp/mysqltmpdir(临时文件目录)
/usr/lib/systemd/system/mysqld.service存放进程守护配置文件
/etc/profile环境变量
/usr/local/mysqlbasedir(MySQL主程序目录)
/usr/local/mysql的子文件夹datadir(数据目录)datadir(数据目录)
同上binary logs(顾名思义,binlog文件目录)
同上备份文件目录
同上socket (socke文件地址,登录用的)
同上log_error(错误日志)
#暴力mysqld进程关闭(杀进程)
$> pkill mysqld
$> killall -KILL mysql mysqld_safe mysqld

#删除配置文件、临时文件、主程序
$> rm -rf /etc/my.cnf
$> rm -rf /tmp/mysql
$> rm -rf /usr/local/mysql

#删除systemd相关配置,并重载 systemd
$> systemctl disable greatsql
$> rm -rf /usr/lib/systemd/system/mysqld.service
$> systemctl daemon-reload

#删除环境变量并刷新
$> vim /etc/profile 
source /etc/profile

FAQ

初始化失败怎么办

如果初始化失败就清一下 相关文件夹,解决问题,然后再重新初始化

删文件夹

$> rm -rf /usr/local/mysql/data/mysql.sock
$> rm -rf /usr/local/mysql/data/datadir/*
$> rm -rf /usr/local/mysql/data/backup/*  
$> rm -rf /usr/local/mysql/data/binlog/*
$> rm -rf /tmp/mysql/*

#报错文件看完再删
$> rm -rf /usr/local/mysql/data/error.log 

通过报错找到问题并解决

如果连报错都没有,可能是没有权限写不了报错文件。或者在my.cnf里报错文件写错位置

$> cat /usr/local/mysql/data/error.log 

解决问题后重新初始化

$> /usr/local/mysql/bin/mysqld --initialize --user=mysql

忘记密码怎么办

思路是:跳过登录验证,把密码删了。 恢复登录验证,无密码登录,改密码

一、关闭 MySQL

#暴力mysqld进程关闭(杀进程)
$> pkill mysqld
$> killall -KILL mysql mysqld_safe mysqld

#使用 systemd 进程管理关闭
$> systemctl mysqld stop

二、跳过登录验证并启动

有俩种方式可以跳过登录验证(任选一种)

1.修改 my.cnf 文件,然后启动数据库

$> vim /etc/my.cnf

#跳过登录验证
[mysqld]
skip-grant-tables

#如果是window客户端还要加上
share-memory

2.在启动的时候指定参数

#使用 systemd 进程管理,参考上文的(MYSQLD_OPTS 系统变量)
$> systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"
$> systemctl mysqld start

#不使用 systemd 直接启动
$> /usr/local/mysql/mysqld --skip-grant-tables &

三、删除密码

#登录数据库
$> mysql -urot

#删除指定用户密码
mysql>UPDATE mysql.user SET authentication_string='' WHERE user = 'root';

#确认一下密码是否是空的
mysql> SELECT host,user,authentication_string FROM mysql.user;

# 刷新保存
mysql> FLUSH privileges;  

四、恢复登录验证

把第二步做的修改恢复一下

#如果前面有改my.cnf ,就改回来,把skip-grant-tables删了
$> vim /etc/my.cnf

#清空设置 mysqld 的启动参数
$> systemctl unset-environment MYSQLD_OPTS

改回来以后重启一下,因为在 skip-grant-tables模式下没办法修改密码

五、修改密码

此时数据库root用户密码已经被删了,无密码登录进去改一下密码就行

$> mysql -uroot
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';

登录不了怎么办

一、MySQL服务没启动导致登录不了:

参考报错:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/usr/local/mysql/data/mysql.sock' (2)

解决方法:启动MySQL服务

#未配置systemd进程守护
/user/local/mysql/bin/mysqld

#已配置下文的进程守护
systemctl start mysqld

二、账号密码host错误 导致登录不了:

参考报错:

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

出现以上报错请检查账号密码,和host设置

MySQL特性:hosts也是属于登录凭证里的,如果hosts不对,报错信息和输错账号密码是一样的。

所以在使用远程工具(如 Navicat )的时候要检测host 。比如说root用户默认的host是'localhost'('root'@'localhost')。如果要进行远程登录要改掉这里的host 。改成 '%'('root'@'%')。这里的'%' 代表所有IP都能登录,虽然方便但是不安全。

三、连接的客户端版本太低

参考报错:

Authentication plugin 'caching_sha2_password' cannot be loaded

出现这个原因是mysql8 之前的版本中登录插件是 mysql_native_password ,而在mysql8之后,默认登录插件是caching_sha2_password,使用的客户端太老不支持 caching_sha2_password

解决方法有两种:一种是升级客户端,另外是把mysql用户登录插件改成 mysql_native_password

以下是修改登录插件的方法,但是我建议是升级一下客户端。

#修改加密规则 
$> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER;   

#更新一下用户的密码
$> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';   

#刷新权限并重置密码
 FLUSH PRIVILEGES; 

参考文章

官方教程:二进制安装MySQL

官方教程:使用 systemd 管理 MySQL
翻译:使用 systemd 管理 MySQL
翻译+搬运:使用 systemd 管理 MySQL

将GreatSQL添加到系统 systemd 服务

官方教程:mysql-ssl-rsa-setup