RedHat 6.4离线安装MySQL 5.7:rpm依赖、初始化与踩坑全记录 刚帮一个完全离线的内网环境完成了一次数据库小版本升级目标机器是RedHat 6.4要装MySQL 5.7。别看这套组合拿出来就带着“老古董”气质真实生产环境里靠它跑业务的一抓一大把。这篇文章把我安装、初始化、调参、配自启、放防火墙权限、以及来回踩坑的过程完整记录下来。照着走半天内你也能在这类老系统上把5.7跑起来。1. 先想清楚为什么还在RedHat 6.4上装5.7以及离线怎么装1.1 还在用RedHat 6.4 MySQL 5.7的几种真实场景先说结论愿意在2025年维护RedHat 6.4的系统通常不是“选择”而是“没得选”。最常见的场景有三类。第一类是纯内网生产环境机器从上线那天就没接过外网系统补丁、软件包全靠光盘和拷贝业务连续性是第一位的。你不可能为了升级数据库去动整个操作系统只能在现有6.4上把数据库从更老的5.1、5.5升到5.7。第二类是应用系统年代太久兼容性被钉死。比如某些老业务用到了旧SQL语法、特定排序规则MySQL 8.0上去直接行为异常5.7是它们能接受的最高版本。第三类是安全整改需求旧版本存在已知漏洞等保检查会点名必须升级到仍有安全修复覆盖的5.7分支。1.2 离线安装路线对比rpm包、二进制包、源码编译怎么选离线装MySQL 5.7核心路线就三条。我用下面这个表快速对比过最后选的是“rpm bundle 本地yum”。安装方式依赖处理安装难度管理规范性适合场景rpm bundle yum localinstall自动解析需补少量系统依赖低高rpm -qa可查卸载清晰绝大多数生产环境推荐官方二进制tar.gzglibc2.12版几乎无依赖解压即用低中手工配置目录和自启依赖包不好收集或想完全自主控制目录源码编译安装编译器、库齐全才行高编译时间长中极少推荐除非要改编译参数docker这路我直接没考虑RedHat 6.4的内核是2.6.32新版容器引擎对内核特性要求太高老版本容器引擎又跟5.7镜像兼容性不好绕远路。最终选择rpm bundle方案还有一个关键原因它把mysqld启动脚本、配置文件模板、目录权限都帮你铺好了这对6.4这种需要手工维护的系统来说能少掉一大半麻烦。唯一要小心的是MySQL官方已经不再为el6专门出包后面版本基本是给el7平台编译的但el7的rpm包本身基于glibc 2.12编译刚好RedHat 6.4也是glibc 2.12所以实际能用。这个细节后面单独讲。2. 离线安装前的一揽子准备2.1 下载安装包版本、平台和文件名怎么看我这次选的是5.7分支最后一个版本MySQL 5.7.44。第三位版本号奇数表示创新版、偶数表示稳定版5.7.44是偶数修复了该分支后期大量累积问题也是这个分支的收尾版本稳定性相对有保障。下载地址在MySQL官网的Community Server下载页面选择Archives版本选5.7.44操作系统选Red Hat Enterprise Linux 7架构选x86_64然后下载这个文件mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar注意这个文件名里的“el7”很多人看到会犹豫我是el6系统能装el7的包吗这里的关键不是发行版版本号而是glibc版本。MySQL 5.7后期官方停止发布el6专用包但编译时对系统的要求仍然是glibc 2.12RedHat 6.4完美满足。真正会影响运行的是init脚本体系RedHat 6.4没有systemd而5.7的rpm包自带SysV风格启动脚本所以也能兼容。这是我实际验证过的路线不是纸上谈兵。下载完成后除了主bundle包还要准备一份MD5校验值确保拷贝进内网时文件没损坏md5sum mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar把校验值和官网发布页上的值对照相差一个字节都不能装。2.2 梳理依赖5.7在el6上缺的包全部列出来MySQL 5.7的rpm包在安装时会有少量系统级依赖RedHat 6.4默认安装通常不全。我在这次安装前先列了依赖清单避免装到一半报错再满世界找包。依赖包用途6.4默认状态libaio / libaio-develInnoDB引擎的异步IO调用必须经常缺失numactl / libnuma内存分配策略相关5.7依赖部分机器缺失perl / perl-DBImysql.server启动脚本和安装工具需要一般自带版本要够ncurses-libs命令行客户端界面支持一般自带mysql-community-libs-compat为老应用提供旧版客户端库不是启动必需但是个雷区bundle里自带在纯离线条件下补这些依赖最常见的办法是找一台和6.4同版本、能联网的机器先下载好对应rpm再用U盘带进去。另外RedHat 6.4安装光盘的Packages目录里也有libaio、numactl这些包没有外网也可以从光盘提取。2.3 把安装包和依赖统一放到一个目录构建本地安装源在内网机器上我习惯把所有rpm文件集中到一个目录例如mkdir -p /root/mysql-rpms cp mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar /root/mysql-rpms/ cd /root/mysql-rpms tar -xvf mysql-5.7.44-1.el7.x86_64.rpm-bundle.tarbundle解开后会出现这些主要rpmmysql-community-common-5.7.44-1.el7.x86_64.rpm mysql-community-libs-5.7.44-1.el7.x86_64.rpm mysql-community-libs-compat-5.7.44-1.el7.x86_64.rpm mysql-community-client-5.7.44-1.el7.x86_64.rpm mysql-community-server-5.7.44-1.el7.x86_64.rpm mysql-community-devel-5.7.44-1.el7.x86_64.rpm mysql-community-test-5.7.44-1.el7.x86_64.rpm然后把你找到的libaio、numactl等系统依赖rpm也放进这个目录下一步就可以直接用yum的本地安装模式处理。这里我没构建createrepo仓库因为只有几个包的时候yum localinstall直接指定文件路径就够了建仓库反而绕。3. 核心安装实操从解包到第一次启动3.1 把旧MySQL和残留文件清干净内网机器很可能之前装过MySQL 5.1或者5.5直接装5.7的rpm会跟旧的mysql-libs冲突。卸载前先看系统里有什么rpm -qa | grep -i mysql如果只是mysql-libs这类基础库卸载前要确认没有系统组件依赖它。6.4上postfix等组件有时会依赖mysql-libs直接rpm -e可能连带破坏postfix。稳妥顺序是service mysqld stop # 如果有老实例在跑 rpm -e mysql-libs --nodeps同时我还要备份老数据目录这个必须放在最高优先级cp -a /var/lib/mysql /var/lib/mysql.bak.$(date %Y%m%d)3.2 用本地yum安装MySQL Server及相关组件清理干净后进入rpm目录执行cd /root/mysql-rpms yum localinstall mysql-community-common-5.7.44-1.el7.x86_64.rpm \ mysql-community-libs-5.7.44-1.el7.x86_64.rpm \ mysql-community-libs-compat-5.7.44-1.el7.x86_64.rpm \ mysql-community-client-5.7.44-1.el7.x86_64.rpm \ mysql-community-server-5.7.44-1.el7.x86_64.rpmyum会自动在指定文件之间解析依赖目录里放着的libaio、numactl等系统依赖包也能一并解决。装的时候它会问你“Is this ok [y/N]”确认即可。如果某些依赖在目录里没找到比如提示需要perl-DBD-MySQL就在目录里补上这个包再重试。多个包之间如果有严格顺序要求yum localinstall通常能处理好一旦它报“multilib version”或“conflict”错误就用最原始的手工顺序安装rpm -ivh mysql-community-common-*.rpm rpm -ivh mysql-community-libs-*.rpm rpm -ivh mysql-community-libs-compat-*.rpm rpm -ivh mysql-community-client-*.rpm rpm -ivh mysql-community-server-*.rpm提示rpm -ivh --nodeps 是最后手段。它会跳过依赖检查装完可能启动时才暴露问题非必要不用。安装完成后验证一下版本rpm -qa | grep mysql mysqld --versionmysqld能正确输出版本号说明二进制已经就位。3.3 初始化数据目录--initialize和--initialize-insecure怎么选MySQL 5.7之后数据目录初始化不再推荐老一套的mysql_install_db改用mysqld自身完成mysqld --initialize --usermysql --basedir/usr --datadir/var/lib/mysqlrpm安装默认会把datadir指向/var/lib/mysql属主默认是mysql。如果你改过datadir比如放到独立磁盘/data/mysql需要先手工创建并授权mkdir -p /data/mysql chown -R mysql:mysql /data/mysql mysqld --initialize --usermysql --datadir/data/mysql--initialize会在数据目录里初始化系统库同时生成一个临时root密码打印在错误日志中。--initialize-insecure则生成一个无密码的root账号只适合开发测试环境。生产环境我建议用--initialize临时密码走一下流程很简单安全起点高。初始化完成的标准输出是日志末尾出现一行类似[Note] A temporary password is generated for rootlocalhost: xxxxXXxxxx记住这个字符串后面登录要用。3.4 my.cnf配置照着抄就能用的一套推荐配置5.7安装完成后默认的/etc/my.cnf内容很简陋我会直接改成下面这套覆盖生产常用需求[mysqld] datadir/var/lib/mysql socket/var/lib/mysql/mysql.sock symbolic-links0 character-set-serverutf8mb4 collation-serverutf8mb4_general_ci lower_case_table_names1 max_connections500 max_allowed_packet64M connect_timeout10 wait_timeout28800 interactive_timeout28800 innodb_buffer_pool_size1G innodb_log_file_size256M innodb_flush_log_at_trx_commit2 innodb_file_per_table1 log-error/var/log/mysqld.log pid-file/var/run/mysqld/mysqld.pid [client] socket/var/lib/mysql/mysql.sock default-character-setutf8mb4几个参数的实际意义lower_case_table_namesLinux系统默认值是0表名区分大小写。如果业务是从Windows迁移过来的必须设成1否则建好的表在Linux上可能找不到。这个参数强烈建议在初始化前确定中途改会导致已有表名大小写混乱。innodb_buffer_pool_size内存不充裕的机器给512M超过8G内存的机器给物理内存的50%到70%都行。innodb_flush_log_at_trx_commit生产环境想要最高持久性设1想要性能妥协设2。离线内网系统大多对性能更敏感我用2居多。default-character-setutf8mb45.7服务端默认字符集在部分版本上仍然不够“现代”乱码问题往往就是没显式设置字符集造成的。改完配置先别急着启动再检查一下/var/log/mysqld.log这个日志文件是否存在并且属主是mysql。有时候rpm安装没有自动创建日志文件mysqld启动时会因为无法写日志而失败。4. 启动、账号与远程访问配置4.1 启动服务用临时密码完成root改密6.4没有systemdrpm包安装后会生成SysV启动脚本直接用service mysqld start如果启动失败第一步不是猜去看日志tail -100 /var/log/mysqld.log启动成功后查临时密码grep temporary password /var/log/mysqld.log登录mysql -uroot -p输入临时密码后MySQL会强制要求立即改密报错提示密码已过期。执行ALTER USER rootlocalhost IDENTIFIED BY Your-Strong-Passw0rd!;5.7默认装了validate_password插件密码必须包含大小写字母、数字和特殊符号长度至少8位。如果你接受降低密码策略也可以SET GLOBAL validate_password_policyLOW; SET GLOBAL validate_password_length6;但我建议生产环境保留默认强度。4.2 创建业务账号并开通远程访问root账号默认只允许本机socket登录业务应用需要通过IP访问时要单独建账号CREATE USER app% IDENTIFIED BY App-Str0ng-Pass!; GRANT ALL PRIVILEGES ON appdb.* TO app%; FLUSH PRIVILEGES;这里建议不要直接GRANT ALL ON.只给实际业务库的权限。内网环境虽然威胁模型不同但最小权限原则放哪里都不过时。MySQL 5.7默认认证插件是mysql_native_password多数老业务客户端能直接连不用像8.0那样折腾caching_sha2_password兼容问题。如果程序连不上并报认证插件错误可以用这句强制指定ALTER USER app% IDENTIFIED WITH mysql_native_password BY App-Str0ng-Pass!;4.3 开机自启没有systemd的年代怎么处理装完rpm包并首次启动成功后把服务加入开机启动chkconfig --add mysqld chkconfig mysqld on查看确认chkconfig --list mysqld对RedHat 6.4来说chkconfig加进去后重启机器mysqld会自动拉起。手工启动的备选方案是mysqld_safe但它主要用来排障或前台调试日常运维用service mysqld start就好。5. 网络访问、防火墙与基础加固5.1 iptables放行3306与SELinux处理RedHat 6.4的防火墙是iptables没有firewalld。放行数据库端口编辑规则文件vim /etc/sysconfig/iptables在COMMIT之前加入-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT重启防火墙service iptables restart这里有个容易被忽略的坑如果规则加在默认DROP策略后面或者加了但顺序在REJECT规则之后依然连不上。验证用iptables -L -n | grep 3306SELinux也要检查6.4默认enforcinggetenforce如果慌张之下直接setenforce 0确实能解决大多数权限问题但生产系统不建议长期关闭。规范做法是给MySQL端口添加SELinux放行策略semanage port -a -t mysqld_port_t -p tcp 3306同时如果你的数据目录放在自定义路径比如/data/mysql还需要设置正确的上下文chcon -R -t mysqld_db_t /data/mysql否则即使文件属主是mysqlmysqld启动时也可能因为SELinux拒绝而报权限错误。5.2 针对老环境的几项基础安全建议RedHat 6.4本身已经是生命周期结束的系统能做的加固有限但数据库层可以做的事还不少。第一清掉数据库里的空密码账号和匿名账号SELECT user, host, authentication_string FROM mysql.user;第二不要给root开远程登录root永远从本机socket登录。5.7默认rootlocalhost就是只能本机保持默认。第三开启binlog离线环境虽然没有主从但binlog是误删数据后的后悔药[mysqld] server-id1 log-binmysql-bin binlog_formatrow expire_logs_days7第三把max_connections和max_allowed_packet压到业务够用即可别给太高。6.4的机器通常内存有限连接数开太大内存和文件描述符容易先被打满。6. 踩坑记录离线安装期间的高频问题6.1 依赖报错导致的安装失败安装时最容易卡在rpm依赖上。常见报错error: Failed dependencies: libaio.so.1()(64bit) is needed by mysql-community-server-5.7.44-1.el7.x86_64 libnuma.so.1()(64bit) is needed by mysql-community-server-5.7.44-1.el7.x86_64处理方式很简单把对应的libaio、numactl包拷贝到目录重新跑yum localinstall。如果目录里没有这些包就在同版本可联网机器上提前下载好。另外一个隐藏较深的依赖是mysql-community-libs-compat它负责提供老版本libmysqlclient.so共享库给系统里的旧程序。如果系统里有老应用依赖这个库不装compat包应用跑了几天突然连不上数据库那时排查起来更痛苦。6.2 初始化失败和启动失败初始化mysqld --initialize时最常见的坑是报这类错误[ERROR] InnoDB: Operating system error number 13 in a file operation. [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.这就是典型的data目录没有授权给mysql用户。解决chown -R mysql:mysql /var/lib/mysql另一个高频启动失败原因是/var/run/mysqld目录不存在或属主不对mkdir -p /var/run/mysqld chown mysql:mysql /var/run/mysqldrpm包安装后理论上会创建这个目录但如果系统里有残留或者tmpwatch清理过就可能缺失。pid-file路径对不上也是同类问题确认my.cnf里pid-file指向的目录存在。6.3 登录失败、临时密码找不到初始化完成后在日志里找不到临时密码这是很多人栽跟头的环节。原因主要两个一是日志路径和my.cnf不一致初始化时的输出写到了默认位置但你改了log-error路径二是初始化过程中日志目录属主不对写不进去。检查方法ls -l /var/log/mysqld.log grep temporary password /var/log/mysqld.log如果确实找不到最省事的方式是用--initialize-insecure重新初始化得到一个无密码root然后立即登录改密rm -rf /var/lib/mysql/* mysqld --initialize-insecure --usermysql service mysqld start mysql -uroot ALTER USER rootlocalhost IDENTIFIED BY Your-Strong-Passw0rd!;还有一种情况是mysql -uroot -p能登录但提示密码过期这是5.7的默认行为直接ALTER USER改新密码就行不是故障。如果root密码彻底忘了用跳过授权表方式启动mysqld_safe --skip-grant-tables --skip-networking mysql -uroot FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY New-Str0ng-Pass!;改完必须正常重启mysqld否则数据库一直裸奔在无认证状态。6.4 字符集、乱码与连接工具问题数据写入后中文全部变成问号或者乱码基本是字符集配置问题。排查先看现状SHOW VARIABLES LIKE character%; SHOW VARIABLES LIKE collation%;需要看到character_set_server和character_set_database都是utf8mb4而不是latin1或者utf8。如果是latin1回到3.4小节把my.cnf里的字符集配置补上重启后再建的表才是utf8mb4。已经建好的库表和转码要单独处理不能靠改参数解决。命令行客户端连接时如果屏幕显示乱码可以显式指定mysql -h内网IP -uapp -p --default-character-setutf8mb4另外老内网环境里可能还残留着5.1时代的mysql客户端连5.7时偶尔会因为协议和插件兼容问题报错。这种情况下优先在应用服务器上换装新版本客户端而不是去改服务端认证插件。6.5 老库数据迁移要点把旧版本的业务数据迁移到新5.7实例时最常用的还是mysqldump。旧实例导出mysqldump -uroot -p --single-transaction --routines --triggers --events \ --set-gtid-purgedOFF --default-character-setutf8mb4 appdb appdb.sql新实例导入mysql -uroot -p --default-character-setutf8mb4 appdb appdb.sql注意几个细节。--set-gtid-purgedOFF必须加MySQL 5.6以后导出文件里如果带GTID信息5.7导入时可能在binlog开启的场景下报错。--default-character-setutf8mb4两端都要带避免导出时数据被转码。导入完成后要对比行数和关键表记录数这个步骤不能省。7. 最后说点维护老环境的实际建议说实话把RedHat 6.4和MySQL 5.7组合起来维护本身就是一件“戴着镣铐跳舞”的事。系统层面的补丁早就停了数据库虽然是5.7分支的最终版本但再过几年也会进入更深的维护阶段。我在实际运维里最大的体会是这类环境的稳定性不是靠某一次安装而是靠安装之后的一系列约束配置和二进制目录分离、数据目录独立、binlog开启、定期mysqldump再加一份物理备份。只要这些底盘是稳的系统再老数据库出大事的概率也能压得非常低。还有一条血泪教训在这类老系统上做任何变更千万不要只准备一条路。rpm装不上就换tar包方案tar包的安装依赖少只需要解压、初始化、配自启三步作为退路非常趁手。离线环境最大的敌人不是技术是“手里没有备选方案”时的焦虑。把你机器上能用的工具、光盘里的依赖包、网上能找到的rpm全备份一份到本地仓库以后再折腾任何东西心里都有底。