news 2026/9/30 17:36:49

CentOS安装MySQL全指南:版本选择、在线/离线部署与故障排查

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CentOS安装MySQL全指南:版本选择、在线/离线部署与故障排查

最近又有人在群里问:CentOS 上装个 MySQL 怎么就这么折腾?装完不是连不上,就是起不来。细问之下,多半是上来就yum install mysql,结果系统塞进去的是 MariaDB,还有人拿着临时密码登不进去,或者配好了远程访问结果 Navicat 疯狂报 SSL 错误。这篇就围绕 Linux(CentOS)安装 MySQL 这件事,把版本选择、在线安装、离线安装、初始化和故障排查完整捋一遍,不管你是给虚拟机装环境、给内网服务器部署,还是准备从 CentOS 7 迁到 Stream 系列,应该都能在里面找到能直接抄的步骤。

我这几年前前后后在 CentOS 7.9、CentOS Stream 8、Stream 9 上都装过不同版本的 MySQL,踩过的坑攒了不少。下面不按教科书讲,就按实际动手顺序来,每一步为什么这么做我都会交代清楚。

1. 选对版本再动手:CentOS与MySQL的兼容性判断

1.1 版本配对:CentOS 7/8/9 与 MySQL 5.7/8.0

很多人栽的第一个跟头,是根本没搞清自己的 CentOS 和 MySQL 版本之间的对应关系。CentOS 7 系列的软件包标识是el7,CentOS Stream 8 是el8,CentOS Stream 9 是el9。MySQL 官方 Yum 源对每个大版本都提供了独立的 rpm 包,下载地址里的el7、el8、el9后缀就是给你区分用的,下错了版本,yum 会直接拒绝安装或者报依赖冲突。

再一个关键问题是选 5.7 还是 8.0。CentOS 7 默认的 glibc 是 2.17,MySQL 8.0 官方要求 glibc 2.17 以上,所以可以装。但如果你手头是跑了很多年的老业务,数据库里有大量旧 SQL_MODE 依赖,我建议老老实实用 5.7,兼容性省心得多。新项目直接上 8.0,窗口函数、公用表表达式、默认 utf8mb4 这些能力都是实打实的优势。

MySQL 5.7 官方支持已经在 2023 年 10 月结束,安全更新不再提供。如果你是在新环境里做方案选型,优先考虑 8.0;除非有明确的兼容性约束,否则不要逆着趋势走。

1.2 装机前必须做掉的三件事

安装之前别急着敲命令,花三分钟做掉下面三件事,后面能少折腾一晚上。

第一件事:确认系统版本。用cat /etc/redhat-release看具体版本号,顺便uname -m确认架构是 x86_64 还是 aarch64。别小看这个,我见过有人在 ARM 架构的机器上硬装 x86_64 的 MySQL 包,装到一半报Exec format error,白忙一场。

第二件事:检查系统里有没有自带的 MariaDB。CentOS 官方源里的mysql包实际指向的是 MariaDB,很多教程说yum install mysql就是因为它。先跑一下:

rpm -qa | grep -iE 'mariadb|mysql'

如果输出里有mariadb-libs之类的包,最好先卸载掉,不然后续装 MySQL 官方 rpm 包时大概率会撞conflict:

systemctl stop mariadb systemctl disable mariadb rpm -e --nodeps mariadb-libs

第三件事:确认网络和磁盘。在线安装要确保能访问repo.mysql.com,curl -I https://repo.mysql.com看一眼通不通。磁盘方面,df -h确认根分区或数据目录所在分区至少留出 5G 以上空间,MySQL 初始化后光系统文件就要几百 MB,数据量大了之后更吃空间。

检查项命令目的
系统版本cat /etc/redhat-release确认 el7/el8/el9,选对源包
已有数据库rpm -qa | grep -iE 'mariadb|mysql'避免 rpm 包冲突
网络连通curl -I https://repo.mysql.com判断能否用在线源
磁盘空间df -h预留足够安装空间

2. 在线安装:用官方Yum源一次装好

2.1 配置 MySQL 官方 Yum 源

在线安装最稳健的方式是用 MySQL 官方提供的 Yum Repository,它会把mysql-community-server、mysql-community-client等包的安装源配置好,不需要自己去拼各种依赖。

先下载官方的源 rpm 包并安装。CentOS 7 用el7,Stream 8 用el8,Stream 9 用el9:

# CentOS 7 示例 wget https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm rpm -ivh mysql80-community-release-el7-7.noarch.rpm

安装完源之后验证一下:

yum repolist enabled | grep mysql

正常情况下能看到mysql80-community这个仓库是 enabled 状态。如果yum repolist输出为空,大概率是 GPG key 导入有问题,可以手动导入:

rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

2.2 切换 MySQL 版本号

官方源默认启用的是 MySQL 8.0 的仓库,如果你需要装 5.7,得手动切换。用yum-config-manager命令操作:

yum -y install yum-utils yum-config-manager --disable mysql80-community yum-config-manager --enable mysql57-community

切完再看一眼仓库状态:

yum repolist enabled | grep mysql

确认mysql57-community是 enabled 的再继续。这里有个小坑:CentOS Stream 9 的官方源里已经没有 mysql57-community 了,最小版本只到 8.0,硬要切 5.7 的话 yum 会直接报错说找不到这个仓库。

2.3 安装、启动、拿临时密码

仓库配置好之后,安装就一条命令的事:

yum -y install mysql-community-server

安装完成后启动服务,并设置开机自启:

systemctl enable --now mysqld

MySQL 首次启动时会自动初始化数据目录,并生成一个临时 root 密码。用下面命令把它捞出来:

grep 'temporary password' /var/log/mysqld.log

看到类似这样的输出:

[Note] A temporary password is generated for root@localhost: xxxxxxxx

把密码复制保存好,下一步要用。

mysqld首次启动的初始化过程是 8.0 之后引入的机制:数据目录为空时,mysqld 会自动创建系统表并生成随机 root 密码。以前 5.6 时代还得自己跑mysql_install_db,现在已经自动化了。如果你在日志里找不到临时密码,先检查是不是因为数据目录之前已经初始化过,那样不会生成新密码。

3. 离线安装:给内网服务器塞MySQL的两种方案

3.1 方案一:rpm 包离线安装

内网服务器没法访问外网,这是运维里特别常见的场景。离线安装的核心思路是:在一台能联网的机器上下载好所有 rpm 包,然后搬到内网机器上安装。

推荐用yumdownloader或者yum --downloadonly把依赖一并拉下来:

# 联网机器上执行 yum -y install yum-utils mkdir -p /root/mysql-rpm yumdownloader --resolve --destdir=/root/mysql-rpm mysql-community-server

--resolve参数会把所有依赖包都下下来,拷到内网机器上后直接:

rpm -ivh /root/mysql-rpm/*.rpm

如果缺依赖,rpm 会明确提示缺哪个包。MySQL 8.0 常见的依赖有libaio、numactl-libs、perl、openssl等,这些包在内网机器的系统镜像里基本都能找到,用yum install从本地光盘源或内网镜像源装掉即可。

用 rpm 离线安装时还有一个典型的坑:如果系统里已经装了mariadb-libs,安装mysql-community-libs时会产生file conflict,提示:

file /usr/lib64/libmysqlclient.so.18 conflicts...

解决办法是先把 maria 相关的包卸掉再装,但卸之前一定要确认系统里没有别的应用依赖它。

3.2 方案二:tar.xz 通用二进制包

另一种离线方式是用 MySQL 官方提供的通用二进制包,也就是 tar.xz 压缩包。这种方式的最大优势是路径完全可控,适合自定义数据目录、做多实例部署、或者不想被 rpm 管理策略限制的场景。

去 MySQL 官网下载mysql-8.0.xx-linux-glibc2.17-x86_64.tar.xz(x86 架构还是 aarch64 别选错),然后执行:

tar -xf mysql-8.0.xx-linux-glibc2.17-x86_64.tar.xz -C /usr/local/ mv /usr/local/mysql-8.0.xx /usr/local/mysql

接着创建 mysql 用户、准备数据目录:

useradd -r -s /sbin/nologin mysql mkdir -p /data/mysql chown -R mysql:mysql /data/mysql

初始化数据目录,注意--initialize-insecure表示生成空密码的 root 账号,内网环境方便调试;如果需要和 rpm 一样的随机密码机制,用--initialize:

/usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql

然后手写一份/etc/my.cnf:

[mysqld] basedir=/usr/local/mysql datadir=/data/mysql socket=/tmp/mysql.sock pid-file=/var/run/mysqld/mysqld.pid port=3306 user=mysql

最后启动。可以通过 systemd 管理,也可以简单点用官方自带的mysqld_safe:

/usr/local/mysql/bin/mysqld_safe --user=mysql &

3.3 两种方案怎么选

对比项rpm 包离线tar.xz 二进制
依赖处理rpm 自动处理,冲突更少完全手动,路径自己控
数据目录默认/var/lib/mysql自定义路径灵活
升级方式yum update直接升级换软链重启,回退也容易
systemd 集成安装即自带服务要手写 service 文件
多实例部署较麻烦很方便

我的建议:没人维护的测试环境用 rpm,省事;生产环境如果对路径、目录规划有要求,或者打算一个机器跑多个 MySQL 实例,用 tar.xz 通用二进制包更合适。rpm 装完后照样能改datadir,但改完要处理 SELinux 标签,反而多出不少事。

4. 初始化与安全加固:拿到临时密码后的正规操作

4.1 修改 root 密码,顺便处理密码强度策略

拿到临时密码后,第一件事就是登进去改密码。

mysql -uroot -p

然后执行:

ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStrongPassword2024!';

如果新密码太简单,MySQL 8.0 默认开启的validate_password插件会直接拒绝。想调整策略的话:

SHOW VARIABLES LIKE 'validate_password%';

常见的变量是这么几个:

validate_password.policy -> MEDIUM validate_password.length -> 8

测试环境想放宽一点,把 policy 改为 LOW 即可:

SET GLOBAL validate_password.policy=LOW;

注意SET GLOBAL只对当前实例生效,重启后失效。建议把配置写进/etc/my.cnf:

[mysqld] validate_password.policy=LOW

个人观点:即使是在内网,root 密码也别用 123456 这种。MySQL 8.0 的密码策略是保护你的第一道防线,真被扫到弱密码,丢数据是分分钟的事。

4.2 建业务账号和远程连接(含防火墙)

生产环境里不应该用 root 去连库,要建独立的业务账号。本着最小权限原则,只给够用的权限:

CREATE USER 'app'@'192.168.10.%' IDENTIFIED BY 'AppPassword2024!'; GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app'@'192.168.10.%'; FLUSH PRIVILEGES;

账号里的192.168.10.%意思是只允许这个网段访问。如果你只允许某一台机器,就写死具体 IP。如果图省事写成'app'@'%',等于所有机器都能连,内网环境风险还是不小的。

MySQL 默认只监听本机回环地址,也就是bind-address=127.0.0.1,想要远程连接必须改配置:

[mysqld] bind-address=0.0.0.0

然后重启服务。这一步之后还有一层防火墙,CentOS 7 及以上默认跑 firewalld:

firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload

最后测试远程连接,客户端命令行或 Navicat 都行。如果你数据库前面挂了连接池(比如 HikariCP 或者 Druid),记得检查连接池的wait_timeout和max_connections两个参数,连接池空闲连接被服务端回收后,客户端会报Connection has been closed。

还有一个兼容性问题值得单独说:MySQL 8.0 默认的认证插件是caching_sha2_password,老版本的 Navicat 或旧版 JDBC 驱动会报错:

Authentication plugin 'caching_sha2_password' cannot be loaded

两个解决办法:升级客户端驱动是首选;如果客户端暂时升不了,可以把账号的认证插件改为老的mysql_native_password:

CREATE USER 'app'@'192.168.10.%' IDENTIFIED WITH mysql_native_password BY 'AppPassword2024!';

但这只是过渡方案,新代码尽量切新驱动。

4.3 字符集、时区,以及一个默认值0的小坑

装完 MySQL 后建议立刻检查字符集配置:

SHOW VARIABLES LIKE 'character_set%';

如果character_set_server不是utf8mb4,赶紧改。utf8mb4 和 utf8 的区别在于:utf8 在 MySQL 里最多 3 字节,存不了 emoji 和部分生僻字;utf8mb4 是完整的 4 字节 Unicode。哪怕业务现在用不到,先配上不会有坏处。

修改/etc/my.cnf:

[mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_0900_ai_ci

8.0 的默认排序规则推荐utf8mb4_0900_ai_ci,5.7 没有这个规则,用utf8mb4_general_ci即可。

注意:如果一个库已经建好了,只改全局字符集不会影响已有的表和字段。需要手动转换:ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

时区也是一个常见坑。国内服务器默认时区是 CST,但 MySQL 系统默认是 UTC,业务日志、统计报表时间很容易差 8 小时。在my.cnf里加上:

[mysqld] default-time-zone='+08:00'

JDBC 连接串里也可以加serverTimezone=Asia/Shanghai双保险。

有一个和“默认值”相关的细节我也一并说了。MySQL 建表时如果想让某个字段默认填 0,写DEFAULT 0就行。但注意:日期时间类型不能随便设默认值,8.0 里datetime DEFAULT CURRENT_TIMESTAMP这个用法很常见,但如果你想设datetime DEFAULT '0000-00-00 00:00:00',默认会失败并报Invalid default value,需要在sql_mode里临时去掉NO_ZERO_DATE才能允许。这种需求实际很少,不要为了图省事牺牲完整性约束。

5. 安装故障排查:几个经典坑的完整链路

5.1 服务器起不来:日志、权限、SELinux 一条线

如果你执行systemctl start mysqld后服务一直起不来,先别急着重启,按链路排查。

第一步,看日志:

journalctl -u mysqld -n 50 tail -n 30 /var/log/mysqld.log

/var/log/mysqld.log是 MySQL 自己的错误日志,绝大多数启动失败的根因都在这里。日志末尾会有[ERROR]开头的记录,直接定位问题。

最常见的失败原因是数据目录权限不对。比如你手动改了datadir=/data/mysql,但目录属主不是 mysql:

chown -R mysql:mysql /data/mysql chmod 750 /data/mysql

把权限修正后重启systemctl restart mysqld基本能解决。

第二个容易被忽略的是 SELinux。CentOS 7 默认开启 SELinux,mysqld 默认只被允许绑定到某些端口和访问某些路径。当你自定义了数据目录,或者改了端口,SELinux 会拦着不让启动。

查看状态:

sestatus

临时关闭验证一下:

setenforce 0

如果临时关闭后 mysqld 能正常启动,说明确确实实是 SELinux 在作祟。生产环境不建议永久关闭 SELinux,更规范的做法是把规则加进去:

semanage port -a -t mysqld_port_t -p tcp 3306 semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?" restorecon -Rv /data/mysql

如果没装 semanage:

yum -y install policycoreutils-python-utils

第三个原因可能是my.cnf配置写错。比如pid-file指定的目录不存在,或者socket路径写成了无权限的位置。可以用这个命令检查 mysqld 实际会加载哪些配置:

mysqld --print-defaults

5.2 客户端连不上:命令找不到、Socket、SSL 报错

客户端连接问题更常见。先看命令是否找得着:

mysql: command not found

rpm 方式安装的 MySQL 客户端通常在/usr/bin/mysql;tar.xz 方式的话,mysql 二进制在/usr/local/mysql/bin/mysql。后者要加软链:

ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql

或者把路径写进/etc/profile的 PATH。

接着看 Socket 报错:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket'/tmp/mysql.sock'

出现这个,要么是服务没起来,要么是 socket 路径和你客户端配置的不一致。检查/etc/my.cnf里[mysqld]和[client]段的 socket 路径是否一致,不一致就改成同一个。

还有一个高频报错是 SSL 相关的:

ERROR 2026 (HY000): SSL connection error: SSL_CTX_set_default_verify_paths failed

或者 JDBC 连接时:

SSL connection error: unknown protocol

原因是 MySQL 5.7 之后默认启用 SSL,但内网环境很少有正规证书,客户端在验证自签名证书时失败。测试环境临时绕过的方法:

mysql -uroot -p --ssl-mode=DISABLED

JDBC 连接串则这样:

jdbc:mysql://ip:3306/db?useSSL=false&allowPublicKeyRetrieval=true

这里要强调一下:生产环境不要直接关 SSL。内网低信任域,或者涉及敏感数据的场景,建议配置正式证书而不是图省事关闭加密。自签名的证书只要客户端和服务端都认,也能保障链路加密。

还有一类 Navicat 报错是前文提到的认证插件问题,报 1251 错误码。老版本 Navicat 认mysql_native_password,不认 8.0 默认的caching_sha2_password,处理方式上面写过了,升级客户端或改认证插件二选一。

5.3 忘记 root 密码的救援操作

运维的人一定会碰上这种情况:root 密码忘了,或者同事把 root 密码改没记。MySQL 提供了一个维护模式入口。

在/etc/my.cnf的[mysqld]段加一行:

[mysqld] skip-grant-tables

重启服务:

systemctl restart mysqld

这时候不需要密码就能登进去:

mysql -uroot

进入后先刷新权限:

FLUSH PRIVILEGES;

注意 8.0 在 skip-grant-tables 模式下,如果不先FLUSH PRIVILEGES,ALTER USER会被拒绝。刷新后重设密码:

ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPassword2024!';

改完删掉my.cnf里的skip-grant-tables,重启服务恢复正常。这个过程要小心:skip-grant-tables模式下,所有用户都能免密访问,谁都能登进你的库,操作完务必立刻移除。

排查故障的最后再说一个我自己很受益的习惯。装好 MySQL 后,别急着把业务接进来,先花十分钟做一件事:在my.cnf里把log-bin开起来,全量备份脚本顺手配一个 cron。MySQL 的 binlog 平时不显山不露水,真遇到误删数据时,binlog 回放就是救命稻草。我第一次在生产库上犯误删错误的时候,靠的就是 binlog,从那以后装任何 MySQL 实例我都默认开 binlog。这个操作成本极低,收益却极高,强烈建议你下次装完就顺手做了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 17:36:04

Strix 实操指南:从安装到第一份渗透测试报告

Strix 实操指南:从安装到第一份渗透测试报告项目卡片 项目:Strix[1]状态:v1.0.4 / 35.8k Star / Apache 2.0 / Python一句话判断:一行命令启动 AI 渗透测试,自动跑侦察、漏洞验证、PoC 生成,输出可复现的安…

作者头像 李华
网站建设 2026/9/30 17:35:58

Flutter鸿蒙应用瘦身:asset_opt资源优化全流程实践

直接说结论:Flutter 应用想要在鸿蒙(HarmonyOS)生态里站住脚,资源体积这道坎绕不过去。我之前把 iOS/Android 双端都在用的asset_opt资源优化库往鸿蒙构建链路里硬搬,一开始完全是被现实逼的——HAP 打出来 80 多 MB&a…

作者头像 李华
网站建设 2026/9/30 17:35:10

园区网络设计实战:三层架构、冗余与接入安全配置指南

简介:这份PDF是一份面向高校校园网及大型园区网络规划场景的完整组网设计方案,以西南交通大学校园网为背景,围绕网络架构、设计原则、应用需求、设备选型与安全策略展开,适合网络工程师、系统集成人员及网络专业学生参考。资源共1…

作者头像 李华
网站建设 2026/9/30 17:27:57

私有化部署的落地检查:镜像仓库、备份副本、恢复演练

做助贷系统的团队,交付单上通常只写一句"已完成私有化部署"。这句话在工程上没法核——它给的是一个结论,没有留下可以对照的中间物。结论核不动,中间物可以。环境装起来之后,至少有三个中间物是能单独查的:…

作者头像 李华
网站建设 2026/9/30 16:56:38

Sonnet 5.5 发布:打工人的新旗舰,性能逼近Opus 5.5,价格只要一半

Claude Sonnet 5.5 终于发了! 前不久发的 Claude Opus 5.5 毫无疑问是我最想用的模型,各方面都是最优的,但问题是太贵了。 且非常的不经用,才发几天我就把它一周额度蹬完了,后面一直靠着 Codex 在苦撑,所…

作者头像 李华
网站建设 2026/9/30 16:55:10

OpenGame路线图前瞻:AI游戏生成框架的下一步走向何方?

OpenGame路线图前瞻:AI游戏生成框架的下一步走向何方? 【免费下载链接】OpenGame OpenGame: Open Agentic Coding for Games 项目地址: https://gitcode.com/gh_mirrors/op/OpenGame OpenGame 是一个开源的 AI 游戏生成框架(Agentic C…

作者头像 李华