ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RockyLinux 8离线安装MySQL 8:RPM依赖包与初始化排错全攻略

RockyLinux 8离线安装MySQL 8:RPM依赖包与初始化排错全攻略 一台不能连外网的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这一大堆开发工具也避免了编译参数踩坑相比DockerRPM方案不需要额外维护容器运行时对传统运维栈更友好。1.3 需要提前准备的物料清单离线安装最忌讳“装到一半发现少个包”。我踩过一次这种坑在客户内网装MySQL传到一半rpm报缺perl现场又没有离线仓库差点让整个部署计划延期。所以物料清单必须先理清楚。我这次用到的MySQL 8 RPM包如下mysql-community-servermysql-community-clientmysql-community-commonmysql-community-libsmysql-community-libs-compatmysql-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 -hMySQL 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 mariadb2.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盘拷贝、带外管理口挂载、或者通过堡垒机的文件分发功能。我这次用的是scpscp /root/mysql8_offline/*.rpm root内网IP:/opt/mysql8rpm/传完后务必做完整性校验。rpm包在传输过程中如果损坏虽然不至于完全装不了但会让安装行为变得很诡异比如安装到一半报校验错误或者装完启动时才发现二进制文件有问题。校验方式很简单用md5sum或sha256sum和源文件比对cd /opt/mysql8rpm sha256sum *.rpm比对源机器上同样命令的输出结果一致再继续。这个习惯我强烈建议保留它不仅是离线安装的问题也是任何二进制交付场景的基础素养。3. 离线安装MySQL 8的完整实操步骤3.1 按依赖顺序安装RPM包物料到齐、环境检查做完就可以正式安装了。RPM包之间的安装顺序有讲究不按顺序装会报依赖缺失但按正确顺序装就能顺利通过。推荐安装顺序mysql-community-commonmysql-community-libsmysql-community-clientmysql-community-icu-data-filesmysql-community-libs-compatmysql-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.rpm3.2 初始化MySQL数据目录RPM包安装完成后mysqld命令已经就位但此时数据目录还是空的。MySQL 8不能像5.7以前那样直接 service mysqld start 由脚本自动初始化需要手动执行初始化命令。有两种方式第一种随机临时密码方式mysqld --initialize --usermysql执行完成后临时密码会写到 /var/log/mysqld.log 里。用 grep 查一下grep temporary password /var/log/mysqld.log第二种空密码方式适合内网测试环境mysqld --initialize-insecure --usermysql这样初始化出的root账号没有密码登录后需要立即设置。我在生产环境推荐第一种至少临时密码能保证首次登录前没有人能直接用root空密码进入数据库。初始化过程中有几点容易踩坑。第一执行用户必须是mysql这个用户是rpm包安装时自动创建的。如果你用root执行初始化数据目录的文件属主会变成root后续mysqld启动时以mysql用户运行没有权限访问直接报错。第二数据目录默认在 /var/lib/mysql如果之前残留过文件初始化会被跳过或失败必须确保目录是空的。第三日志目录 /var/log/mysql 或 /var/log 需要有mysql用户的写权限否则初始化过程不会产出日志你也找不到临时密码。初始化完成后可以先根据自己的业务需求调整 /etc/my.cnf。MySQL 8默认配置已经比较合理但有几个参数我是常调的[mysqld] port3306 character-set-serverutf8mb4 collation-serverutf8mb4_general_ci max_connections500 innodb_buffer_pool_size1G default-time-zone8:00innodb_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 doesnt exist”。如果遇到这种情况说明你的实例还没加载该组件需要手动安装INSTALL COMPONENT file://component_validate_password;修改root密码的标准姿势如下ALTER USER rootlocalhost 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] Cant open the mysql.plugin table排查方法很简单ls -ld /var/lib/mysql如果属主不是mysql用户和mysql组就改回去chown -R mysql:mysql /var/lib/mysqlSELinux导致的启动失败也很常见尤其在你移动过数据目录、改了端口、或者自定义了日志路径之后。先看当前SELinux状态getenforce如果返回 Enforcing可以临时关闭验证setenforce 0然后再启动MySQL。如果关闭SELinux后能正常启动说明确实是SELinux上下文的问题。稳妥的解决方案是恢复SELinux上下文而不是直接关掉SELinuxrestorecon -Rv /var/lib/mysql但如果这是内网隔离环境、对安全等级要求没到强制SELinux的程度我个人的处理习惯是直接把SELinux设为disabled因为内网环境的SELinux带来的管理成本远大于它的安全收益。修改 /etc/selinux/config 里的 SELINUXenforcing 改为 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/mysqld4.3 忘记root密码的应急处理生产环境最糟心的问题之一就是忘记了MySQL的root密码。尤其在离线内网环境没有外部工具可以介入只能本机处理。MySQL 8的密码重置思路是先跳过授权表启动服务再更新root账号。具体步骤先在my.cnf里加一行基础配置或者直接用--skip-grant-tables参数手动启动mysqld --skip-grant-tables --usermysql 注意MySQL 8的skip-grant-tables模式有个限制你进入MySQL后不能直接用ALTER USER修改密码因为该模式下权限加载不完全。需要先让授权表在内存中重新生效FLUSH PRIVILEGES;然后再执行密码修改ALTER USER rootlocalhost IDENTIFIED BY 新密码; FLUSH PRIVILEGES;改完密码后退出MySQL把后台启动的mysqld进程杀掉再用 systemctl start mysqld 正常启动。这个流程我在MySQL 8.0.36上验证过可行。另一种办法是用 --init-file 指定一个包含SQL语句的文件启动时自动执行。这个方式更优雅适合在服务能正常登录但密码丢失的场景下使用。先写一个sql文件echo ALTER USER rootlocalhost IDENTIFIED BY 新密码; /tmp/reset_pwd.sql然后以init-file启动mysqld --init-file/tmp/reset_pwd.sql --usermysql 启动完成后删除该文件防止SQL语句里的密码留在磁盘上。4.4 远程登录连不上的排查路径MySQL能启动数据也能写入但业务服务器连数据库时提示无法连接。这种问题通常不是MySQL本身故障而是网络链路上的配置问题。按顺序排查第一步确认MySQL服务监听地址ss -lntp | grep 3306看到 0.0.0.0:3306 说明监听所有网卡如果看到 127.0.0.1:3306说明server配置了 bind-address127.0.0.1外部无法连接改回 0.0.0.0 后重启服务。第二步确认防火墙放行3306端口firewall-cmd --permanent --add-port3306/tcp firewall-cmd --reload firewall-cmd --list-ports内网环境有时候会有多道防火墙应用防火墙、宿主防火墙、云安全组每一层都要检查。我遇到过最匪夷所思的情况是系统firewalld没开、云安全组也放行了最后发现是交换机ACL挡了端口这种只能在现场根据网络拓扑一层层排查没有捷径。第三步确认账号host范围。如果你创建账号时用的是 appuserlocalhost那业务服务器肯定连不上。改用 % 或者指定业务服务器的IP网段CREATE USER appuser192.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状态、已有包冲突、数据目录残留。宁可在前期把这些检查做足、做细也不要等安装报错后救火。版本锁定、物料清单、日志路径这几样东西心中有数离线部署就能从“老运维才能干”变成“照着清单就能复现”的标准化流程。
返回列表