1. 装 MySQL 这件事,为什么值得单独写一篇
我这些年帮人排查过不少 MySQL 装不上、起不来、连不上的问题,最后发现七成以上都出在安装之前的环境认知和装完之后的初始化配置上,真正卡在安装命令本身的反而不多。尤其在 CentOS 上,很多人习惯性yum install mysql一把梭,结果装出来一个 MariaDB,或者装完了mysqld根本不在服务列表里,又或者启动成功了却怎么都登不进去——这些都是高频问题。
这篇就围绕 CentOS 下安装 MySQL 的完整链路来讲,覆盖常用版本(以 5.7 和 8.0 为主)、yum 源安装、初始化配置、远程授权、常见坑排查,最后补充卸载重装和生产环境建议。文章不是只给命令,还会解释每一步在干什么、为什么要这么干——因为单纯复制粘贴的人,十有八九会在下一步踩更深的坑。
适合三类读者:刚接触 Linux 想在自己虚拟机里把 MySQL 跑起来的初学者、公司内网需要快速部署 MySQL 的运维同事、以及因为 MySQL 起不来或连不上而正在搜排查方案的人。保证你照着走完,至少能拿到一个可用、稳定、知道怎么维护的实例。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 安装前的环境检查:这些前置问题不解决,后面全是坑
2.1 先看清楚你的 CentOS 是哪个版本
CentOS 7 和 CentOS 8 以及早期的 CentOS 6,在安装 MySQL 时的源配置、命令习惯完全不同。很多时候"照着网上教程操作失败"就是因为教程写的系统版本和你实际用的不一样。
查看系统版本用:
bash复制cat /etc/redhat-release
# 或者
rpm -q centos-release
我在实际工作中见过的最典型情况:有人在 CentOS 8 上使用yum install mysql-community-server,结果找不到包;还有人在 CentOS 7 上用 dnf 命令,结果报错 command not found。CentOS 7 默认用的是 yum,CentOS 8 支持 dnf 但 yum 命令通常也兼容,CentOS 6 则务必注意它已经相当老旧,很多软件的安装方式都和其他版本不同。
CentOS 7 是当前存量用户最多、教程生态最成熟的版本,也是本文档主力讲解的对象。CentOS 8 的部分差异我会在相关位置专门标注。
2.2 检查是否已经装过 MySQL 或 MariaDB
CentOS 7 默认软件源里带的是 MariaDB,很多人执行yum install mysql装到的其实是 MariaDB 的客户端,服务器端根本不在里面。这是新手最容易困惑的地方:明明"装了 MySQL",但服务名是mariadb,用的数据目录也是/var/lib/mysql,命令行工具却写着 MariaDB。
安装新环境前建议先检查:
bash复制rpm -qa | grep -E 'mysql|mariadb'
systemctl status mysqld
systemctl status mariadb
如果发现:
- 存在 MariaDB 相关包但没启动,建议
yum remove mariadb-libs -y(注意:这个包可能被其他工具依赖,移除前需要确认不影响系统组件,比如 Postfix 之类) - 存在旧版 MySQL 但不确定要不要保留,先备份数据再处理,不要随手删
- 什么输出都没有,说明是干净环境,继续往下走
这里有个关键经验:yum remove mariadb-libs 在 CentOS 7 上经常会连带把 postfix 等依赖它 libs 的软件也移除掉,如果这台机器要用来发邮件或已经装了相关依赖,移除时需要加 --noautoremove 或在确认无影响后再操作。生产环境更保险的做法是留着 Mariadb-libs 不删,直接强制安装 MySQL 的兼容库(下述 yum 源安装方式本身会处理依赖冲突)。
2.3 保持系统时间和服务状态正常
MySQL 对系统时间比较敏感,特别是做主从复制、定时任务、日志分析时,时间不准会影响判断。安装前最好做一次:
bash复制date
# 如果时间偏差明显
yum install ntpdate -y
ntpdate ntp.aliyun.com
另外确认网络能通,因为无论用官方 yum 源还是国内镜像源都需要联网。可以用curl -I https://mirrors.tuna.tsinghua.edu.cn快速验证外网连通性。
提示:刚装完的 CentOS 7 默认可能没有开启网络,
ping baidu.com超时,但ping 网关IP通。这种情况检查 /etc/sysconfig/network-scripts/ifcfg-ens33 里的 ONBOOT 是否为 yes。也就是热搜里很多人遇到的"vm中桥接模式centos网络激活失败"类似问题,这里先不展开,后面远程连接部分再细说网络排查。
3. 官方 yum 源安装:最稳的一条路,附 5.7 与 8.0 差异对比
3.1 为什么推荐用官方 yum 源而不是通用源
社区里安装 MySQL 的姿势大体有四种:官方 yum 源安装、第三方源(如 remi、webtatic)、二进制免编译包解压安装、源码编译安装。我个人的推荐顺序是:官方 yum 源 > 二进制包 > 第三方源 > 源码编译。
理由很直接:官方 yum 源能自动处理依赖、注册 systemd 服务、升级时不用手动替换文件,而且版本干净。源码编译适合对参数有特殊定制需求的场景,但对多数人来说是浪费时间和埋坑,光是编译依赖就能让你折腾一下午。二进制包适合离线内网环境,但初始化配置要手动处理的细节偏多。
第三方源最大的问题是兼容性风险:不同源对同一个包的编译参数可能不同,而 MySQL 对 glibc 版本、libaio、numactl 这些底层库有依赖要求,一旦不满足,启动时会出现诡异的报错。
3.2 安装 MySQL 8.0(完整步骤)
MySQL 从 5.7 升级到 8.0 后,默认字符集变为 utf8mb4,默认认证插件变为 caching_sha2_password,而且移除了 query cache,这些变化对老项目迁移有影响。新装环境直接用 8.0 是未来的趋势,下面是完整操作。
先下载并安装官方 yum 源 RPM 包:
bash复制yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
这里需要注意,el7 代表适用于 CentOS 7 / RHEL 7。如果你用的是 CentOS 8,需要把地址换成对应的 el8 版本,通常形如 mysql84-community-release-el8-x.noarch.rpm。下错版本源,后面安装时大概率会报 "package mysql-community-server requires ..." 之类的依赖错误。
检查源的启用状态:
bash复制yum repolist enabled | grep mysql
正常情况下能看到 mysql-connectors-community、mysql-tools-community、mysql80-community 三个源。如果想装 5.7,需要先禁用 8.0 源再启用 5.7 源(后面细讲)。
接着安装:
bash复制yum install -y mysql-community-server
启动并设置开机自启:
bash复制systemctl start mysqld
systemctl enable mysqld
systemctl status mysqld
MySQL 8.0 安装完会自动生成一个临时 root 密码,存放在错误日志中:
bash复制grep 'temporary password' /var/log/mysqld.log
你会看到类似 A temporary password is generated for root@localhost: xxxxxxxx。立刻用它登录:
bash复制mysql -uroot -p
进入 MySQL 后必须尽快修改密码,否则无法执行任何其他操作:
sql复制ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStrongPass_123';
注意 MySQL 8.0 的默认密码策略是 validate_password 组件,要求密码至少 8 位,且包含大小写字母、数字和特殊字符。很多人第一次装完在这里卡住,提示 ERROR 1819 (HY000): Your password does not satisfy the current policy requirements,就是这个原因。
3.3 安装 MySQL 5.7(迁移场景和旧项目需要)
尽管 8.0 已经发布多年,但存量项目里 5.7 依然有大量存在。如果你的项目还在用老版本驱动、老版本主从配置或某些不兼容 8.0 的 ORM 框架,老老实实用 5.7 是更稳妥的选择。
首先要安装官方源,然后手动切换启用版本:
bash复制yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
这个源文件里其实同时包含了 5.7 和 8.0 的源定义,只是默认启用了 8.0。可以通过手动修改仓库配置文件来切换:
bash复制yum install -y yum-utils
yum-config-manager --disable mysql80-community
yum-config-manager --enable mysql57-community
或者直接编辑 /etc/yum.repos.d/mysql-community.repo,把 mysql80 的 enabled 改为 0,把 mysql57 的 enabled 改为 1。推荐用 yum-config-manager,不用手改文件,不容易出错。
确认之后重新安装:
bash复制yum repolist enabled | grep mysql
yum install -y mysql-community-server
5.7 首次启动后的临时密码同样在日志里查:
bash复制grep 'temporary password' /var/log/mysqld.log
然后登录并修改密码。5.7 的默认密码策略和 8.0 类似,新的 5.7.6+ 版本已经内置 validate_password 插件,密码复杂度要求同样比较严格。
3.4 两种版本的核心差异对比
我在实际切换中总结过一张对比表,方便你做版本决策:
| 对比项 | MySQL 5.7 | MySQL 8.0 |
|---|---|---|
| 默认字符集 | latin1(需手动改 utf8mb4) | utf8mb4 |
| 默认认证插件 | mysql_native_password | caching_sha2_password |
| 查询缓存 | 可用 | 已移除 |
| 窗口函数 | 不支持 | 支持 |
| 通用表表达式(CTE) | 不支持 | 支持 |
| 默认临时密码生成 | 是,日志可查 | 是,日志可查 |
| JSON 功能 | 基础 | 增强 |
| 对老客户端兼容性 | 好 | 差(老客户端连不上) |
特别是最后一点,PHP 5.x 的老项目连 MySQL 8.0 会报 "The server requested authentication method unknown to the client",就是因为驱动不支持 caching_sha2_password。所以在选版本前,先确认你项目里的驱动版本和框架兼容性。
4. 初始化配置的必踩之处:密码策略、字符集、远程访问授权
4.1 修改 root 密码策略(只在需要时做)
默认密码策略对安全性敏感的场景是好事,但对开发环境、测试环境来说就很烦。如果你确定这台机器只在内网用,可以调低策略:
sql复制SHOW VARIABLES LIKE 'validate_password%';
在 MySQL 8.0 中,要修改策略参数需要用 SET GLOBAL:
sql复制SET GLOBAL validate_password.policy = LOW;
SET GLOBAL validate_password.length = 6;
注意 8.0 的参数名是带点的形式,5.7 则是下划线形式(validate_password_policy 和 validate_password_length)。改完后退出重登即可生效。重启数据库后这些设置会恢复默认值,如果想永久生效,需要写进配置文件,但这属于进阶内容,开发环境一般不折腾。
如果你确实希望彻底关闭密码插件(比如纯内网测试机),可以在 /etc/my.cnf 的 [mysqld] 段加:
ini复制validate_password = OFF
然后在 MySQL 里卸载插件组件,但我不建议生产环境这么做。
4.2 设置字符集和排序规则
很多中文乱码问题都根植于安装时的默认字符集。5.7 默认是 latin1,必须在安装完成后立刻确认和修改。MySQL 8.0 默认是 utf8mb4,但为了统一和保险,仍然建议在配置文件里显式声明。
编辑 /etc/my.cnf,在 [mysqld] 段下追加:
ini复制character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
skip-character-set-client-handshake
然后在 [client] 段(没有就新建)加:
ini复制default-character-set = utf8mb4
重启 MySQL:
bash复制systemctl restart mysqld
登录后用以下 SQL 验证:
sql复制SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';
重点关注 character_set_server 和 character_set_database 都是 utf8mb4 即可。还有一个网站开发中常见的坑:表连接用的排序规则不统一会导致关联查询报 "Illegal mix of collations"。如果你在建表时统一使用 utf8mb4_general_ci,基本能避开。
4.3 创建应用账号和远程访问授权
root 默认只允许 localhost 连接,而且很多人直接在 root 上开远程权限是非常危险的习惯。正规做法是创建专用账号,只给最小权限。
比如给应用创建一个账号:
sql复制CREATE USER 'appuser'@'192.168.1.%' IDENTIFIED BY 'AppPass_123';
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'appuser'@'192.168.1.%';
FLUSH PRIVILEGES;
这里 '192.168.1.%' 表示只允许 192.168.1 网段的主机访问。如果你不知道应用机器的 IP 或者网段变动频繁,可以用 'appuser'@'%',但这是四类授权里最不安全的使用方式,建议配合防火墙做网段限制。
如果确实需要远程访问 root(很多开发环境图省事),可以执行:
sql复制GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'YourStrongPass_123' WITH GRANT OPTION;
但这句话等同于给整个网络打开了管理员入口,风险自行承担。我的建议是:任何情况下都不要给 root 开远程,尤其是数据库服务器有公网 IP 的时候,你这等于在公网上挂了个裸奔的管理后台。
4.4 3306 端口和监听地址确认
MySQL 默认监听 3306 端口。安装完可以检查一下监听状态:
bash复制netstat -tlnp | grep 3306
# 或者
ss -tlnp | grep 3306
如果只监听了 127.0.0.1,说明配置文件里 bind-address 限制了本地访问。需要远程连接时,在 /etc/my.cnf 的 [mysqld] 段加一行:
ini复制bind-address = 0.0.0.0
然后重启。这个配置同时也要配合防火墙放行端口,否则外面依然连不上(下一节专门讲防火墙)。
5. 装好了却连不上:防火墙、SELinux 和网络连通性排查
5.1 先从客户端和服务端两头判断
遇到"远程连不上 MySQL"这个问题,90% 都不是 MySQL 本身的问题,而是网络层被挡了。排查时有固定顺序:
第一步,看 MySQL 进程是否在监听所有网卡:
bash复制ss -tlnp | grep 3306
如果是 127.0.0.1:3306,表示只监听本地,需要按 4.4 节修改 bind-address。
第二步,在远端机器上用 telnet 测试端口通不通:
bash复制telnet 192.168.x.x 3306
# 或者用 nc
nc -vz 192.168.x.x 3306
如果不通,问题在防火墙、SELinux 或网络链路。
第三步,在服务器本机上用 mysql 命令测试本地登录是否正常:
bash复制mysql -uappuser -p -h 127.0.0.1
如果本地能连、远程连不上,基本就是防火墙或 SELinux 的锅。
5.2 防火墙配置:CentOS 7 的 firewalld 操作
CentOS 7 默认使用 firewalld。查看状态:
bash复制systemctl status firewalld
放行 3306 端口有两种方式:
bash复制firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload
或者只针对特定来源 IP 放行(更推荐):
bash复制firewall-cmd --zone=public --add-rich-rule='rule family=ipv4 source address=192.168.1.100 port port=3306 protocol=tcp accept' --permanent
firewall-cmd --reload
查看放行结果:
bash复制firewall-cmd --list-all
这里特别说明一个常见误区:很多人以为执行了 firewall-cmd --add-port=3306/tcp 就放开了,但没加 --permanent 时重启防火墙就失效。如果你改过临时规则后发现重启后又连不上,就是这个原因。
如果测试环境实在不想折腾防火墙,可以直接停掉:
bash复制systemctl stop firewalld
systemctl disable firewalld
但生产环境这么干,基本等于把数据库裸奔在网络上,强烈不建议。
5.3 SELinux 可能是那个隐蔽的拦路虎
CentOS 7 默认开启 SELinux,状态是 enforcing。SELinux 对 MySQL 的网络监听和文件访问都有约束,而且它的拦截日志不像防火墙那么直观,经常被忽略。
临时验证是不是 SELinux 的问题,可以先设为 permissive:
bash复制setenforce 0
然后再次从远程连接 MySQL。如果通了,说明就是 SELinux 的规则在拦截。永久性方案是把 MySQL 端口加入 SELinux 放行列表:
bash复制yum install -y policycoreutils-python
semanage port -a -t mysqld_port_t -p tcp 3306
注意如果你的 MySQL 改了端口,比如用了 3307、3308,也要用同样的方法把对应端口加进去。semanage 在某些最小化安装的 CentOS 上可能没有,需要先安装 policycoreutils-python 这个包,否则执行时找不到命令。
查看当前 SELinux 端口上下文:
bash复制semanage port -l | grep mysqld
如果看到 mysqld_port_t 对应的端口列表里有 3306,就说明放行成功了。
5.4 还有一类常见问题:虚拟机的网卡和网络模式
这个话题在热搜里出现频率非常高:VMware 里桥接模式 CentOS 网络激活失败。多数情况下不是 MySQL 的问题,而是虚拟机的网络基础没配好,导致你根本无法 ping 通服务器,更不用说连 MySQL。
如果你是在虚拟机里装的 CentOS,并打算用宿主机或其他机器连接 MySQL,建议优先用桥接模式或自定义 NAT 端口转发。桥接模式下,虚拟机需要和宿主机在同一网段且没有 IP 冲突。
检查虚拟机 IP:
bash复制ip addr
修改网卡配置后需要重启网络:
bash复制systemctl restart network
或者更符合故障排查习惯的逐步操作:
bash复制ifdown ens33 && ifup ens33
网卡设备名可能是 eth0、ens33、ens192,取决于 CentOS 版本和虚拟化平台。如果 systemctl restart network 报错,通常是 NetworkManager 和 network 服务冲突,最直接的办法是把 NetworkManager 停掉并禁用:
bash复制systemctl stop NetworkManager
systemctl disable NetworkManager
systemctl restart network
这些做完之后,再回到 5.1 节的顺序从端口连通性开始验证。
6. 常见启动失败和数据目录问题深入排查
6.1 mysqld 启动报错的日志分析路径
MySQL 安装完启动失败是另一个高频问题。很多人拿到报错就搜"Can't connect to local MySQL server",其实正确做法是先看日志。
MySQL 的日志位置默认在 /var/log/mysqld.log,但有些版本可能是 /var/log/mysql/mysqld.log。查看最近 30 行:
bash复制tail -n 30 /var/log/mysqld.log
我梳理过常见的启动失败报错及对应处理方向:
| 报错关键词 | 可能原因 | 处理方向 |
|---|---|---|
| Can't find messagefile | 安装不完整或路径不对 | 重装 mysql-community-server |
| [ERROR] Aborting | 常见于配置错误后的连锁反应 | 查看更前面的日志,往往是 /etc/my.cnf 某参数不合法 |
| Directory /var/lib/mysql doesn't exist | 数据目录缺失 | 手动创建并授权:mkdir -p /var/lib/mysql && chown mysql:mysql /var/lib/mysql |
| [ERROR] InnoDB: Unable to lock ./ibdata1 | 已有 mysqld 进程在运行 | 检查进程:ps aux | grep mysqld,kill 后重启 |
| Access denied for user 'root'@'localhost' | 密码错误或插件不匹配 | 用 --skip-grant-tables 重置后恢复 |
| [ERROR] unknown variable | my.cnf 参数写错 | 逐个注释排查可疑参数 |
6.2 数据目录权限问题:安装中最容易被忽略的一环
MySQL 的数据目录、日志文件、socket 文件都有严格的属主和权限要求。如果之前用 root 手动创建过 /var/lib/mysql,或者把数据目录迁移到了其他路径,很容易出现权限不对导致启动失败。
正确的初始化目录操作:
bash复制mkdir -p /data/mysql/data
chown -R mysql:mysql /data/mysql/data
chmod 750 /data/mysql/data
然后在 /etc/my.cnf 中指定:
ini复制datadir=/data/mysql/data
启动后确认日志里没有权限相关报错。很多从二进制包安装的人习惯手动执行 mysqld --initialize,但忘记了初始化后 /var/lib/mysql 下的文件属主不是 mysql,导致服务用 mysql 用户启动时无法写入。yum 源安装时这个流程会自动处理好,但手动改过路径的人一定要重新 chown。
6.3 忘记 root 密码的紧急重置方法
这个场景几乎每个人迟早会遇到,而且一旦发生,项目组群会比任何时候都活跃。在 CentOS 上快速重置 root 密码的方法如下。
先停止服务:
bash复制systemctl stop mysqld
以跳过授权表方式启动(临时):
bash复制mysqld_safe --skip-grant-tables &
此时可以免密登录:
bash复制mysql -uroot
重新设置密码。注意 5.7 和 8.0 的写法有差异,5.7 直接 UPDATE 即可:
sql复制UPDATE mysql.user SET authentication_string=PASSWORD('NewPass_123') WHERE User='root';
FLUSH PRIVILEGES;
8.0 则推荐使用 ALTER USER:
sql复制FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPass_123';
操作完成后退出,把 mysqld_safe 进程结束掉,再正常启动:
bash复制pkill mysqld_safe
pkill mysqld
systemctl start mysqld
注意:--skip-grant-tables 模式启动期间,MySQL 的安全性完全丧失,任何本机用户都能免密访问数据库。操作完务必确认恢复标准启动模式,不要在重启后又用这个参数启动。
6.4 systemd 服务文件对启动失败的影响
通过 yum 安装的 MySQL 会自动注册 systemd 服务。如果你在 /etc/my.cnf 里写了错误参数,systemctl start mysqld 会很快失败,但有时候执行后并没有立即报错,而是卡在那里,然后过几秒才出现 failed。这时候看 journalctl 更有效:
bash复制journalctl -u mysqld -n 50
这个命令能看到 systemd 视角里 mysqld 的完整启动日志,包括它读取的配置文件路径、加载失败的参数、文件权限错误等。比单纯看 /var/log/mysqld.log 更全面。
如果配置被改坏了,但又说不清改了哪里,可以用 minimal 配置快速拉起来:
bash复制mysqld --defaults-file=/etc/my.cnf --user=mysql --datadir=/var/lib/mysql
它会先输出配置解析错误和具体行号,方便定位问题参数。
7. 卸载重装与版本升级的经验教训
7.1 干净卸载 MySQL 的标准流程
需要重装时,不能只执行 yum remove mysql* 就完事,因为配置文件、数据目录和日志文件默认都还会残留,重新安装时可能继续报诡异错误。干净卸载步骤如下:
停止服务并查看已安装包:
bash复制systemctl stop mysqld
rpm -qa | grep mysql
移除所有 mysql 相关 rpm 包:
bash复制yum remove -y mysql-community-server mysql-community-client mysql-community-common mysql-community-libs
清理残留目录和文件:
bash复制rm -rf /var/lib/mysql
rm -rf /etc/my.cnf
rm -rf /var/log/mysqld.log
rm -rf /tmp/mysql.sock
这里有个重要提醒:如果你只是重装系统或搬家,在删除前一定要先备份数据目录。
全量备份最简单的方式是用 mysqldump:
bash复制mysqldump -uroot -p --all-databases --single-transaction > all_db_backup.sql
或者直接复制整个数据目录(停止服务后操作):
bash复制cp -a /var/lib/mysql /var/lib/mysql_backup
如果你把整个数据目录删了再装好 MySQL,才发现忘备份了,那基本就等于数据没救了。这个坑我见人踩过很多次。
7.2 从 5.7 升级到 8.0 的注意事项
升级前先确认没有使用不兼容特性。MySQL 8.0 移除了 query cache,如果你的业务大量依赖 query cache(老版本配置里设置了 query_cache_type=1),升级后需要移除相关配置。另外 8.0 对 GROUP BY 等语法行为更严格,某些老 SQL 在 5.7 能跑但在 8.0 会报错,上线前一定要跑一遍完整的回归测试。
官方推荐的升级路径是 5.7 -> 8.0 直接升级,但数据量大时还是建议先用逻辑备份恢复到测试库验证:
bash复制# 在5.7上导出
mysqldump -uroot -p --all-databases --single-transaction --routines --triggers > backup.sql
# 在8.0上导入
mysql -uroot -p < backup.sql
导入过程中常见两类问题:一是字符集不兼容导致的乱码,二是旧版 SQL 模式(sql_mode)在 8.0 中被默认设置了更严格的值(比如 ONLY_FULL_GROUP_BY),导致某些聚合查询失败。遇到后可以在 /etc/my.cnf 里临时调整 sql_mode,但不建议长期关闭,因为这是新版对数据规范性的基本要求。
7.3 用 Docker 装 MySQL 是备选方案,但不是偷懒方案
热搜里 docker 安装 mysql 出现频率很高。确实,Docker 方式安装 MySQL 比 yum 源安装速度更快、版本隔离更干净,非常适合本地开发和测试。简单示例:
bash复制docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=YourRootPass_123 \
-e MYSQL_DATABASE=mydb \
-v /data/mysql:/var/lib/mysql \
mysql:8.0
但我对生产环境的建议是:如果没有容器化基础设施(K8s、Docker Compose 等)和经验丰富的维护团队,业务数据库用 Docker 裸跑其实没有比 yum 源安装省心多少,反而多了存储卷、网络模式和容器重启策略几个维度要维护。我见过比较尴尬的情况是服务器重启后 Docker 容器没有自动启动,数据库在凌晨 3 点静默下线,等早上大家发现问题已经过去好几个小时。
反过来讲,如果你团队已经习惯了容器化运维,Docker 装 MySQL 的问题反而比物理机少,因为容器环境统一,镜像版本可控,yum 源版本漂移的问题就消失了。
8. 安装完成后的基础加固与日常维护清单
8.1 立即执行的几个安全项
MySQL 装好后,很多人的第一反应是马上把业务接进来跑起来。但我建议你花五分钟把下面这些做了,后面能避免大量麻烦。
先检查和删除默认的匿名账户:
sql复制SELECT user, host, authentication_string FROM mysql.user;
默认情况下,mysql.user 表里除了 root 和系统运维账号之外,不应存在 User 为空或 Host 为 '%' 的匿名账号。如果发现匿名账号存在,执行:
sql复制DROP USER ''@'localhost';
FLUSH PRIVILEGES;
再检查默认数据库。information_schema、mysql、performance_schema、sys 是系统库,不要随便动。如果看到 test 库,可以直接删掉:
sql复制DROP DATABASE IF EXISTS test;
另外,root 账号的密码要确认已经是强密码。如果安装后一直在用临时密码跑业务,建议立即更换,因为 MySQL 日志里存着初始密码,而日志文件通常权限较宽,容易泄露。
8.2 设置 binlog 和慢查询日志
binlog 是 MySQL 主从复制和时间点恢复的基石。如果这台 MySQL 后面要搭从库,binlog 必须提前打开。在 /etc/my.cnf 的 [mysqld] 段加:
ini复制server-id=1
log-bin=mysql-bin
binlog_format=ROW
expire_logs_days=7
max_binlog_size=100M
MySQL 8.0 中 expire_logs_days 已被 binlog_expire_logs_seconds 取代,配置时可以写成:
ini复制binlog_expire_logs_seconds = 604800
慢查询日志对排查接口响应慢特别有用:
ini复制slow_query_log=1
slow_query_log_file=/var/log/mysql-slow.log
long_query_time=2
设置后,超过 2 秒的 SQL 都会被记录到 /var/log/mysql-slow.log。排查性能问题时,mysqldumpslow /var/log/mysql-slow.log 是你最常用的命令之一。
8.3 定期备份是最后一道防线
我见过太多因为没备份而付出惨痛代价的案例。哪怕你的数据暂时没什么价值,也建议养成定时备份的习惯。最简单的 cron 备份:
bash复制crontab -e
# 每天凌晨2点执行
0 2 * * * mysqldump -uroot -p'YourPass' --all-databases --single-transaction --routines --triggers | gzip > /backup/mysql_$(date +\%F).sql.gz
备份文件保存周期建议至少保留 7 天以上,有条件的话异地存放。这里的 -p 后面直接跟密码确实存在命令行泄露风险,更稳妥的方式是把密码写进 /root/.my.cnf 并限制权限 600,这样 cron 和 mysqldump 都能自动读取,命令行里也不会暴露明文。
8.4 日常运维高频命令速查
最后分享几个日常最常用的命令组合,几乎每周都会用到:
查看数据库状态和版本:
sql复制SELECT VERSION();
SHOW STATUS;
SHOW PROCESSLIST;
查看连接数和最大连接数:
sql复制SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';
慢查询日志里频繁出现的 SQL,用 EXPLAIN 看执行计划:
sql复制EXPLAIN SELECT * FROM users WHERE email='test@example.com';
如果发现某个查询走了全表扫描,第一步考虑是否给相关字段加了索引。很多线上慢查询问题,SHOW INDEX FROM table_name 比任何调参都更有效。
这些命令不用全记住,收藏起来或者写成自己的便签脚本都行,关键是有排查思路:先看状态,再看进程,再看慢查询,最后看执行计划,基本就能解决 80% 的日常问题。
9. 最后再分享一个我自己的排查顺序
MySQL 装得多之后,你会发现很多问题归根到底就三类:配置不对、权限不够、网络不通。而我个人的建议是遇到任何 MySQL 异常,先不要急着改配置文件,按照"日志 -> 进程 -> 端口 -> 权限 -> 网络"的顺序理一遍,90% 的故障在第一步看日志时就能定位。
还有一个小习惯:每次修改 /etc/my.cnf 前,先复制一份备份:
bash复制cp /etc/my.cnf /etc/my.cnf.bak.$(date +%F)
这个习惯救过我很多次。改坏了随时可以回滚,而且对比新旧配置能快速知道是哪一行导致的问题。
如果你是第一次在 CentOS 上装 MySQL,建议先把官方 yum 源安装这条路走通,理解密码初始化、字符集、开远程访问这些基础流程,再去看二进制包和 Docker 方案。基础链路顺了,后面迁移、升级、主从复制这些进阶操作才有稳的地基。装数据库这件事不难,但踩坑往往是在你以为装完了之后才开始。
