ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RockyLinux 8 离线安装 MySQL 8 完整指南:RPM 抓包与排障实践

RockyLinux 8 离线安装 MySQL 8 完整指南:RPM 抓包与排障实践 前几天在封闭内网帮客户部署一套业务系统目标机是 RockyLinux8机房完全隔离外网yum install直接报Could not resolve host。要装 mysql8整个离线安装过程比预想中曲折依赖包没抓全、临时密码找不到、SELinux 拦自定义数据目录前前后后折腾了小半天。后来整理成一套固定流程再遇到类似环境基本半小时搞定。这篇就把它完整写出来给需要在 RockyLinux8 上做 mysql8 离线安装的运维朋友当个参考。适合谁看被隔离内网困住、只能靠 U 盘或跳板机往服务器拷文件的人不想在目标机上折腾源码编译、想走 RPM 方案的人以及想搞清楚离线装 MySQL 8 有哪些隐藏依赖、哪些坑必须先避开的人。1. 先想清楚离线装 MySQL 8 到底该用哪条路很多人一上来就问离线安装用什么命令其实最该先定的是路线。路线选错后面每一步都在补坑。我在 RockyLinux8 上试过的离线方案大概有三类内网 yum 镜像源、官方 RPM 包本地安装、源码编译或容器镜像导入。三者的适用场景差别很大选之前必须搞清楚自己手里的条件。1.1 内网 Yum 镜像源最省心的离线方案如果你的单位有自己的 yum 仓库镜像比如用 nginx 搭了一个内网 RockyLinux8 的 BaseOS 和 AppStream 源或者运维已经同步了一套本地仓库那么离线安装的难度会骤降。这种模式下目标机能访问内网源地址只是不能访问公网。此时只需要把源配置改成本地镜像然后正常执行dnf install -y mysql-serverRockyLinux8 的 AppStream 模块里内置了 MySQL 8.0 模块流dnf install mysql-server装的就是 MySQL 8.0 系列。好处是依赖完全由内网源解决RPM 也都齐了安装后 systemd 服务、mysql客户端命令一应俱全。但我必须提醒一句这个方案的瓶颈不在安装过程而在内网源里有没有 MySQL 模块。很多单位只同步了 BaseOS没同步 AppStream或者 AppStream 同步策略把 mysql 模块裁掉了。所以执行dnf module list mysql前最好确认一下源里到底有没有货。1.2 官方 RPM 包本地收录通用性最强的部署姿势如果内网没有源或者源不完整那就要走在联网机器上下载 RPM 包拷贝到目标机安装的路线。这也是本文接下来重点讲的方案。这条路线的好处很明显包来源是 MySQL 官方 yum 仓库版本可控补丁可控。RPM 安装自带 systemd unit 文件、配置文件模板、目录权限设置省去很多手工操作。依赖关系虽然存在但只要用对工具yumdownloader --resolve一次性抓齐离线安装时基本不会卡壳。缺点只有一个你得有一台能访问 MySQL 官方仓库的临时机器通常在办公网络里就能完成不需要机房权限。1.3 源码编译与容器方案为什么放到最后源码编译在离线环境下是最不推荐的。MySQL 8 源码编译依赖 boost、cmake、gcc-c、openssl-devel 等一大批开发包光收集编译依赖就要花大量时间而且每台机器环境有差异编译参数稍有问题就得返工。除非业务要求必须自己定制编译选项否则不要选它。容器方案比如docker load导入 mysql 镜像在一些团队里很流行但它要求目标机提前装好 docker且离线环境下的镜像文件动辄几百 MB导入后还要处理容器数据卷、端口映射、宿主机目录权限。加上容器内跑 MySQL 的 IO 性能损耗和运维排障复杂度在很多政企内网里并不被接受。所以我也把它排在最后。这里给一个选型判断表方便你对着自己的环境直接拍板环境条件推荐路线理由内网有完整 yum 源含 AppStream/mysql 模块dnf 直接装依赖自动解决运维成本最低内网无源但能从办公网拷贝文件官方 RPM 离线包依赖可控升级方便通用性强有 docker 基础且接受容器化docker load 镜像快速但排障成本和 IO 损耗偏高只有源码包且必须定制编译源码编译非必要不建议依赖收集成本极高2. 在联网机器上一次性抓齐所有 RPM 包离线安装最核心的环节不是在目标机上敲命令而是提前把 RPM 包准备完整。这里我踩过一次非常典型的坑只下载了 mysql-community-server 一个包就拿到现场结果yum localinstall报缺七八个依赖现场又没有外网只能干等。所以抓包这一步必须按完整流程来。2.1 环境对齐源机器和目标机版本别出现偏差先在联网机器上确认系统版本cat /etc/redhat-release如果联网机器是 RockyLinux8目标机也是 RockyLinux8那 RPM 架构可以直接用。这里有个容易忽略的点MySQL 官方仓库的 el8 包不能用在 el9 上反之亦然。你在下载仓库配置文件时要选带el8标识的yum install -y https://dev.mysql.com/get/mysql80-community-release-el8-7.noarch.rpm这个包的版本号会变但核心是el8这个词。注意仓库安装过程本身也需要网络所以它应该在联网机器上完成。安装完仓库后可以用yum repolist确认 mysql80-community 仓库已经启用。2.2 用 repoquery 先摸清依赖长什么样在下载之前先看看要装哪些包、它们依赖哪些东西yum install -y yum-utils repoquery --requires mysql-community-serverrepoquery的输出可能会很长因为会递归列出依赖库、perl 模块、openssl 等。这里不用太担心后面用--resolve会自动把依赖都拉下来。但是建议你关注几个关键依赖因为它们在后面的离线排障中经常出现libaionumactl-libsperl通常是 perl-interpreter 或 perl 相关模块openssl相关库ncurses相关库这些包在目标机上如果没有内网源都必须从联网机器一并下载。2.3 yumdownloader 批量下载与打包核对安装好 yum-utils 后用yumdownloader抓包。注意加--resolve它会把所有被依赖的包一起下载到指定目录mkdir -p /root/mysql8-offline cd /root/mysql8-offline yumdownloader --enablerepomysql80-community --resolve \ mysql-community-server \ mysql-community-client \ mysql-community-common \ mysql-community-libs \ mysql-community-libs-compat说下为什么要这五个包一个都不能少mysql-community-server服务端本体mysqld 就在这里。mysql-community-clientmysql命令行客户端安装后你才能连进数据库执行 SQL。mysql-community-common公共文件很多其他包都依赖它。mysql-community-libs核心客户端库文件如果只装 server某些工具连库都找不到。mysql-community-libs-compat兼容包避免与系统自带的mariadb-libs产生文件冲突。这个包在 RockyLinux8 上尤其重要因为系统默认预装了 mariadb-libs如果不带 compat 包rpm 安装时会因为文件冲突直接失败。yumdownloader执行完之后目录下应该多出一批 RPM。除了上面五个主包还会有一批依赖包比如libaio、numactl-libs、openssl等。可以用下面命令统计数量ls -l /root/mysql8-offline/*.rpm | wc -l我碰到过一次比较少见的情况yumdownloader --resolve把 perl 的很多模块也拉了下来数量多达五六十个。这些包整体会比 mysql 主包还占空间但不要轻易删因为mysql_secure_installation脚本依赖 perl缺了 perl 模块你会卡在初始化脚本那一步。2.4 传包前的一分钟检查清单包抓完之后不要直接打包走人。过一遍检查清单确认 RPM 架构是x86_64或 aarch64不是i686。确认源机器和目标机的glibc大版本兼容。确认目录下非空且主包 version 一致比如都来自 8.0.x 系列。打包时保留目录结构方便目标机直接用yum localinstall ./*.rpm。打包命令不复杂tar czf mysql8-offline.tar.gz /root/mysql8-offline传输方式看现场条件U 盘、scp、跳板机都可以。这里只说一点tar 包传过去之后先解压不要在压缩状态下直接安装。3. 目标机离线安装与首次启动排障包已经到了目标机接下来的操作顺序很重要先装依赖再启动服务最后做初始化配置。顺序反了排查成本会很高。3.1 从 yum localinstall 说起为什么不用 rpm -ivh 硬拼把 RPM 包目录放到目标机后最简单的方式是cd /root/mysql8-offline yum localinstall -y ./*.rpmyum localinstall会扫描当前目录下所有 rpm自动解决本地包之间的依赖关系。比rpm -ivh一个包一个包地按顺序敲要省心得多。可能有人问如果目标机内网源不完整yum localinstall会不会跑去联网找依赖不会只要你的本地 rpm 目录里都有yum 会优先用本地包满足依赖。只有缺包时它才会尝试从已配置的 repo 里找如果 repo 不可达它会明确报缺哪个依赖。如果报缺某个依赖先检查是不是 rpm 目录里没抓全。处理办法是回联网机器上补下载一次再拷过来。现场临时手段也可以搜一下本机有没有相关包rpm -qa | grep libaio3.2 数据目录与初始化方式的选择RPM 安装完成后默认数据目录是/var/lib/mysql。如果只是测试环境这个目录直接能用不用改。但生产环境我建议在初始化前就规划好独立数据盘比如/data/mysql避免和系统盘挤在一起。初始化数据库实例有两种方式# 方式一生成随机临时密码 mysqld --initialize --usermysql # 方式二生成空密码的 root 账户适合首次进入后自定义密码 mysqld --initialize-insecure --usermysql我个人的经验是第一次部署用--initialize-insecure更顺滑。因为它不会生成随机密码你直接mysql -uroot就能进去再ALTER USER改密码就好。相比之下--initialize的随机密码存在日志里如果日志轮转或者你记错了路径很容易找不到折腾半天。需要说明的是官方 RPM 在部分环境下首次systemctl start mysqld会自动初始化也就是说你可能不需要手动执行mysqld --initialize。但如果日志里没有生成临时密码或者服务启动失败那就手动执行上面任意一条初始化命令。初始化命令执行时要求--usermysql否则 mysqld 会用 root 身份创建数据文件后面 systemd 以 mysql 身份启动时就没有权限。3.3 启动服务、找回临时密码并重置 root 口令初始化完成后启动服务并设置开机自启systemctl enable --now mysqld systemctl status mysqld --no-pager如果服务已经起来了接下来就是进 MySQL 设置 root 密码。使用空密码初始化的直接执行mysql -uroot如果走的是随机密码路线在日志里找grep temporary password /var/log/mysqld.log找到后用mysql -uroot -p登录然后立刻改密码ALTER USER rootlocalhost IDENTIFIED BY NewPassword_123; FLUSH PRIVILEGES;注意MySQL 8 默认启用了validate_password组件密码如果太简单会报ERROR 1819。生产环境我建议保留强密码策略但如果确实需要弱密码可以临时调低校验等级再改SET GLOBAL validate_password.policy LOW;这行命令只在当前会话生效要永久生效需要写进配置文件后面章节会给出模板。3.4 systemd 开机自启与防火墙开放安装产生的 systemd 服务名是mysqld不是mysql也不叫mysql-server。这点容易记混写脚本的人尤其要注意。确认自启systemctl is-enabled mysqld如果需要从其他机器访问这台数据库放行防火墙firewall-cmd --permanent --add-servicemysql firewall-cmd --reload如果不打算开防火墙只想本地访问这步可以跳过。4. 让实例贴合生产习惯的 my.cnf 调整离线安装成功不是终点。默认配置的 MySQL 8 能跑但远谈不上好用。生产上一套合理的my.cnf能把后续很多性能问题和运维麻烦提前规避掉。4.1 一份可以直接抄作业的基础配置RPM 安装的配置文件在/etc/my.cnf下面是适合中小型业务的基础模板[mysqld] datadir/var/lib/mysql socket/var/run/mysqld/mysqld.sock pid-file/var/run/mysqld/mysqld.pid log-error/var/log/mysqld.log # 连接与端口 port3306 bind-address0.0.0.0 max_connections500 max_connect_errors1000 # 字符集 character-set-serverutf8mb4 collation-serverutf8mb4_0900_ai_ci # 日志 slow_query_log1 slow_query_log_file/var/log/mysql-slow.log long_query_time2 log_timestampsSYSTEM # 缓存与线程 innodb_buffer_pool_size1G innodb_log_file_size256M配置文件写好之后重启生效systemctl restart mysqld关于innodb_buffer_pool_size一个简单的经验是设为物理内存的 50%~70%但不要超过可用内存的一半太多否则和其他进程争内存容易触发 swap。测试机内存 2G 的话512M 起步就够了。4.2 生产常用参数连接数、超时、日志与字符集max_connections不要盲目设大。500 是一个比较稳妥的起点如果业务确实需要更高并发可以渐进调整。每次调大后观察Threads_connected和Threads_running两个状态值避免资源浪费。skip-name-resolve是很多 DBA 喜欢开的参数能避免远程连接时反向解析域名造成的延迟。但开了之后MySQL 授权表里就不能用域名匹配主机必须用 IP。如果你的业务用了类似userapp-server.local这样的授权开了它会连不上这点要特别注意。字符集这里多说一句MySQL 8 默认字符集已经是utf8mb4但排序规则在不同版本间有差别。我模板里写的是utf8mb4_0900_ai_ci这是 8.0 的默认排序规则。如果你以后要和老版本环境做数据迁移建议先确认两边排序规则一致否则表关联可能出现 collation 冲突。4.3 自定义 datadir 的三件套权限、SELinux 上下文、备份迁移如果数据目录不是默认的/var/lib/mysql而是/data/mysql那要处理三件事。第一件目录属主必须是mysql:mysqlmkdir -p /data/mysql chown -R mysql:mysql /data/mysql chmod 750 /data/mysql第二件RockyLinux8 默认开启 SELinux自定义目录不在mysqld_db_t类型里会被 denied。需要设置上下文yum install -y policycoreutils-python-utils semanage fcontext -a -t mysqld_db_t /data/mysql(/.*)? restorecon -Rv /data/mysql这一步不做mysqld 启动时会报权限错误但报错信息往往看着像文件权限问题排查起来很迷惑。第三件如果是在已有数据的情况下迁移目录正确顺序是先停服务再rsync数据到新目录然后改my.cnf里的datadir最后restorecon和重启服务。不要边跑边拷数据一致性没法保证。5. 离线部署最容易翻车的五个场景这一章把我实际踩过和帮同事排查过的典型问题集中列出来。顺序不重要但每一条都可能卡住你一两个小时。5.1 动态链接库缺失导致 mysqld 起不来表现systemctl start mysqld后服务状态是 failedjournalctl -u mysqld里报error while loading shared libraries: libaio.so.1: cannot open shared object file这类问题本质是系统缺少运行时依赖库。排查思路很直接ldd /usr/sbin/mysqld | grep not found看哪些库缺失然后回联网机器上把对应 RPM 下载下来。常见的缺失库包括libaio.so.1、libncurses.so.5、libnuma.so.1等。处理办法是安装对应的包libaio、ncurses-libs、numactl-libs。如果你的离线包目录里已经有这些 rpm直接yum localinstall -y libaio*.rpm ncurses*.rpm numactl*.rpm装完后再次ldd检查确认没有 not found再启动服务。5.2 日志里找不到临时密码表现执行mysqld --initialize后去/var/log/mysqld.log里查 temporary password什么都没看到。这不是初始化失败更多时候是你没找到正确的日志路径。对策有两个明确指定日志路径后重新初始化mysqld --initialize --usermysql --log-error/tmp/mysql-init.log cat /tmp/mysql-init.log或者直接放弃随机密码路线改为mysqld --initialize-insecure --usermysql用空密码登录后自改。我建议新环境无脑走第二条省时间。只有在安全要求特别高的环境里才值得花时间找随机密码。5.3 弱密码被 validate_password 卡住表现执行ALTER USER设置简单密码时报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirementsMySQL 8 的 validate_password 是默认启用的默认策略要求包含大小写字母、数字、特殊字符长度至少 8 位。想临时允许弱密码在 MySQL 里执行SET GLOBAL validate_password.policy LOW; SET GLOBAL validate_password.length 6;然后把密码改掉。要永久生效把这些参数写进my.cnf的[mysqld]段[mysqld] validate_password.policyLOW validate_password.length6但我的建议还是测试环境这么干没问题生产环境保持默认强密码策略。5.4 SELinux 把自定义数据目录拦在门外表现数据目录明明chown mysql:mysql了目录权限也是 750但 mysqld 启动后立刻退出错误日志里出现类似[ERROR] failed to open directory /data/mysql: Permission denied这通常是 SELinux 在拦。查看 SELinux 拦截记录ausearch -m avc -ts recent如果确认是文件上下文问题按 4.3 里的命令重新设置mysqld_db_t和restorecon。如果现场确实不要求 SELinux 保护且运维规范允许也可以临时关闭验证问题是否与 SELinux 相关setenforce 0验证没问题后再决定是否在 /etc/selinux/config 里永久关闭。我个人建议能修上下文就不要关 SELinux毕竟这是 RockyLinux8 的默认安全机制直接关闭会把系统整体防护降级。5.5 收尾检查端口、Socket 与远程连接验证所有坑填完最后过一遍收尾检查# 检查监听端口 ss -tlnp | grep 3306 # 检查 socket 文件 ls -l /var/run/mysqld/mysqld.sock # 检查进程 ps -ef | grep mysqld在另一台机器上测试远程连接mysql -h 目标机IP -P 3306 -uroot -p如果连接报Host is not allowed to connect to this MySQL server那是在授权层面没放行远程 root 登录SQL 里补授权即可CREATE USER root% IDENTIFIED BY NewPassword_123; GRANT ALL PRIVILEGES ON *.* TO root%; FLUSH PRIVILEGES;但注意生产上直接开放 root 远程权限风险很大建议建立独立账号。最后再分享一点个人体会离线安装这件事百分之八十的功夫在准备阶段也就是提前把 RPM 包、依赖、配置文件都弄齐到了现场反而就是几分钟的事。我后来养成了一个习惯每次离线装完 MySQL 后会把整个 rpm 目录、my.cnf 模板、初始化命令按日期归档成一整套部署包下次新机器直接复用。这个习惯帮我省了不少时间也保证了不同机器上的 MySQL 版本和配置尽量一致。
返回列表