1. 项目概述与核心场景
在不少企业的生产环境、政府单位的内部网络,或是某些对安全有严格要求的研发场景里,服务器往往处于一个“与世隔绝”的状态——没有外网,甚至物理隔离。这种环境下,想装个MySQL数据库,你没法像在个人电脑上那样,敲个yum install mysql-server就万事大吉。我最近就刚在一个客户的内网数据中心里,折腾完一套CentOS 7上离线部署MySQL 5.7的活儿。整个过程,从找对安装包、处理依赖,到最后的配置优化,每一步都得自己动手,丰衣足食。这篇内容,就是把我这次实操的完整过程、踩过的坑以及验证有效的解决方案,系统地梳理出来。如果你也正面临在无外网的Linux服务器上部署MySQL的需求,特别是使用CentOS 7这个依然广泛存在的经典系统,那么这篇近万字的详细指南,应该能让你少走很多弯路。
为什么是MySQL 5.7?尽管8.0版本功能更强大,但5.7因其极高的稳定性、广泛的生态兼容性以及经过长期考验的可靠性,至今仍是众多企业级应用,尤其是传统或对稳定性要求极高的系统的首选。而CentOS 7,作为Red Hat Enterprise Linux 7的免费克隆版,拥有长达十年的支持周期,其稳定性和安全性使其在服务器领域占据着重要地位。这两者的组合,构成了一个非常经典且坚实的后端服务基础环境。
离线安装的核心挑战,不在于安装命令本身,而在于“依赖”和“环境”。你需要一个完整的、自包含的“安装包集合”,这个集合必须包含MySQL本体及其所有必需的依赖库,并且这些依赖库的版本要与你的系统环境(如glibc版本)精确匹配。任何一环的缺失或版本冲突,都可能导致安装失败或运行时出现诡异问题。接下来,我们就从准备工作开始,一步步拆解这个全过程。
2. 前期准备:构建离线安装仓库
离线安装的第一步,也是最关键的一步,不是在目标服务器上操作,而是在一台可以联网的、系统环境尽可能与目标服务器一致的机器上进行的。我们称之为“打包机”。这台机器的作用,就是利用网络下载所有需要的安装包,形成一个完整的本地仓库。
2.1 环境规划与软件选型
首先,明确你的目标服务器环境。假设我们目标服务器的系统是CentOS 7.9 Minimal,架构是x86_64。你的打包机也必须是相同版本和架构的系统,这是避免依赖地狱的最有效方法。
关于MySQL的安装方式,通常有几种:源码编译、通用二进制包(Generic Binary)、以及RPM包。对于离线环境,我强烈推荐使用RPM包方式。
- 源码编译:虽然最灵活,但过程漫长,需要解决编译依赖(如cmake, gcc, ncurses-devel等),在离线环境下准备这些编译工具链本身又是一项大工程,不推荐。
- 通用二进制包:解压即用,但需要手动初始化数据库、配置环境变量和服务管理脚本,步骤稍显繁琐。
- RPM包:这是Red Hat系Linux(包括CentOS)的“原生”软件包格式。它的最大优势是能清晰地管理依赖关系。我们可以利用
yum或dnf的downloadonly插件,将MySQL及其所有依赖的RPM包一次性下载下来,形成一个完整的离线仓库。安装时,使用rpm命令或配置本地yum源安装,可以自动解决包之间的依赖,是最省心、最接近在线安装体验的方式。
因此,我们的核心思路是:在打包机上,模拟在线安装,但只下载不安装,把所有的RPM包收集起来。
2.2 在打包机上下载所有RPM包
首先,在打包机上,我们需要安装一个能帮助我们只下载不安装的小工具:yum-plugin-downloadonly。如果你的系统没有,请先联网安装:
yum install -y yum-plugin-downloadonly接下来,我们需要添加MySQL的官方Yum仓库。访问MySQL官网的Yum仓库配置页面,找到对应CentOS 7的仓库配置文件。通常,我们可以直接使用以下命令来安装仓库配置包:
# 安装MySQL官方的Yum仓库源 rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm注意:这个命令会默认启用MySQL 8.0的仓库。我们的目标是5.7,所以需要禁用8.0,启用5.7。
# 查看当前可用的MySQL子仓库 yum repolist all | grep mysql # 禁用MySQL 8.0仓库 yum-config-manager --disable mysql80-community # 启用MySQL 5.7仓库 yum-config-manager --enable mysql57-community # 再次确认 yum repolist enabled | grep mysql现在,关键的步骤来了:使用yum的downloadonly插件来下载mysql-community-server这个核心包及其所有依赖。
# 创建一个目录来存放所有下载的RPM包 mkdir -p /opt/mysql-offline-packages # 使用downloadonly插件下载 yum install --downloadonly --downloaddir=/opt/mysql-offline-packages mysql-community-server执行这个命令后,yum会解析mysql-community-server的所有依赖,并将这些RPM包下载到/opt/mysql-offline-packages目录下,但不会执行任何安装操作。
实操心得:有时候,
yum可能会提示“没有启用 downloadonly 插件”或直接开始安装。确保插件已正确安装,并且命令格式无误。一个更稳妥的替代命令是yumdownloader(来自yum-utils包),你需要先yum install -y yum-utils,然后使用yumdownloader --resolve --destdir=/opt/mysql-offline-packages mysql-community-server。--resolve参数会自动下载依赖。
下载完成后,进入目录查看:
ls -lh /opt/mysql-offline-packages/你会看到一堆.rpm文件,数量可能在30-40个左右,包括mysql-community-server,mysql-community-client,mysql-community-libs,mysql-community-common以及许多依赖如net-tools,perl相关的包等。这些就是我们的“离线安装宝库”。
2.3 传输离线包到目标服务器
将/opt/mysql-offline-packages目录整个打包,通过U盘、内部文件服务器、或者安全的网络传输方式(如scp,前提是有内网通路),拷贝到目标离线服务器的某个目录下,例如/tmp/mysql-packages。
# 在打包机上打包 cd /opt tar -czf mysql-offline-packages.tar.gz mysql-offline-packages/ # 传输到目标服务器(假设有内网SCP通道) scp mysql-offline-packages.tar.gz root@目标服务器IP:/tmp/在目标服务器上解压:
mkdir -p /opt/mysql-offline tar -xzf /tmp/mysql-offline-packages.tar.gz -C /opt/ # 最终RPM包路径为 /opt/mysql-offline/mysql-offline-packages/至此,离线安装的“弹药”已经准备就绪。
3. 目标服务器离线安装实战
现在,我们登录到那台没有外网的CentOS 7目标服务器,开始真正的安装。
3.1 环境检查与清理
在安装之前,良好的习惯是检查系统是否已经存在旧版本的MySQL或MariaDB,并进行清理,避免冲突。
# 检查已安装的MySQL或MariaDB包 rpm -qa | grep -i mysql rpm -qa | grep -i mariadb # 如果存在,则卸载它们(谨慎操作,生产环境请确认可卸载) # 例如,卸载MariaDB(CentOS 7默认可能安装了) yum remove -y mariadb-libs # 或者使用rpm -e --nodeps 包名 强制卸载 # 删除旧的MySQL数据目录和配置文件(如果是全新安装或确认可清除) rm -rf /var/lib/mysql rm -rf /etc/my.cnf /etc/my.cnf.d/重要警告:
rm -rf /var/lib/mysql会永久删除所有数据库数据!如果这是升级或迁移,请务必先备份数据。对于全新安装的服务器,可以执行此操作。
3.2 本地RPM包安装
我们有几种方式来安装这一堆RPM包:
方法一:使用rpm命令手动安装(不推荐)你可以尝试rpm -ivh *.rpm,但RPM包之间有严格的依赖顺序,直接这样做大概率会失败,需要你手动排序,非常麻烦。
方法二:配置本地Yum仓库(推荐)这是最优雅的方式,它能让yum在离线环境下,像在线一样自动解决依赖。我们创建一个本地仓库文件。
安装创建本地仓库所需的工具(如果系统最小化安装可能没有): 我们需要
createrepo命令。如果你的离线包中包含了它的RPM,可以先手动安装它和它的依赖(如deltarpm,python-deltarpm)。更简单的方法是,在打包机上下载createrepo的RPM包一并放入离线包目录。这里假设我们已经把它包含在内了。如果没有,你需要找到对应版本的createrepoRPM包并手动解决其依赖,过程类似MySQL。创建本地仓库: 进入我们的RPM包目录,生成仓库元数据。
cd /opt/mysql-offline/mysql-offline-packages/ # 安装createrepo(如果已提前放入包中) rpm -ivh createrepo-*.rpm # 生成仓库数据 createrepo .执行
createrepo .后,会在当前目录生成一个repodata文件夹,里面就是仓库的元数据。配置本地Yum源: 创建一个新的
.repo文件。vi /etc/yum.repos.d/mysql-local.repo添加以下内容:
[mysql-local] name=MySQL Local Repository baseurl=file:///opt/mysql-offline/mysql-offline-packages enabled=1 gpgcheck=0baseurl使用file://协议指向我们的RPM包目录。gpgcheck=0表示不进行GPG密钥检查。因为我们是本地可信包,可以跳过。如果追求安全,可以导入MySQL的GPG密钥并设置为1。
清理Yum缓存并安装:
yum clean all yum makecache # 现在可以像在线一样安装了 yum install -y mysql-community-serveryum会从我们刚配置的mysql-local仓库中查找并安装mysql-community-server及其所有依赖,整个过程自动完成。
方法三:使用yum localinstall(折中推荐)如果觉得配置本地仓库稍显复杂,可以使用yum localinstall命令,它也能自动处理本地RPM文件的依赖。
cd /opt/mysql-offline/mysql-offline-packages yum localinstall -y *.rpm这个命令会扫描当前目录下所有.rpm文件,并尝试解决它们之间的依赖关系后进行安装。它比单纯的rpm -ivh聪明,但本质上还是依赖于系统已配置的仓库来寻找可能的缺失依赖。在我们的场景下,所有依赖包都已在此目录中,所以通常能成功。
实操心得:三种方法中,配置本地Yum仓库是最规范、最接近生产环境运维习惯的做法。它不仅用于本次安装,以后如果需要离线安装其他软件(如PHP、Nginx等),都可以如法炮制,将包放入目录,更新一下仓库(
createrepo --update .)即可。yum localinstall更快捷,适合一次性安装。根据你的运维习惯选择即可。
安装完成后,验证MySQL包是否已安装:
rpm -qa | grep -i mysql-community应该能看到mysql-community-server,mysql-community-client,mysql-community-libs等包名。
4. MySQL数据库初始化与基础配置
安装完RPM包,MySQL服务程序和相关文件就已经部署到系统上了,但数据库还没有初始化,也就是没有创建系统数据库(如mysql,sys,performance_schema)和root用户。
4.1 初始化数据目录
MySQL 5.7推荐使用mysqld --initialize命令进行初始化,这会生成一个临时的root密码。
# 启动MySQL服务(在初始化前,服务是启动不了的,但此操作会创建必要的目录和文件) systemctl start mysqld # 首次启动会自动执行初始化,并生成一个随机root密码。查看日志获取: grep 'temporary password' /var/log/mysqld.log更推荐显式地执行初始化,以便控制行为:
# 首先停止可能因尝试启动而运行失败的服务 systemctl stop mysqld # 删除可能已存在的旧数据(再次确认是全新安装!) rm -rf /var/lib/mysql/* # 执行初始化,并指定默认字符集为utf8mb4 mysqld --initialize --user=mysql --basedir=/usr --datadir=/var/lib/mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci初始化完成后,务必在日志中找到root用户的临时密码:
grep 'A temporary password is generated for root@localhost' /var/log/mysqld.log | tail -1输出类似:2023-10-27T08:00:00.123456Z 1 [Note] A temporary password is generated for root@localhost: Jqsl&a1!kKd-。记下冒号后面的密码Jqsl&a1!kKd-。
4.2 启动服务与修改root密码
现在可以安全地启动MySQL服务了:
systemctl start mysqld systemctl enable mysqld # 设置开机自启 systemctl status mysqld # 检查运行状态使用临时密码登录,并立即修改密码:
mysql -uroot -p # 输入刚才记下的临时密码登录成功后,MySQL会强制你修改密码才能执行其他操作:
-- 修改root用户密码,请将‘YourNewStrongPassword!123’替换成你自己的强密码。 ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourNewStrongPassword!123'; -- 刷新权限 FLUSH PRIVILEGES; -- 退出 exit;注意事项:MySQL 5.7默认启用了密码强度验证插件
validate_password。如果你设置的密码过于简单,会报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements。你可以临时降低密码策略级别,或者设置一个包含大小写字母、数字和特殊字符的复杂密码。-- 查看密码策略 SHOW VARIABLES LIKE 'validate_password%'; -- 如果必须使用简单密码(仅限测试环境),可以调整策略 SET GLOBAL validate_password_policy=LOW; SET GLOBAL validate_password_length=4; -- 然后再修改密码
4.3 基础安全配置与远程访问
运行MySQL自带的安全配置脚本,这是一个交互式程序,会引导你完成一些安全设置,如移除匿名用户、禁止root远程登录、移除测试数据库等。
mysql_secure_installation根据提示操作即可。它会询问你:
- 输入当前root密码。
- 是否设置密码强度验证插件?(建议Y)
- 是否修改root密码?(如果刚改过,选N)
- 是否移除匿名用户?(建议Y)
- 是否禁止root账户远程登录?(强烈建议Y,生产环境root只允许本地登录)
- 是否移除test测试数据库?(建议Y)
- 是否立即重载权限表?(建议Y)
如果需要允许其他服务器远程连接MySQL(通常用于应用程序连接),不要直接允许root远程登录,而是创建一个具有所需权限的专用用户。
mysql -uroot -p-- 创建一个新用户,例如‘appuser’,并允许从任何主机(‘%’)连接,请使用强密码。 CREATE USER 'appuser'@'%' IDENTIFIED BY 'AnotherStrongPassword!456'; -- 授予所有数据库的所有权限(根据实际需要调整,生产环境建议按库按表授权) GRANT ALL PRIVILEGES ON *.* TO 'appuser'@'%' WITH GRANT OPTION; -- 刷新权限 FLUSH PRIVILEGES;要使远程连接生效,还需要确保MySQL绑定了服务器的公共IP地址,而不是只监听本地回环(127.0.0.1)。编辑MySQL配置文件:
vi /etc/my.cnf在[mysqld]部分,找到bind-address这一行,如果存在则将其值改为0.0.0.0(监听所有网卡),如果不存在则添加一行:
[mysqld] bind-address = 0.0.0.0安全警告:
bind-address = 0.0.0.0和创建‘%’主机用户会使你的MySQL服务暴露在网络上。务必配合防火墙(如firewalld或iptables)限制访问来源IP,并使用强密码。
保存后重启MySQL服务:
systemctl restart mysqld同时,配置防火墙开放3306端口(如果使用firewalld):
firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload5. 配置文件详解与性能调优入门
初始安装后,MySQL会使用一个基础的配置文件/etc/my.cnf。对于生产环境,我们通常需要根据服务器硬件资源(CPU、内存、磁盘)进行一些优化。这里介绍几个关键参数,你可以根据情况调整/etc/my.cnf中的[mysqld]部分。
vi /etc/my.cnf以下是一个针对拥有4核CPU、8GB内存的虚拟机或容器的入门级优化配置示例:
[mysqld] # 基础设置 datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock symbolic-links=0 log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid # 字符集设置,避免中文乱码 character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci # 网络与连接 bind-address = 0.0.0.0 port=3306 max_connections=200 # 最大连接数,根据应用调整 connect_timeout=10 wait_timeout=600 # 非交互式连接超时时间(秒) interactive_timeout=600 # 交互式连接超时时间(秒) # 内存相关配置(关键!) # 为当前连接线程分配的缓冲区大小,默认256K,可适度增大 sort_buffer_size=2M # 关联查询缓冲区大小 join_buffer_size=2M # 线程栈大小,默认192K,一般够用 thread_stack=256K # InnoDB存储引擎配置(MySQL 5.7默认引擎) # InnoDB缓冲池大小,这是最重要的性能参数,通常设置为系统内存的50%-70% innodb_buffer_pool_size=4G # 缓冲池实例个数,建议每个实例不小于1GB,这里设为4 innodb_buffer_pool_instances=4 # 日志文件大小,默认48M,增大可减少checkpoint,提升写性能 innodb_log_file_size=256M # 日志缓冲区大小 innodb_log_buffer_size=16M # 刷新日志的策略。0-每秒刷写一次日志到磁盘并flush;1-每次事务提交都刷写(最安全,性能差);2-每次提交只写OS缓存,每秒flush一次磁盘(推荐折中) innodb_flush_log_at_trx_commit=2 # 刷新脏页的策略,默认是“模糊检查点”,保持默认即可 # innodb_flush_method=O_DIRECT # 如果使用SSD或RAID,可考虑设置为O_DIRECT绕过OS缓存 # 日志与慢查询 # 慢查询日志,用于捕获执行缓慢的SQL,便于优化 slow_query_log=1 slow_query_log_file=/var/log/mysql-slow.log long_query_time=2 # 执行时间超过2秒的查询被记录 # 通用查询日志,记录所有SQL,调试用,生产环境建议关闭(=0)以免产生大量IO general_log=0 # 二进制日志(用于主从复制或基于时间点的恢复) server-id=1 # 服务器唯一ID,主从复制时必需 log_bin=/var/log/mysql/mysql-bin.log expire_logs_days=7 # 二进制日志保留天数 max_binlog_size=100M # 每个binlog文件大小 binlog_format=row # 行模式,最安全 [mysql] default-character-set=utf8mb4 [client] default-character-set=utf8mb4参数调优核心思路:
innodb_buffer_pool_size:这是“内存缓存池”,用来缓存表数据和索引。设置得越大,能缓存的热数据就越多,磁盘IO就越少。这是提升性能最有效的参数。对于8GB内存的机器,设为4G-6G是合理的。- 连接与超时:
max_connections不要设得过高,每个连接都会占用内存。wait_timeout和interactive_timeout用于回收空闲连接,避免连接数堆积。- 日志:开启慢查询日志 (
slow_query_log) 是性能优化的第一步。定期分析慢日志,找出需要优化的SQL。- 二进制日志:如果不需要主从复制或特定时间点恢复,可以关闭 (
log_bin=OFF) 以节省磁盘空间和IO。
修改完配置后,务必重启MySQL服务使配置生效:
systemctl restart mysqld重启后,检查关键参数是否生效:
mysql -uroot -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';" mysql -uroot -p -e "SHOW VARIABLES LIKE 'character_set_server';"6. 常见问题排查与运维技巧
离线安装和后续运维中,你可能会遇到一些问题。这里记录一些典型问题的排查思路。
6.1 安装阶段问题
问题1:安装RPM包时依赖错误
- 现象:
error: Failed dependencies: libxxx.so.5()(64bit) is needed by mysql-community-xxx - 原因:系统缺少某个共享库,或者离线包集合不完整。
- 解决:
- 回到打包机,使用
yum deplist mysql-community-server命令仔细查看依赖树,确保所有依赖包都已下载。 - 在打包机上,通过
yum provides */libxxx.so.5查找提供该库的包,并将其加入离线包目录。 - 在目标服务器上,也可以尝试使用
rpm -ivh --nodeps --force强制安装某个包(不推荐,可能导致运行时错误)。
- 回到打包机,使用
问题2:初始化失败,日志报错“Could not create unix socket lock file”
- 现象:
/var/log/mysqld.log中有类似错误。 - 原因:
/var/lib/mysql目录的权限不对,或者SELinux阻止了操作。 - 解决:
对于生产环境,建议学习并配置正确的SELinux策略,而不是直接关闭。# 确保目录所有权为mysql用户和组 chown -R mysql:mysql /var/lib/mysql # 临时禁用SELinux(生产环境请谨慎,最好配置SELinux策略) setenforce 0 # 或者永久禁用(编辑 /etc/selinux/config,设置 SELINUX=disabled,重启生效)
6.2 启动与连接阶段问题
问题3:MySQL服务启动失败
- 排查步骤:
- 查看详细日志:
journalctl -xe或tail -100f /var/log/mysqld.log。 - 检查端口占用:
netstat -tlnp | grep 3306,看是否被其他进程占用。 - 检查配置文件语法:
mysqld --verbose --help | grep -A 1 -B 1 'my.cnf'可以查看配置文件读取顺序。使用mysqld --defaults-file=/etc/my.cnf --validate-config(MySQL 5.7可能不支持--validate-config,可尝试跳过)或直接注释掉可疑配置行来测试。 - 检查磁盘空间:
df -h,确保/var/lib/mysql所在分区有足够空间。
- 查看详细日志:
问题4:远程客户端无法连接
- 排查步骤(“从内到外”排查法):
- 本地连接测试:在服务器本机执行
mysql -uroot -p,确认MySQL服务本身正常。 - 检查用户权限:登录MySQL,执行
SELECT user, host FROM mysql.user;查看目标用户(如appuser)的host是否是%或特定IP。 - 检查绑定地址:
SHOW VARIABLES LIKE 'bind_address';确认是0.0.0.0。 - 检查服务器防火墙:
firewall-cmd --list-all查看是否开放了3306端口。可以用telnet 服务器IP 3306从客户端测试。 - 检查网络路由和安全组:如果服务器在云上(如AWS, 阿里云),还需要检查云服务商的安全组规则是否允许3306端口入站。
- 本地连接测试:在服务器本机执行
6.3 基础运维命令速查
服务管理:
systemctl start mysqld # 启动 systemctl stop mysqld # 停止 systemctl restart mysqld # 重启 systemctl status mysqld # 查看状态 systemctl enable mysqld # 开机自启 systemctl disable mysqld # 禁用开机自启数据库连接与信息查看:
mysql -u用户名 -p密码 -h主机IP -P端口 mysqladmin -uroot -p status # 查看简要状态 mysqladmin -uroot -p ping # 检查服务是否存活 mysqladmin -uroot -p processlist # 查看当前连接进程备份与恢复(基础):
# 全库备份(逻辑备份) mysqldump -uroot -p --all-databases --single-transaction --routines --triggers --events > /backup/full_backup_$(date +%Y%m%d).sql # 恢复 mysql -uroot -p < /backup/full_backup_20231027.sql注意:
mysqldump是逻辑备份,适合数据量不大或需要跨版本迁移的情况。对于大型数据库,应考虑物理备份(如使用Percona XtraBackup)或文件系统快照。
6.4 性能问题初步定位
如果感觉数据库变慢,可以按以下顺序快速检查:
- 检查当前状态:登录MySQL,运行
SHOW FULL PROCESSLIST;查看是否有长时间运行的查询或大量等待的查询。 - 检查资源使用:在服务器上运行
top或htop,看mysqld进程的CPU和内存占用。使用iostat -x 1查看磁盘IO状况。 - 分析慢查询日志:如果配置了慢查询日志,使用
mysqldumpslow工具或pt-query-digest(Percona Toolkit)进行分析。# 简单的慢日志分析(按总耗时排序) mysqldumpslow -s t /var/log/mysql-slow.log | head -20 - 查看关键状态变量:
SHOW GLOBAL STATUS LIKE 'Threads_connected'; -- 当前连接数 SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%'; -- 缓冲池命中率 SHOW GLOBAL STATUS LIKE 'Questions'; -- 总查询数 SHOW GLOBAL STATUS LIKE 'Slow_queries'; -- 慢查询数
通过这套组合拳,你不仅能成功在离线的CentOS 7上部署好MySQL 5.7,还能建立起基础的运维和问题排查能力。记住,离线环境下的每一步操作都要更谨慎,因为获取额外的工具或信息会更加困难。做好规划,充分测试,保留好你的离线软件包仓库,这些都是保障后续运维顺畅的关键。