☰
RockyLinux 8离线安装MySQL 8:RPM依赖包与初始化排错全攻略
2026/10/3 14:36:47 网站建设 项目流程

一台不能连外网的RockyLinux 8服务器,要装MySQL 8。很多刚接触服务器运维的朋友,第一次遇到这种“离线环境”都会懵:yum装不了,源码编译缺工具链,想找离线安装包又不知道从哪里下手。我前阵子刚好在物理隔离的内网环境里部署了一套MySQL 8,从依赖包准备到初始化完成,踩了一路坑,也沉淀了一套可以“照抄”的流程。这篇文章就把整个过程完整记录下来,覆盖mysql8离线安装的核心要点、依赖包准备方法、RPM安装顺序、初始化配置、常见报错排查,希望能帮到同样被离线环境折腾的人。

1. 离线安装的整体思路与方案选型

1.1 什么场景下会用到离线安装

先聊清楚“离线”到底指什么。它不是指你本地电脑没网,而是指目标服务器处于内网隔离环境,访问不了外网yum仓库,甚至整个网段默认就不通外部DNS。常见的场景有这几种:

  • 生产内网有安全要求,服务器不允许连接公网,安装软件只能靠离线包。
  • 等保合规或项目交付时,需要把整套软件版本固定下来,不允许线上yum随意升级。
  • 批量交付多台同配置服务器,离线包可以一次准备好,在每台机器上重复执行,版本完全一致。

在这类场景下,直接用 yum install mysql-server 基本是行不通的。即使你的机器能访问外网,也不建议在生产环境直接yum安装,因为你无法控制它装出来的版本和依赖,一旦后续需要迁移、重建环境,版本漂移会让你非常痛苦。

1.2 三种离线安装方案,我为什么选了RPM

离线装MySQL 8,业内比较常见的路子有三条:RPM离线包安装、Docker离线镜像安装、源码编译安装。三条路我都在实际环境里试过,先做个直观对比:

方案安装速度依赖处理适合场景坑点
RPM离线包快,10分钟内完成需提前备齐依赖包常规生产环境首选依赖遗漏时会装到一半卡住
Docker镜像快,镜像加载即可无需额外依赖已经用了容器体系的团队需要额外维护容器网络、数据卷
源码编译慢,编译耗时长需要完整工具链需要定制编译参数的特殊场景对新手极不友好,后期升级麻烦

我个人强烈推荐RPM方案。理由很直接:RockyLinux 8和RHEL 8同源,官方yum仓库里就提供MySQL 8的RPM包,这些包针对系统做了适配,安装后的服务管理、日志路径、环境配置都是标准化的。相比源码编译,RPM方案省掉了gcc、make、cmake这一大堆开发工具,也避免了编译参数踩坑;相比Docker,RPM方案不需要额外维护容器运行时,对传统运维栈更友好。

1.3 需要提前准备的物料清单

离线安装最忌讳“装到一半发现少个包”。我踩过一次这种坑,在客户内网装MySQL,传到一半rpm报缺perl,现场又没有离线仓库,差点让整个部署计划延期。所以物料清单必须先理清楚。

我这次用到的MySQL 8 RPM包如下:

  • mysql-community-server
  • mysql-community-client
  • mysql-community-common
  • mysql-community-libs
  • mysql-community-libs-compat
  • mysql-community-icu-data-files

其中 mysql-community-icu-data-files 是很多新手容易忽略的包,它提供ICU字符集数据,MySQL 8的utf8mb4排序规则依赖它,漏装会导致启动时直接报错。

除了MySQL自身的包,还要准备一些系统依赖:libaio、perl、net-tools、ncurses-libs。这些依赖通常会被MySQL 8的RPM包自动检查,如果系统里原本没有,rpm安装就会报依赖缺失。最稳妥的做法是:在一台能联网的RockyLinux 8机器上用 yum install --downloadonly 把这些依赖连同MySQL包一起下载下来,再传到目标机器上。这样版本匹配度最高,也最不容易出幺蛾子。

2. 安装前的环境检查与物料准备

2.1 系统环境确认

拿到一台干净的RockyLinux 8服务器,别急着传包,先把系统信息确认一遍。这一步看起来简单,但能避免很多后面才发现的问题。

先看系统和架构:

cat /etc/os-release uname -m

确保目标机器是RockyLinux 8.x版本,架构是x86_64。虽然MySQL 8的RPM也提供aarch64版本,但x86_64下的包最全,遇到问题也最好排查。

再看内存和磁盘:

free -h df -h

MySQL 8运行起来后占用内存不少,尤其是InnoDB缓冲池。建议内存至少2GB,数据盘剩余空间至少10GB。我这里有一台4GB内存的测试机,默认配置下运行MySQL 8完全没问题;如果你机器内存只有1GB,后面my.cnf里就得把 innodb_buffer_pool_size 调小,否则启动后会面临OOM风险。

接着检查repo状态。目标机器上可能残留了系统自带的repo文件,如果服务器完全离线,这些repo其实没有意义,但有些repo会在执行 yum 命令时报错或者卡在超时上。建议把 /etc/yum.repos.d/ 目录下的非必要repo文件统一备份后移走:

mkdir -p /root/repo_backup mv /etc/yum.repos.d/*.repo /root/repo_backup/

同时还要确认AppStream模块的默认状态。RockyLinux 8自带的mysql模块可能是8.0版本,也可能是mariadb版本。如果不关心,可以不管它;但如果你后面想用 yum localinstall 来装rpm包,模块冲突会直接导致安装中止。处理方式很简单,把默认模块禁用掉:

dnf module disable -y mysql dnf module disable -y mariadb

2.2 处理系统自带的MariaDB和残留文件

RockyLinux 8默认自带的是MariaDB,而不是MySQL。这两个数据库虽然名字相近,但文件目录、服务管理方式有差别。如果直接用rpm安装MySQL 8,很可能会和系统自带的MariaDB-libs冲突。

先检查系统里是否已经有相关包:

rpm -qa | grep -iE 'mysql|mariadb'

如果查出 mariadb-libs 之类的包,不要犹豫,先备份配置再卸载。数据库里的数据如果有用,一定要先备份到安全位置。我在实践中见过不少同事,卸载前不备份,事后发现系统根目录下还有旧库文件,悔之晚矣。

卸载命令:

rpm -e --nodeps mariadb-libs

加 --nodeps 是因为系统中其他组件可能对这个库有依赖,直接正常卸载会报错。这种操作有风险吗?有。但对于刚装好的系统,MariaDB通常没有实际业务使用,风险可控。如果服务器上已经跑了MariaDB服务并且有业务在写,那就必须先停服务、备份数据,再走迁移流程,不能直接卸载。

卸载完后,检查 /var/lib/mysql 目录是否存在。如果存在且是空的,直接清掉;如果里面有旧数据文件,先重命名备份:

mv /var/lib/mysql /var/lib/mysql_backup

这一步很关键。MySQL初始化时如果发现数据目录里已有文件,会直接跳过初始化,导致你后续找不到临时密码,服务也无法启动。

2.3 在联网机器上准备离线安装包

这是整个离线安装里最考验“情报收集能力”的环节。准备安装包有两条路子,我建议两条都走一遍,互相补充。

第一条路子:从镜像站直接下载RPM包。国内常用的清华TUNA镜像、阿里云开源镜像站都收录了MySQL官方仓库。以清华镜像为例,在浏览器里访问镜像站上的MySQL yum仓库路径,找到 el8 目录,文件列表里就能看到 mysql-community-server-8.0.x.x86_64.rpm 等包。用 wget 逐个下载:

wget https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-8.0-el8/x86_64/mysql-community-server-8.0.36-1.el8.x86_64.rpm

第二条路子:用 yum install --downloadonly 把MySQL包和依赖包一次拉全。在一台能联网、系统版本和目标机器一致的机器上执行:

dnf install --downloadonly --downloaddir=/root/mysql8_offline mysql-community-server

这条命令会把 mysql-community-server 以及它依赖的所有软件包全部下载到指定目录。注意:执行这条命令之前,需要先安装MySQL官方yum仓库:

dnf install https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm

或者手动把官方repo文件放到 /etc/yum.repos.d/ 下。下载完成后,把整个 /root/mysql8_offline 目录打包带走,里面既包括MySQL自己的RPM包,也包括perl、ncurses等系统依赖。

我提倡两条路子都准备,是因为镜像站下载适合精确控制版本,而 --downloadonly 适合保证依赖完整。两者结合,基本可以覆盖所有场景。

2.4 上传文件与校验完整性

离线包准备好了,接下来就是传到目标机器。传输方式取决于现场条件,常见的有:scp/rsync走内网、U盘拷贝、带外管理口挂载、或者通过堡垒机的文件分发功能。

我这次用的是scp:

scp /root/mysql8_offline/*.rpm root@内网IP:/opt/mysql8rpm/

传完后,务必做完整性校验。rpm包在传输过程中如果损坏,虽然不至于完全装不了,但会让安装行为变得很诡异,比如安装到一半报校验错误,或者装完启动时才发现二进制文件有问题。校验方式很简单,用md5sum或sha256sum和源文件比对:

cd /opt/mysql8rpm sha256sum *.rpm

比对源机器上同样命令的输出结果,一致再继续。这个习惯我强烈建议保留,它不仅是离线安装的问题,也是任何二进制交付场景的基础素养。

3. 离线安装MySQL 8的完整实操步骤

3.1 按依赖顺序安装RPM包

物料到齐、环境检查做完,就可以正式安装了。RPM包之间的安装顺序有讲究,不按顺序装会报依赖缺失,但按正确顺序装就能顺利通过。

推荐安装顺序:

  1. mysql-community-common
  2. mysql-community-libs
  3. mysql-community-client
  4. mysql-community-icu-data-files
  5. mysql-community-libs-compat
  6. mysql-community-server

实际命令行如下:

cd /opt/mysql8rpm rpm -ivh mysql-community-common-8.0.36-1.el8.x86_64.rpm rpm -ivh mysql-community-libs-8.0.36-1.el8.x86_64.rpm rpm -ivh mysql-community-client-8.0.36-1.el8.x86_64.rpm rpm -ivh mysql-community-icu-data-files-8.0.36-1.el8.x86_64.rpm rpm -ivh mysql-community-libs-compat-8.0.36-1.el8.x86_64.rpm rpm -ivh mysql-community-server-8.0.36-1.el8.x86_64.rpm

如果安装过程中报缺失perl或其他系统依赖,用你之前下载的依赖RPM包手动装上,再回来继续:

rpm -ivh perl-*.rpm ncurses-libs-*.rpm libaio-*.rpm

有一个更省事的替代方案:用 yum localinstall 安装本地rpm目录,它会自动解析目录内可行的依赖关系,还需要联网做额外的仓库解析时会失败,但目录内的包能自动处理。命令如下:

dnf localinstall ./mysql-community-*.rpm

我这里还是建议逐个 rpm -ivh 安装。原因很简单:逐个装,每步的成功失败你都能明确知道,排查时定位更快。而 localinstall 一旦中途报错,它究竟解析到哪一步、缺了什么,有时看输出都费劲。

另外,如果在生产环境里之前装过MySQL的老版本,rpm安装时可能会报文件冲突。比如 /etc/my.cnf 已存在,rpm默认不会覆盖,会报“conflicts with file”错误。处理方式是把旧配置文件备份改名,再重新执行安装命令:

mv /etc/my.cnf /etc/my.cnf.bak rpm -ivh mysql-community-server-8.0.36-1.el8.x86_64.rpm

3.2 初始化MySQL数据目录

RPM包安装完成后,mysqld命令已经就位,但此时数据目录还是空的。MySQL 8不能像5.7以前那样直接 service mysqld start 由脚本自动初始化,需要手动执行初始化命令。有两种方式:

第一种,随机临时密码方式:

mysqld --initialize --user=mysql

执行完成后,临时密码会写到 /var/log/mysqld.log 里。用 grep 查一下:

grep 'temporary password' /var/log/mysqld.log

第二种,空密码方式,适合内网测试环境:

mysqld --initialize-insecure --user=mysql

这样初始化出的root账号没有密码,登录后需要立即设置。我在生产环境推荐第一种,至少临时密码能保证首次登录前没有人能直接用root空密码进入数据库。

初始化过程中有几点容易踩坑。第一,执行用户必须是mysql,这个用户是rpm包安装时自动创建的。如果你用root执行初始化,数据目录的文件属主会变成root,后续mysqld启动时以mysql用户运行,没有权限访问,直接报错。第二,数据目录默认在 /var/lib/mysql,如果之前残留过文件,初始化会被跳过或失败,必须确保目录是空的。第三,日志目录 /var/log/mysql 或 /var/log 需要有mysql用户的写权限,否则初始化过程不会产出日志,你也找不到临时密码。

初始化完成后,可以先根据自己的业务需求调整 /etc/my.cnf。MySQL 8默认配置已经比较合理,但有几个参数我是常调的:

[mysqld] port=3306 character-set-server=utf8mb4 collation-server=utf8mb4_general_ci max_connections=500 innodb_buffer_pool_size=1G default-time-zone='+8:00'

innodb_buffer_pool_size的设定需要注意:经验值是物理内存的50%到70%,但别超过实际可用内存。机器内存2GB时,我通常设为512M;内存4GB时设1G;内存8GB以上再考虑更大的值。这个参数直接影响MySQL的读写性能,设太大容易触发OOM,设太小则索引和数据频繁刷盘,查询会明显变慢。

3.3 启动服务并配置开机自启

初始化完成后,就可以启动服务了:

systemctl start mysqld

启动后先确认状态,再确认进程和端口:

systemctl status mysqld ss -lntp | grep 3306

如果服务没有正常起来,第一时间看日志,MySQL 8的默认日志路径有两个:

tail -100 /var/log/mysqld.log tail -100 /var/log/mysql/mysqld.log

启动成功后,顺手配置开机自启:

systemctl enable mysqld

这样每次服务器重启后,MySQL服务会自动拉起,不需要人工干预。这一步看着不起眼,但运维工作中经常有人忘记,服务器一重启数据库不在了,业务报警才发现问题。

如果要修改数据目录位置,需要做更复杂的处理:新建目录、复制文件、调整权限,并在my.cnf里指定 datadir,同时还要处理SELinux上下文。这个操作不建议在离线部署中做,因为一旦SELinux上下文没配置好,MySQL反复启动失败,排查起来比较费时间。默认的 /var/lib/mysql 在根分区上,生产环境可以把数据盘挂载到 /var/lib/mysql 或者用软链接方式调整,总之数据目录单独挂载到数据盘更稳妥。

3.4 修改root密码与创建业务账号

服务启动后,接下来就是首次登录和密码设置。如果你用的是临时密码方式,先登录:

mysql -uroot -p

输入临时密码进入MySQL命令行。MySQL 8默认安装了密码校验插件validate_password,所以设置密码时不能太简单。先看一下当前密码策略:

SHOW VARIABLES LIKE 'validate_password%';

默认策略要求密码至少8位,包含大小写字母、数字和特殊字符。如果这是生产库,建议保持默认强度;如果只是内网测试环境,想简化密码,可以临时调低策略:

SET GLOBAL validate_password.policy = LOW; SET GLOBAL validate_password.length = 6;

但注意,这两个设置只对当前实例生效,重启后恢复默认。要持久化,需要把对应的配置项写进my.cnf的[mysqld]段。

有部分版本的validate_password组件还需要在配置文件里显式声明,否则修改全局变量时报“Variable 'validate_password.policy' doesn't exist”。如果遇到这种情况,说明你的实例还没加载该组件,需要手动安装:

INSTALL COMPONENT 'file://component_validate_password';

修改root密码的标准姿势如下:

ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码'; FLUSH PRIVILEGES;

密码设置完成后,再为业务单独创建一个账号,避免业务代码直接用root连库。这是最基本的权限隔离概念:

CREATE USER 'appuser'@'%' IDENTIFIED BY '业务密码'; GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'%'; FLUSH PRIVILEGES;

这里 'appuser'@'%' 表示允许任意主机通过该账号连接数据库,适合业务服务器和数据库服务器分离的场景。如果业务代码只和数据库在同一台机器上,建议把 '%' 改成 'localhost',安全面会小很多。远程登录时还需要注意,MySQL 8默认的 bind-address 是 0.0.0.0,也就是监听所有网卡,不用额外改;但如果你在my.cnf里把 bind-address 设成了 127.0.0.1,远程连接一定会失败,这个参数需要提前确认。

4. 常见问题与排查技巧实录

4.1 依赖缺失类报错

离线安装MySQL,碰到最多的报错就是rpm安装时提示 Failed dependencies。典型的输出长这样:

error: Failed dependencies: libaio.so.1()(64bit) is needed by mysql-community-server-8.0.36-1.el8.x86_64

这个问题的根源在准备工作做得不够。如果你严格按照2.3节用 yum install --downloadonly 拉取了依赖包,这种报错基本不会出现。但万一目标机器上还有其他软件包缺失,rpm会明确告诉你缺什么,你只要去离线包里找到对应的rpm文件装上即可。

优先排查顺序:

rpm -qa | grep libaio rpm -qa | grep perl rpm -qa | grep ncurses

缺哪个装哪个。如果下载的依赖包里没有对应文件,就得想其他办法,比如换一台联网的同版本机器重新执行 --downloadonly,或者直接从官网下载对应依赖包。

有没有必要用 --nodeps 强制安装?我的建议是:不到万不得已,不要用。--nodeps 会让rpm跳过依赖检查,包本身能装上,但缺失的系统库会导致mysqld启动时直接报错,比如找不到libaio.so.1,这种错误比安装时缺依赖更难排查。宁可多花十分钟把依赖备齐,也别让服务起不来再返工。

关于如何判断一个rpm包依赖哪些库,可以用这个命令提前检查:

rpm -qpR mysql-community-server-8.0.36-1.el8.x86_64.rpm

它会列出这个包所有依赖的库和rpm包名,拿到这个清单,对照系统里已有的包,就能提前发现缺什么。这个技巧在离线安装中非常实用。

4.2 初始化或启动失败的典型原因

MySQL 8启动失败,90%的原因集中在三个地方:数据目录权限、SELinux、日志目录问题。

数据目录权限问题最常见的表象是:

[ERROR] failed to set datadir to /var/lib/mysql [ERROR] Can't open the mysql.plugin table

排查方法很简单:

ls -ld /var/lib/mysql

如果属主不是mysql用户和mysql组,就改回去:

chown -R mysql:mysql /var/lib/mysql

SELinux导致的启动失败也很常见,尤其在你移动过数据目录、改了端口、或者自定义了日志路径之后。先看当前SELinux状态:

getenforce

如果返回 Enforcing,可以临时关闭验证:

setenforce 0

然后再启动MySQL。如果关闭SELinux后能正常启动,说明确实是SELinux上下文的问题。稳妥的解决方案是恢复SELinux上下文,而不是直接关掉SELinux:

restorecon -Rv /var/lib/mysql

但如果这是内网隔离环境、对安全等级要求没到强制SELinux的程度,我个人的处理习惯是直接把SELinux设为disabled,因为内网环境的SELinux带来的管理成本远大于它的安全收益。修改 /etc/selinux/config 里的 SELINUX=enforcing 改为 disabled,重启后生效。需要注意,setenforce 0 只对当前运行态生效,重启后会恢复成Enforcing,一定要把配置文件和运行态一起处理。

还有一个细节:MySQL 8的socket文件默认在 /var/lib/mysql/mysql.sock,运行时的pid文件在 /var/run/mysqld/ 目录。如果 /var/run/mysqld 目录不存在或权限不对,mysqld无法创建pid文件,启动也会失败。手动创建并授权:

mkdir -p /var/run/mysqld chown mysql:mysql /var/run/mysqld

4.3 忘记root密码的应急处理

生产环境最糟心的问题之一就是忘记了MySQL的root密码。尤其在离线内网环境,没有外部工具可以介入,只能本机处理。MySQL 8的密码重置思路是:先跳过授权表启动服务,再更新root账号。

具体步骤:

先在my.cnf里加一行基础配置,或者直接用--skip-grant-tables参数手动启动:

mysqld --skip-grant-tables --user=mysql &

注意,MySQL 8的skip-grant-tables模式有个限制:你进入MySQL后不能直接用ALTER USER修改密码,因为该模式下权限加载不完全。需要先让授权表在内存中重新生效:

FLUSH PRIVILEGES;

然后再执行密码修改:

ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码'; FLUSH PRIVILEGES;

改完密码后,退出MySQL,把后台启动的mysqld进程杀掉,再用 systemctl start mysqld 正常启动。这个流程我在MySQL 8.0.36上验证过,可行。

另一种办法是用 --init-file 指定一个包含SQL语句的文件,启动时自动执行。这个方式更优雅,适合在服务能正常登录但密码丢失的场景下使用。先写一个sql文件:

echo "ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';" > /tmp/reset_pwd.sql

然后以init-file启动:

mysqld --init-file=/tmp/reset_pwd.sql --user=mysql &

启动完成后删除该文件,防止SQL语句里的密码留在磁盘上。

4.4 远程登录连不上的排查路径

MySQL能启动,数据也能写入,但业务服务器连数据库时提示无法连接。这种问题通常不是MySQL本身故障,而是网络链路上的配置问题。

按顺序排查:

第一步,确认MySQL服务监听地址:

ss -lntp | grep 3306

看到 0.0.0.0:3306 说明监听所有网卡;如果看到 127.0.0.1:3306,说明server配置了 bind-address=127.0.0.1,外部无法连接,改回 0.0.0.0 后重启服务。

第二步,确认防火墙放行3306端口:

firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload firewall-cmd --list-ports

内网环境有时候会有多道防火墙,应用防火墙、宿主防火墙、云安全组,每一层都要检查。我遇到过最匪夷所思的情况是:系统firewalld没开、云安全组也放行了,最后发现是交换机ACL挡了端口,这种只能在现场根据网络拓扑一层层排查,没有捷径。

第三步,确认账号host范围。如果你创建账号时用的是 'appuser'@'localhost',那业务服务器肯定连不上。改用 '%' 或者指定业务服务器的IP网段:

CREATE USER 'appuser'@'192.168.%' IDENTIFIED BY '密码';

然后授权并刷新。这个操作可以在MySQL运行时直接调整,不需要重启。

第四步,注意网络时延和TCP连接超时。内网环境通常没有问题,但如果业务服务器和数据库隔着多跳网络,连接超时也会表现为“无法连接”,需要用 ping、telnet 等工具通断检测后再判断。

4.5 一些让你少走弯路的经验

最后补几条纯粹来自现场的经验,不写进常规文档但非常有用:

  • RPM包版本号和镜像站不一致时,优先选择镜像站能下到的版本。宁可版本旧一个patch,也不要手忙脚乱去官网找旧包,因为官网的仓库通常只保留最新版本。
  • 离线安装前,先把 /etc/my.cnf 备份一份。RPM安装和后续修复过程中很有可能会被覆盖或者被修改,备份能让你快速回溯。
  • 使用 systemctl start mysqld 前,先确认 /var/lib/mysql 目录的属主。这一步常被人忽略,但重要性我前面已经强调过。
  • 建议把离线包整理成固定的“软件交付目录”:包含RPM目录、依赖目录、README文件(写明安装顺序和已知问题)。团队里多人操作时,这个习惯能省去大量重复沟通成本。
  • 所有rpm包安装完成后,用 mysql --version 确认客户端版本和服务端版本一致。版本不一致也会引起连接时的鉴权兼容问题,这在RHEL8系系统上时有发生。

离线安装MySQL 8这件事,只要物料准备齐全、顺序不搞错,成功率其实很高。我个人在实际操作中的体会是:最难的不是命令本身,而是那些看不见的前提条件——SELinux状态、已有包冲突、数据目录残留。宁可在前期把这些检查做足、做细,也不要等安装报错后救火。版本锁定、物料清单、日志路径,这几样东西心中有数,离线部署就能从“老运维才能干”变成“照着清单就能复现”的标准化流程。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询