尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

无网环境离线安装MySQL 8.0:rpm依赖处理与yum本地仓库实战指南

无网环境离线安装MySQL 8.0:rpm依赖处理与yum本地仓库实战指南 写这篇东西之前先交代下背景。最近接手了一个隔离网段的项目服务器全部在封闭的内网环境里别说外网了连本地 yum 源都没有。业务系统又指定要 MySQL 8.0这可把不少人卡住了——毕竟平时大家装 MySQL 都是拿着 yum 一行命令搞定一旦断网光是那一堆依赖包的循环依赖就够喝一壶。我把整个过程从头到尾趟了一遍从在联网机器上收集 rpm 包到内网服务器上离线安装、初始化、调优最后再用 Navicat 远程连上中间踩了不少坑也整理出了一套几乎可以照着抄的操作流程。这篇就完完整整分享出来给所有被“无网安装 MySQL 8.0”折磨过的朋友一个参考。1. 为什么说无网装 MySQL 8.0 是个坎MySQL 8.0 和 5.7 看着都是 rpm 包装起来其实完全两个难度级别。8.0 的安装包拆得更碎各个组件之间互相有依赖关系而且对操作系统的 glibc、libaio、numactl 这些基础库版本有硬性要求。你光下载一个 mysql-server 的 rpm 是远远不够的它会在安装时就给你报一堆 error: Failed dependencies然后整个安装流程直接中断。在线环境里遇到依赖缺失yum 会自动从仓库里把依赖拉下来装上你根本感知不到。但离线环境下yum 等于废了所有依赖都得你自己提前准备好少一个就装不上。更麻烦的是依赖是有层级关系的A 依赖 BB 依赖 CC 又依赖 D而且还存在循环依赖比如两个包互相依赖你必须把两个 rpm 文件放到同一个目录下用一条命令同时安装才能解掉这个结。我这次用的服务器是 CentOS 7.9内核 3.10glibc 2.17MySQL 版本是 8.0.36。这套组合是目前无网部署最常见的搭配兼容性经过了大量验证。操作系统跟 MySQL 版本选对了后面的坑能少一半。2. 装之前必须想清楚的四个方案问题2.1 为什么选 rpm 而不是源码编译很多人一提到离线安装就想到编译源码说实话这是最不推荐的路子。MySQL 8.0 源码编译依赖的库非常多boost、cmake、gcc 版本都有要求而且编译一次少说四十分钟多则两三个小时中途任何一个依赖不满足都会前功尽弃。在无网环境下你根本没法临时去补装编译工具链。rpm 包则是已经编译好的二进制只要依赖库版本匹配装完就能用部署效率高一个数量级。2.2 要不要考虑 Docker 方案说实话如果服务器上有 Docker 环境那直接跑 mysql:8.0 镜像是最省事的一个 docker load 就搞定了。但很多内网服务器是纯净系统连 Docker 都没有你还得先离线装 Docker这就又绕回到依赖地狱里了。所以本文不讨论 Docker 路径专注原生 rpm 安装这也是兼容性最好、最通用、后续维护最直接的方式。2.3 依赖包收集的两种策略收集依赖包有两种策略一种是在能联网的机器上用 yumdownloader 把 MySQL 官方仓库里的 rpm 连同依赖一起下载到本地另一种是直接用 yum 的 downloadonly 插件。两种方式本质一样但前者更灵活可以指定下载目录。实际操作中我推荐在 CentOS 7 的联网机器上先把 MySQL 官方 yum 仓库装好然后一条命令把需要的包全部拉下来这样能保证版本号完全对应不会出现内网里装到一半发现版本不匹配的问题。2.4 版本锁定与后续升级的考量无网环境下还有一个隐形问题——版本锁定。在线环境可以随时 yum update 升级 MySQL无网环境一旦部署完后续升级就得重新走一遍离线流程。所以前期最好是直接装当时最新的稳定版减少升级频率。我用的 8.0.36 在写这篇时是官方长期支持版功能稳定bug 修复也全面踩坑概率相对较低。3. 在联网机器上准备离线安装包3.1 准备工作一台能联网的 CentOS 7 机器在开始之前需要确认自己的操作环境。我自己是在一台可以联网的 CentOS 7 最小化安装机器上操作的这台机器最好和你的内网目标机器是同一个大版本避免 glibc 版本差异。如果你手里只有 Windows 机器也可以装个 CentOS 7 虚拟机来做包收集反正最后只需要拿到 rpm 文件集合就行。首先确认系统版本和架构cat /etc/redhat-release uname -m输出结果应该是CentOS Linux release 7.9.2009 (Core) x86_64x86_64 架构下下面的包都能直接用。如果是 arm64 架构比如华为鲲鹏服务器下载包的时候要选 aarch64 版本后面操作逻辑一样。3.2 下载 MySQL 官方 yum 仓库并启用联网机器上先把 MySQL 官方 yum 仓库装上rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm装完后确认仓库里 MySQL 8.0 的源是启用的yum repolist enabled | grep mysql正常会看到 mysql-connectors-community、mysql-tools-community、mysql80-community 这三行。如果 mysql80-community 没启用手动打开yum-config-manager --enable mysql80-community3.3 核心一步用 yumdownloader 批量拉取 rpm这里用到的核心工具是 yumdownloader它在 yum-utils 包里。先安装yum install -y yum-utils然后建一个目录把所有需要的 rpm 下载进去mkdir -p /root/mysql8-offline-rpm cd /root/mysql8-offline-rpm yumdownloader --resolve mysql-server加上 --resolve 参数后yumdownloader 会把 mysql-server 以及所有依赖包全部下载到当前目录。这一步下载的包数量通常有十几个包括 mysql-server、mysql-client、mysql-common、libaio、numactl-libs、openssl-libs、ncurses-compat-libs、perl 相关包等等。下载完成后数一下文件数量ls -lh /root/mysql8-offline-rpm | wc -l一般会有 15-25 个 rpm 文件具体数量取决于你安装的组件。这时候不要急着走再手动补几个打包时容易漏掉的yumdownloader --resolve mysql-community-client yumdownloader --resolve mysql-community-libs yumdownloader --resolve mysql-community-common这样能把客户端、库文件、公共文件全套抓齐避免内网机器上装完 server 后发现缺客户端工具。3.4 生成本地仓库索引关键细节手动收集的 rpm 文件直接 yum localinstall 也是能装的但依赖关系处理不够聪明。更好的做法是顺便生成一个本地 yum 仓库索引让内网机器上也能用 yum 来智能解决依赖顺序。联网机器上安装 createrepo 工具并生成索引yum install -y createrepo createrepo /root/mysql8-offline-rpm生成完成后目录里会多出一个 repodata 子目录这个目录就是 yum 的索引数据库。把整个 /root/mysql8-offline-rpm 目录打包传到内网机器上tar czf mysql8-offline-rpm.tar.gz mysql8-offline-rpm/3.5 如果找不到联网的 CentOS 机器的替代方案如果手上实在没有能联网的 CentOS 7 机器还可以用一个更取巧的办法在一台能联网的任意 Linux 机器上去 MySQL 官方下载页面把对应 el7 的 rpm 包全部手工点下载。页面地址是 MySQL Community Server 下载页选 Red Hat Enterprise Linux 7 / Oracle Linux 7挑 x86_64 架构把下面这些包逐一下载mysql-community-servermysql-community-clientmysql-community-libsmysql-community-commonmysql-community-client-pluginsmysql-community-icu-data-files至于 libaio、numactl-libs、ncurses-compat-libs 这些系统依赖直接去 CentOS 7 的官方 mirror 仓库找或者从任意的 CentOS 7 yum 源 respository 里下载对应 rpm。这个方法比较笨但可行。4. 无网环境下的完整安装流程4.1 把安装包传到内网服务器并解压拿到打包好的 mysql8-offline-rpm.tar.gz 之后传到目标服务器的 /opt 目录下然后解压cd /opt tar zxf mysql8-offline-rpm.tar.gz cd mysql8-offline-rpm/解压后目录下应该有全部 rpm 文件和 repodata 目录。先检查当前系统是否装了旧版 MySQL 或 MariaDB有的话先卸载干净否则端口和 socket 文件会冲突rpm -qa | grep -E mysql|mariadb查出有 mariadb-libs 这类包直接卸载rpm -e --nodeps mariadb-libs这个操作在最小化安装的 CentOS 7 上几乎必做系统默认自带 mariadb-libs不去掉的话装 MySQL 时会有文件冲突。4.2 配置离线 yum 仓库推荐省心在 /etc/yum.repos.d/ 下新建一个本地仓库配置指向刚才解压的目录vi /etc/yum.repos.d/mysql-offline.repo写入以下内容[mysql-offline] nameMySQL 8.0 Offline RPM Repository baseurlfile:///opt/mysql8-offline-rpm enabled1 gpgcheck0保存后清理 yum 缓存并重建yum clean all yum makecache此时 yum repolist 里应该出现 mysql-offline 仓库。这样做的最大好处是依赖顺序完全由 yum 自动解析比如它知道要先装 common 再装 libs 再装 server不用你自己去手动算依赖链。4.3 一条命令离线安装 MySQL 8.0配置好本地仓库之后安装变得非常简单yum install -y mysql-community-serveryum 会自动从本地仓库中解析所有依赖并逐个安装。如果前面收集的 rpm 包数量够全这一步通常不会报错。如果个别依赖缺失就把报错提示的包名记录下来回到联网机器上用 yumdownloader 补拉一次再传过来重新安装即可。我实测在最小化 CentOS 7.9 上mysql80-community-release 仓库依赖的全部包加系统库总共是 27 个 rpm 文件安装完成后 /usr/bin 下会有 mysql 和 mysqladmin 等客户端工具/usr/sbin 下有 mysqld 服务端。4.4 不建本地仓库的直接安装方式如果你不想创建本地 yum 仓库也可以直接用 rpm 命令安装。但有一个关键坑rpm -ivh 一次只装一个包会卡在依赖上正确做法是把所有 rpm 放在同一目录下一条命令同时安装cd /opt/mysql8-offline-rpm rpm -ivh *.rpm --nodeps用 --nodeps 可以跳过依赖检查强行安装但如果系统里真的缺了某些基础库比如 libaio 根本不存在mysqld 启动时会直接失败报错信息还挺难排查。所以这个方式我放在最后推荐除非你确认系统基础库齐全否则还是建议走 yum 本地仓库让安装过程变成“傻瓜式”操作。5. 初始化配置与调优装完才是开始5.1 首次启动与临时密码获取安装完成后先初始化数据目录然后启动服务mysqld --initialize --usermysql这一步会生成初始数据目录 /var/lib/mysql并创建一个随机临时密码。初始化过程如果报错先看日志cat /var/log/mysqld.log常见错误多是 /var/lib/mysql 目录权限不对或者缺 mysql 用户。权限不对就先 chown 一下chown -R mysql:mysql /var/lib/mysql用户不存在则创建系统用户useradd -r -s /sbin/nologin mysql初始化成功后启动 mysqld 并设置开机自启systemctl start mysqld systemctl enable mysqld临时密码在日志里用 grep 关键词找出来grep temporary password /var/log/mysqld.log输出类似这样[Note] A temporary password is generated for rootlocalhost: xxxxxxxx这个密码只生效一次首次登录后 MySQL 会强制你修改密码。5.2 首次登录与密码策略调整用临时密码登录mysql -uroot -p登录成功后第一件事就是改密码ALTER USER rootlocalhost IDENTIFIED BY YourStrongPass123!;MySQL 8.0 默认密码策略要求包含大小写字母、数字和特殊字符且长度至少 8 位。如果你所在的网络环境对内网数据库密码强度要求不那么严格或者业务系统要求弱密码可以先降低校验等级再设置密码SET GLOBAL validate_password.policy LOW; SET GLOBAL validate_password.length 6; ALTER USER rootlocalhost IDENTIFIED BY 123456;需要注意MySQL 5.7 和 8.0 的密码策略参数名完全不同。5.7 是 validate_password_policy8.0 改成了 validate_password.policy带了点号。如果记混淆了会直接报系统变量不存在的错误。为了永久生效还需要把参数写进配置文件 /etc/my.cnf[mysqld] validate_password.policyLOW validate_password.length6否则重启后又会恢复强密码策略。5.3 字符集、时区与端口配置MySQL 8.0 默认字符集已经是 utf8mb4这是好事但有一处地方容易漏默认 collation 可能是 utf8mb4_0900_ai_ci如果业务系统的排序规则和你的开发环境不一致可能出现诡异的排序结果。建议显式指定[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_general_ci default-time-zone08:00时区默认是系统时区如果你服务器在 CST 时区但系统设置成了 UTC时间字段会差 8 个小时排查起来非常头疼。在配置里写死 default-time-zone08:00 一劳永逸。最后检查端口配置默认 3306没特殊需求不用改。确认监听配置netstat -tlnp | grep 3306看到 0.0.0.0:3306 表示服务已经正常监听所有网卡。5.4 创建业务账号并开启远程访问无网部署的数据库通常要允许内网其他机器连接默认 root 只能本地登录需要创建业务账号并授权CREATE USER appuser% IDENTIFIED BY AppPass123!; GRANT ALL PRIVILEGES ON *.* TO appuser% WITH GRANT OPTION; FLUSH PRIVILEGES;注意 8.0 里 GRANT 之后再 FLUSH PRIVILEGES 其实不是必须的因为授权操作会实时生效但习惯上写一下也没毛病。真正必须确认的是防火墙要放行 3306 端口。CentOS 7 默认用 firewalld放行命令firewall-cmd --permanent --add-port3306/tcp firewall-cmd --reload如果用的 iptables则iptables -A INPUT -p tcp --dport 3306 -j ACCEPT service iptables save还有一个隐蔽的坑SELinux。如果 SELinux 开着且 enforcing即使防火墙放行了远程连接仍可能被拒。测试的时候可以直接临时关闭 SELinuxsetenforce 0如果能连上了说明就是 SELinux 的问题。生产环境建议用正确方式处理而不是简单关闭yum install -y policycoreutils-python semanage port -a -t mysqld_port_t -p tcp 33065.5 my.cnf 基础调优参数无网环境下跑业务数据库性能调优主要靠内存池和连接数这两个大头。给出一个适合 8C16G 机器的起步配置实测在中等并发场景下比较稳[mysqld] innodb_buffer_pool_size8G innodb_log_file_size1G innodb_flush_log_at_trx_commit1 max_connections500 table_open_cache2048 sort_buffer_size4M join_buffer_size4Minnodb_buffer_pool_size 是最核心的参数官方建议设为机器物理内存的 50% 到 70%这里 16G 内存给了 8G留了一部分给操作系统和业务进程。如果你机器内存小比如 4G那就把这个值降到 2G 左右宁可小一点也别让 MySQL 把内存吃光导致 OOM。6. 常见问题与排查技巧实录6.1 问题速查表症状可能原因解决方式安装时报 Failed dependencies依赖 rpm 包缺失回联网机器补下载依赖重新生成仓库索引mysqld 启动失败日志报 libaio.so.1 找不到系统缺 libaio 库rpm -ivh libaio-*.rpm或 yum install libaio初始化时报 Cant create directory/var/lib/mysql 权限错误chown -R mysql:mysql /var/lib/mysql远程连接失败客户端报 10060防火墙未放行 3306firewall-cmd 放行端口或关闭 SELinux测试远程连接失败报 1045 Access denied账号未正确授权检查 user 表确认 % 主机授权是否存在密码修改报 ERROR 1819密码不符合策略先 SET GLOBAL validate_password.policyLOW用 Navicat 连上后看不到数据表用户对库没权限GRANT ALL ONdbname.* TO 用户6.2 一个隐蔽的依赖循环案例我在收集依赖时遇到过一个 flaky 的坑mysql-community-server 和 mysql-community-libs 相互依赖如果单独用 rpm -ivh 安装会提示error: Failed dependencies: mysql-community-libs(x86-64) 8.0.36 is needed by mysql-community-server-8.0.36-1.el7.x86_64这是非常经典的循环依赖。你在同一个目录下用一条 rpm 命令同时装这两个包就能解掉rpm -ivh mysql-community-libs-8.0.36-1.el7.x86_64.rpm mysql-community-server-8.0.36-1.el7.x86_64.rpm但如果按照我前面推荐的方式配置了本地 yum 仓库一路 yum install 下来这个循环依赖 yum 会自动处理根本碰不到。这也是我强烈建议走 yum 本地仓库路径的原因。6.3 字符集导致的数据写入报错有次在另一个环境帮人排查问题应用侧写入 emoji 表情时报错java.sql.SQLException: Incorrect string value: \xF0\x9F\x98\x80 for column name at row 1原因就是数据库字符集不是 utf8mb4emoji 属于四字节字符utf8 编码存不下。MySQL 8.0 默认虽然建库是 utf8mb4但如果你建表时指定了 utf8还是会踩坑。解决办法是在 my.cnf 里彻底锁死[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_general_ci然后重启服务新建的库表就都是 utf8mb4 了。已经存在的旧表需要单独转换ALTER TABLE tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;这个操作会重建表数据量大时耗时较长建议业务低峰期执行。6.4 备份恢复路径验证无网部署完不能就这么完事备份恢复路径一定要先验证一遍。MySQL 8.0 自带的备份工具是 mysqldump基础用法mysqldump -uroot -p --single-transaction --master-data2 --all-databases /backup/all_backup_$(date %F).sql--single-transaction 参数在 InnoDB 引擎下能保证备份数据一致性不用锁表对线上业务影响极小。恢复时在目标机器上mysql -uroot -p all_backup_20250601.sql这里提醒一句MySQL 8.0 的 mysqldump 备份数据不能直接恢复到 5.7 版本跨大版本恢复需要用官方提供的迁移工具或者在 5.7 环境里用兼容模式导出。无网环境如果后续要做版本升级这一点尤其要注意。建议在部署完成后立刻做一次全备并恢复到测试库验证别等到业务数据进去之后再现测那时发现问题就麻烦了。6.5 无网环境下的日志清理与维护MySQL 运行一段时间后binlog 会占掉不少磁盘空间。无网环境没有额外的监控报警尤其要注意定期清理。检查当前 binlog 大小du -sh /var/lib/mysql/binlog.*手动清理到指定保留天数之前的 binlogPURGE BINARY LOGS BEFORE NOW() - INTERVAL 7 DAY;更省心的做法是配置自动清理[mysqld] expire_logs_days7MySQL 8.0 里该参数已经改名 binlog_expire_logs_seconds建议用新版写法[mysqld] binlog_expire_logs_seconds604800604800 秒正好是 7 天。配置后重启 mysqld老日志会被自动清理新日志到了时间也会自动滚动删除。别小看这个配置内网服务器磁盘通常不大binlog 堆积把磁盘写满导致 MySQL 直接挂掉的案例我见过不止一次。7. 我的实操心得与几点补充建议整套流程走完最大的体会是离线安装本身不难难的是安装前的准备工作做得到不到位。依赖包收集这一步决定了后面 90% 的成败宁可多收集几个用不到的包也不要装到一半发现缺依赖再回头去补。把本地 yum 仓库建好安装过程从“闯关”变成“一键”体验完全不一样。另外两个小建议送给经常做无网部署的朋友。第一个维护一个自己的 rpm 包仓库把常用的 MySQL、Nginx、Redis、JDK 这些组件的离线安装包按版本归档存放下次部署直接拷走就用能省大量时间。第二个写部署文档的时候把 MySQL 的临时密码获取方式、远程授权命令、防火墙配置这些容易忘的步骤单独用红字标注项目交接的时候能少接无数个咨询电话。这套方案我已经在两批服务器上验证过一次 CentOS 7.9 配 MySQL 8.0.36一次 CentOS 7.6 配 MySQL 8.0.34全程无外网按同样的步骤走下来都是半小时内完成部署。遇到的环境虽然不同但核心思路一致把依赖提前备齐让 yum 帮你解决问题把时间留给真正需要调优的地方。你可以直接拿这份操作记录当参考结合自己服务器的具体配置稍微调整参数应该能少走不少弯路。
返回列表