
最近在一台CentOS 7.9服务器上重新部署MySQL 5.7.44过程中踩了不少坑趁着记忆还热乎把完整的安装、配置、排错流程整理出来。不管你是刚接触Linux的新手还是已经能熟练使用常用命令的老手在CentOS上安装MySQL这件事看似简单但一个不小心就会遇到依赖冲突、权限错乱、启动失败这些麻烦。这篇文章我会用最直接的方式分别讲清用Yum源和RPM包安装的完整流程还会补充大量实测出来的排错经验。1. 安装前的环境准备与方案选型1.1 确认系统版本、硬件与网络环境很多新手拿到一台服务器就急着装MySQL结果装一半才发现系统是CentOS 8或者架构对不上白折腾半天。建议第一步先把环境信息摸清楚执行下面几条命令cat /etc/centos-release uname -m nproc free -h df -hcat /etc/centos-release看系统版本比如CentOS Linux release 7.9.2009 (Core)或者8.x系列。uname -m看CPU架构最常见的是x86_64如果是aarch64ARM架构服务器仓库包的选择会不一样。nproc看CPU核心数free -h看内存df -h看磁盘空间。MySQL 5.7最低要求内存不低于1GB空闲磁盘不少于5GB但实际生产环境2GB内存加20GB可用磁盘是起点否则跑一会儿就会因为内存耗尽或日志撑爆磁盘出各种奇怪问题。另外网络环境决定你能不能顺利下载依赖包。如果是内网服务器没法直接访问外网就需要提前下载好RPM包和依赖或者配置内网镜像源。这里多说一句很多人喜欢把系统自带的最小化安装再精简一遍但MySQL需要一些基础依赖库例如libaio、numactl等后面会讲到。1.2 三种主流安装方式到底选哪种CentOS上装MySQL主流路线有三条官方Yum源、RPM包手动安装、源码编译。还有一部分人直接拉Docker镜像这里也顺便说一下。官方Yum源安装最省心适合大部分场景。通过MySQL官方提供的repo包把Yum源指向官方仓库然后yum install mysql-community-server一条命令自动解决所有依赖后续升级也方便。RPM包手动安装适合内网环境、离线安装或者需要精确控制版本的场景。从官方站点下载对应的rpm-bundle.tar解压后用rpm -ivh按顺序安装依赖需要自己处理。源码编译适合需要深度定制编译参数、关闭某些插件或者优化特定硬件的场景。编译耗时耗力配置不当还可能性能反而不如二进制包非特殊需求一般不建议。Docker安装用镜像跑MySQL是现在很多开发和测试环境的标准做法但生产环境需要自行处理数据卷、网络、日志、自动重启等问题。如果只是本地练手Docker很舒服真正上生产我还是建议直接用物理或虚拟机的系统服务方式少一层中间层排错也简单。我用得最多的还是官方Yum源。原因很简单官方仓库的版本经过专业测试依赖处理自动化不会出现手动装漏一个.so库然后服务启动失败的问题。而且官方Yum源支持同时安装5.7和8.0系列切换版本也方便。2. 使用官方Yum源安装MySQL 5.7与8.02.1 先清理系统自带的MariaDB和残留MySQLCentOS 7默认自带MariaDB它是MySQL的一个分支很多命令和客户端兼容但因为服务和数据文件与MySQL不兼容直接装MySQL会冲突。先看系统里有没有rpm -qa | grep -E mariadb|mysql如果看到mariadb-libs这类包就用yum remove mariadb*把它卸掉。注意有些系统库可能依赖于它比如postfix如果报依赖错误可以加上--nodeps强行删除但删除后记得后续排查其他服务是否正常。这一步不做干净后面MySQL启动时可能会出现socket文件冲突或者库文件混乱的问题。另外如果之前已经装过MySQL但没装完整重新安装前最好先清理旧数据和旧配置防止残留的/etc/my.cnf干扰新服务。默认数据目录在/var/lib/mysql如果里面已经有库且不是你想保留的直接把整个目录移走或删除都可以。systemctl stop mysqld 2/dev/null rm -rf /var/lib/mysql /etc/my.cnf /etc/my.cnf.d2.2 添加官方Yum仓库并验证可用性MySQL官方提供了一个集成仓库的RPM包安装这个包之后Yum就能自动识别MySQL的软件源。5.7对应的是mysql57-community-release8.0对应的是mysql80-community-release。以CentOS 7为例执行yum install -y https://repo.mysql.com/mysql57-community-release-el7-11.noarch.rpm如果想装8.0就把包名换成mysql80-community-release-el7-7.noarch.rpm。安装完成后检查仓库是否生效yum repolist enabled | grep mysql你会看到mysql57-community、mysql-tools-community之类出现了。这时还可以先查一下当前仓库里MySQL的可用版本yum list available --showduplicates mysql-community-server如果系统年久失修连GPG密钥都可能过期。遇到GPG key retrieval failed的报错可以手动导入官方密钥或者更新mysql-public-key.asc。不过正常情况下安装了release包后密钥会一起放入基本不用管。2.3 安装MySQL服务器并启动初始化现在直接安装服务器程序yum install -y mysql-community-server安装过程会列出依赖比如mysql-community-libs、mysql-community-common全自动搞定非常省事。安装完成后先初始化数据目录再启动服务。5.7和8.0的初始化不太一样5.7的默认配置文件/etc/my.cnf里已经配置了log-error安装后首次启动时MySQL会自己完成初始化并生成临时root密码。因此直接启动就可以systemctl start mysqld systemctl enable mysqld systemctl status mysqld启动成功的标志是状态显示active (running)。如果失败请先看第5章的排错内容。启动以后MySQL已经在/var/lib/mysql下写好了系统库和默认数据文件挺快的。2.4 拿到临时密码并完成root改密5.7和8.0都开启了密码用过期机制首次启动会生成一个随机临时密码记录在错误日志里。找到它的命令是grep temporary password /var/log/mysqld.log然后登录mysql -uroot -p输入刚才的临时密码进入后立刻修改root密码ALTER USER rootlocalhost IDENTIFIED BY 你的新密码;注意MySQL默认启用了密码校验插件要求密码至少包含大写字母、小写字母、数字和特殊符号长度不少于8位。如果你觉得这太苛刻可以降低策略后面会在第3章详细写。改完密码之后建议执行FLUSH PRIVILEGES其实ALTER USER之后不需要这一步但做一次无妨。3. 修改核心配置与安全加固3.1 调整my.cnf让MySQL更贴业务/etc/my.cnf是MySQL的主配置文件5.7和8.0默认安装后会带上一个基础配置其实内容很少很多默认值对生产环境并不适合。就拿我最近这台业务服务器来说默认配置跑起来后没几天就发现连接数不够日志混乱字符集也是老旧设定。分享一段常用配置可以直接存进/etc/my.cnf[mysqld] datadir/var/lib/mysql socket/var/lib/mysql/mysql.sock symbolic-links0 log-error/var/log/mysqld.log pid-file/var/run/mysqld/mysqld.pid character-set-serverutf8mb4 collation-serverutf8mb4_general_ci port3306 bind-address0.0.0.0 max_connections500 max_connect_errors1000 wait_timeout600 interactive_timeout600 key_buffer_size64M innodb_buffer_pool_size1G innodb_log_file_size256M innodb_flush_log_at_trx_commit1 innodb_file_per_table1 slow_query_log1 slow_query_log_file/var/log/mysql-slow.log long_query_time2这里重点解释几个关键参数的意图character-set-serverutf8mb4决定默认字符集utf8mb4能完整存储中文和emoji而utf8是历史遗留问题很多地方是不完整的。bind-address0.0.0.0让MySQL允许从任意IP访问注意这时候必须通过防火墙限制来源不然等于裸奔。max_connections根据业务评估连接数过多会内存翻倍增长过少则应用经常报Too many connections。innodb_buffer_pool_size决定InnoDB缓存池大小这个直接决定读写性能通常设为物理内存的60%~70%比较合理。1G内存的机器就不要设1G否则系统内存被吃光。我建议内存2G的机器设512M4G的设1.5G照此推。slow_query_log开启慢查询日志线上排查性能问题必备。配置改完后重启服务systemctl restart mysqld建议每次改配置后用mysqld --validate-config先验证配置是否有语法错误6.0.8以上的版本这命令还支持检查参数有效性。如果没有这个命令就多留意报错日志。3.2 创建业务账号配置远程访问root账号极其敏感生产环境绝对不能拿root给应用连接。正确做法是创建一个专用账号只授权应用需要的数据库。CREATE USER appuser% IDENTIFIED BY StrongPass2024; GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO appuser%; FLUSH PRIVILEGES;appuser%代表来自任意主机的appuser账号为了安全可以缩小范围比如应用服务器IP是192.168.1.100就写appuser192.168.1.100。这样即使密码泄露攻击面也小很多。创建完账号还要检查系统防火墙是否放行3306端口firewall-cmd --permanent --add-port3306/tcp firewall-cmd --reload如果你用的是云厂商的安全组还要在管理后台额外放行。很多新手本地防火墙关了结果被云安全组拦在外面一脸懵。3.3 密码策略放宽与安全清理MySQL的validate_password插件会强制复杂密码开发环境或者老系统里这简直让人抓狂。可以动态修改校验级别SET GLOBAL validate_password_policy LOW; SET GLOBAL validate_password_length 6;但注意重新启动MySQL实例后这两项配置会重置。想要永久生效把下面两行加进my.cnfvalidate_password.policyLOW validate_password.length68.0的变量名带validate_password.*前缀5.7是validate_password_policy注意区分。安全清理方面全新的MySQL实例默认会带着test库直接删掉。还有匿名用户也可以顺手清理DELETE FROM mysql.user WHERE User; DROP DATABASE IF EXISTS test; FLUSH PRIVILEGES;另外远程登录尽量别用root。即使要用也建议限定来源IP。4. 数据目录、日志与备份策略4.1 把数据目录迁移到底层数据盘很多服务器会有系统盘和数据盘之分。默认情况下MySQL数据存在/var/lib/mysql系统盘如果满了数据库就挂了。把数据目录迁移到挂在/data的独立数据盘是很常见的需求。操作流程分几步# 1. 停止服务 systemctl stop mysqld # 2. 复制数据目录到新位置 cp -a /var/lib/mysql /data/mysql # 3. 修改配置 vim /etc/my.cnf # 把 datadir/var/lib/mysql 改为 datadir/data/mysql # 4. 修改SELinux上下文否则启动失败 semanage fcontext -a -t mysqld_db_t /data/mysql(/.*)? restorecon -Rv /data/mysql # 5. 启动服务 systemctl start mysqld如果你的系统启用了SELinuxCentOS 7默认忘记第三步MySQL启动时会疯狂写Permission denied到日志。当然也可以直接关闭SELinux但我不建议宁可正确配置上下文。另外迁移后原本的/var/lib/mysql如果不再使用可以备份后删除或者做成软链接但软链接方案容易搞混权限建议直接修改datadir。4.2 binlog、慢查询、错误日志的合理配置MySQL的日志体系多样其中binlog二进制日志负责记录所有数据变更是数据恢复和主从复制的基础。默认情况5.7下log-bin是关闭的生产环境强烈建议开启。在my.cnf中加上server-id1 log-binmysql-bin expire_logs_days7 max_binlog_size100Mserver-id在主从复制时是必须的数字任意但集群中必须唯一。expire_logs_days控制清理多少天前的binlog防止磁盘被撑爆8.0里有更灵活的binlog_expire_logs_seconds。错误日志前面已经提到路径在log-error/var/log/mysqld.log如果MySQL起不来第一件事就是看这个文件。慢查询日志帮助我们找出执行时间超过阈值的SQL定位性能瓶颈。把它们都配在my.cnf里线上问题排查会少很多麻烦。数据恢复试验我强烈建议做一次开好binlog后建立一个测试库插入几行数据然后删库再通过binlog按时间点恢复。这一套流程熟悉了遇到真正故障时不慌。5. 常见问题与排查技巧5.1 启动失败与日志定位装完MySQL最常遇到的就是systemctl start mysqld执行后提示失败但原因却五花八门。先把日志打开看你现在的错误日志路径是不是/var/log/mysqld.logtail -100 /var/log/mysqld.log如果日志里出现Cant create/write to file /var/lib/mysql/mysql.pid这类内容八成是目录权限不对。可以执行chown -R mysql:mysql /var/lib/mysql修正。如果日志显示Unit mysqld.service entered failed state大概率是配置里写了无效参数。可以尝试用mysqld --usermysql --verbose --help | grep -A 1 -E some-param确认参数是否被识别。另外/var/run/mysqld目录如果不存在MySQL会启动失败因为它要放socket和pid文件。解决方法mkdir -p /var/run/mysqld chown mysql:mysql /var/run/mysqld5.2 忘记root密码怎么办忘了root密码是家常便饭处理思路是跳过权限表然后把密码改掉。操作步骤systemctl stop mysqld mysqld_safe --skip-grant-tables mysql -uroot进入MySQL后FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY New_Strong_Pass;注意在--skip-grant-tables模式下很多客户端会报Root password is expired这时先执行FLUSH PRIVILEGES;再改密就能绕过去。改完密码重启服务即可。如果你用的是MySQL 5.7之前的旧版本改密码的语法是UPDATE mysql.user SET authentication_stringPASSWORD(...) WHERE Userroot; FLUSH PRIVILEGES;5.7之后更推荐用ALTER USER。5.3 远程连接失败防火墙、SELinux与网络三重排查客户端连不上MySQL但本地能登录这是高频问题。按顺序查MySQL用户权限rootlocalhost和root%不是同一个用户远程连接必须用用户可访问IP。先确认你创建的账号是否授权了对应主机。网络端口在客户端机器上执行telnet 服务器IP 3306如果超时说明中间链路不通。再在服务器上用ss -lntp确认MySQL是否监听在0.0.0.0:3306。如果只监听127.0.0.1需要把bind-address改成0.0.0.0。防火墙firewall-cmd --list-all检查3306是否放行。SELinux如果你没有配置SELinux上下文MySQL的网络访问也会被阻断。可以临时执行setenforce 0测试如果问题解决了就找到原因了再用semanage为MySQL配置上下文。5.4 MySQL 8.0与5.7差异导致的坑如果你之前一直用5.7切到8.0会发现几个非常明显的差异。首先8.0默认使用caching_sha2_password认证插件很多老版本的客户端工具例如PHP 7.1之前的mysqlnd驱动、某些版本的Python驱动不支持这种认证方式连接数据库报Authentication plugin caching_sha2_password cannot be loaded。解决办法是把这个用户改成动态密码方式ALTER USER appuser% IDENTIFIED WITH mysql_native_password BY yourpassword;其次是字符集系列变量8.0默认已经是utf8mb4不需要额外设置。还有my.cnf中一些旧参数被移除了比如query_cache_size在8.0里已经失效继续写会启动失败。8.0的官方文档更推荐用performance_schema替代。所以从5.7升级到8.0不能直接把老配置拷过来用必须逐个参数照一遍兼容性。6. 升级路径与彻底卸载6.1 5.7升级8.0需要注意的事如果你打算从5.7平滑升到8.0最稳妥的思路是备份后在新库上恢复而不是直接原地升级。原因在于8.0对数据字典、事务系统做了大量重构原地升级需要遵循官方升级路径稍有不慎就会锁表或损坏数据。我的建议流程停止写入全量备份所有库mysqldump -uroot -p --all-databases --single-transaction backup.sql在新环境安装MySQL 8.0用mysql backup.sql导入备份。手动验证应用与驱动的兼容性。有些服务可以接受短时间连接抖动也可以用mysqlsh utility.upgrade进行原地检查但必须有完整备份兜底。生产环境不要脑子一热就直接原地升。6.2 如何彻底卸载MySQL有时装坏了想重来或者要切换版本彻底卸载干净是很关键的。命令如下systemctl stop mysqld yum remove -y mysql-community-server mysql-community-libs mysql-community-common mysql-community-client rm -rf /var/lib/mysql /etc/my.cnf /etc/my.cnf.d /var/log/mysqld.log还要检查下有没有残留依赖比如mysql-community-release这个repo包如果不想要也一起删掉yum remove -y mysql57-community-release删完后用rpm -qa | grep mysql确认无残留。如果只装了server想保留client那就不要一次性卸掉全部。这里分享一个自己踩过的坑有一次卸载没有删掉/var/lib/mysql重新安装后新数据一直初始化失败错误提示是数据目录已存在且非空。因为之前库里的表不兼容。后来老老实实把数据目录备份移走再重装问题立刻解决。7. 最后的几个实践心得装了这么多次MySQL我个人最推荐的方式还是官方Yum源systemd管理省心且可控。遇到问题不要慌每一步错误信息都能在日志里找到具体原因关键是知道去哪看日志、看哪些关键词。新同学如果第一遍装完能远程登录再顺手练一遍数据迁移、binlog恢复基本就能应对日常运维了。最后再分享一个小技巧MySQL的/var/log/mysqld.log会记录启动过程中的所有错误和警告但日志会滚动覆盖。如果你排查问题需要更早的日志可以修改my.cnf增加log-error的保留策略或者结合logrotate定期归档。这个习惯养成后不管是自己排错还是将来交给同事都会轻松很多。祝一次安装成功。