ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux下MySQL 8.0安装配置与常见问题排查指南

Linux下MySQL 8.0安装配置与常见问题排查指南 1. 装之前先想清楚的三件事能帮你省一整天的时间很多人拿到一台新服务器或者新虚拟机第一反应就是sudo apt install mysql-server或者yum install mysql-server装完以为万事大吉结果半天之后还在和各种奇奇怪怪的报错作斗争。我在日常运维和帮朋友排查问题的时候见过太多这样的案例所以先花点时间聊一聊安装前的决策问题这些决策直接决定你后面是顺畅还是折腾。1.1 版本选择不是越新越好但也不是越稳越好先说结论除非你有历史包袱否则新环境直接上 MySQL 8.0。如果你非要用 5.7那也得清楚自己在为什么买单。MySQL 8.0 已经发布很多年到了 8.0.x 的后期维护版本稳定性完全没问题。相比之下5.7 虽然经典但已经进入 EOL 阶段不再有长期的安全更新。我记得有一次给一个老项目搭环境对方指定要 5.7我折腾了一圈官方源之后发现现在下载 5.7 的包要比以前麻烦不少很多镜像已经把 5.7 的目录下掉了这种版本包袱带来的成本是实实在在的。如果你是在 Linux 上从零开始学 MySQL、或者做新项目开发选 8.0 就对了。具体版本号选择 8.0.x 的最新小版本即可没必要追着 innovation release 跑那些是给喜欢新特性的人尝鲜用的生产环境求的是稳。1.2 镜像源选择用系统自带源还是官方仓库源这是一个非常关键、但很多人不重视的决定。Ubuntu、Debian 自带的软件源里确实有 mysql-server但你要注意这个包名有时候指向的是 MariaDB 的兼容实现或者版本号滞后得非常厉害。Ubuntu 的 apt 源里那个 mysql-server 8.0 版本号可能比你想象中老不少而且它和你手动从 MySQL 官网下载的二进制包的目录结构、配置文件路径会有细微差别。CentOS / Rocky Linux 这边更典型默认源里那个mysql-server其实是 MariaDB。你执行yum install mysql-server装的很可能不是 MySQL 本身。很多新手在这里就已经跑偏了后面所有的操作都建立在错误的基础上。所以我个人的建议是无论你用哪个发行版都优先按照 MySQL 官方文档把官方 Yum/Apt 仓库配置好再从仓库里装。虽然多两步操作但换来的是完全可控的版本、目录结构和升级路径。官方仓库地址就是repo.mysql.com文档里写得很清楚跟着走就行。1.3 root 用户误区别急着切换系统用户还有一个观念问题MySQL 里的 root 账户和 Linux 系统里的 root 用户是两码事。很多人习惯性用系统的 root 去执行 mysql 命令然后开始怀疑人生——其实在 Linux 上安装完 MySQL 之后你用sudo mysql就能进客户端这依赖的是 Unix socket 认证。这个机制后面配置的时候会细说但你先记住这个结论操作 MySQL 并不需要系统 root 身份普通用户加 sudo 就够了。想清楚这三件事基本上就避开了新手最容易踩的三个大坑。接下来我们进入正题把安装流程完整走一遍。2. 最稳的安装路径从配置官方仓库到跑通验证下面这套流程我分别在 Ubuntu 22.04 / 24.04 和 Rocky Linux 9 上都实测过照着做基本不会出幺蛾子。2.1 Ubuntu / Debian 系列配置官方 APT 仓库先更新系统索引然后安装几个基础工具这些工具后面都会用到sudo apt update sudo apt install -y wget gnupg lsb-release接着下载并导入 MySQL 官方的 GPG 签名密钥这个步骤很关键少了它 apt 会拒绝安装来自官方仓库的包wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.33-1_all.deb sudo dpkg -i mysql-apt-config_0.8.33-1_all.deb过程中会弹出图形化选择界面让你选择要安装的 MySQL 版本。默认就是 MySQL 8.0直接选择 OK 退出即可。如果你需要选 5.7这里就要手动切换但说实话除非特殊需求我都不建议在这上面花时间。选完之后再执行sudo apt update sudo apt install -y mysql-server安装过程中系统可能会提示你输入 root 密码也可能不提示。如果你在安装时已经设置了密码那就记好如果没设置后面用安全脚本初始化时再搞。这两种情况我都遇到过不提示密码是更常见的情况别慌。2.2 CentOS / Rocky Linux 系列配置官方 YUM 仓库Rocky Linux 9 上这么操作sudo dnf install -y https://dev.mysql.com/get/mysql80-community-release-el9-5.noarch.rpm装完这个 rpm 之后它会往/etc/yum.repos.d/里写入 MySQL 官方的 repo 文件。接着检查一下仓库列表确认 MySQL 8.0 的仓库是启用的dnf repolist enabled | grep mysql然后安装sudo dnf install -y mysql-community-server和 apt 不同yum/dnf 安装的过程中不会让你设置任何密码装完之后 root 账户默认是空的这反而是个好事因为我们可以完全掌控初始化的流程。2.3 初始化、启动与开机自启一条龙讲完装完之后Ubuntu 系的 MySQL 服务通常会自动启动。CentOS/Rocky 系不会需要手动初始化sudo mysqld --initialize-insecure注意这里用的是--initialize-insecure它的意思是初始化数据目录并且 root 账号没有密码。你如果看官方文档还会见到--initialize那个是生成一个临时随机密码会写到错误日志里第一次登录还得去日志里翻。对于自己搭环境来说--initialize-insecure更方便反正后面我们还要执行安全脚本统一设置密码。启动服务和设置开机自启sudo systemctl start mysqld sudo systemctl enable mysqld systemctl status mysqld看到active (running)就说明服务起来了。2.4 跑一下安全初始化脚本MySQL 装完自带的mysql_secure_installation脚本是个好东西它会引导你完成几件事设置 root 密码、删除匿名用户、禁止 root 远程登录、删除 test 数据库、重新加载权限表。很多人嫌它麻烦直接跳过但我建议新环境都跑一遍尤其是部署在真实服务器上的情况。sudo mysql_secure_installation第一个问题大概率是问你密码强度策略。MySQL 8.0 默认装了一个validate_password组件它会把密码策略卡得很严要求包含大小写字母、数字和特殊字符长度至少 8 位。如果你只是想本地开发用可以选 Low 策略如果是要上生产的建议至少保持 Medium。这个组件后面会在排查实录那一节专门讲因为太多人在这一步被卡住了。脚本跑完之后你可以验证一下mysql -u root -p输入刚才设置的密码能进客户端就说明安装和初始化都完成了。3. 装完先别急着写业务把这几个配置改好再开工很多教程到上面就结束了但我认为真正影响日常使用体验的是这一节的内容。刚装好的 MySQL 就像一套毛坯房能住人和住得舒服是两码事。3.1 root 账户与认证插件为什么有时 sudo mysql 能进、密码却进不去这是一个几乎所有人都会撞上的问题尤其在使用 Debian/Ubuntu 系的时候。Ubuntu 上通过 apt 安装的 MySQLroot 用户默认的认证插件是auth_socket。这个插件的意思是只要你是 Linux 系统里的 root 用户或者属于 sudo 用户组就能直接通过 Unix socket 登录 MySQL完全不用密码。所以你执行sudo mysql能顺利进客户端。但问题来了当你用mysql -u root -p输入密码登录时会一直报错Access denied。原因就是auth_socket压根不看密码它看的是你是谁。这个设计对安全来说其实很合理——本地 root 访问 MySQL 不再依赖密码保护而是依赖系统用户的权限边界。但如果你需要通过 TCP/IP 连接 root比如用 Navicat、MySQL Workbench 远程连auth_socket就完全不适用了。解决办法是手动把 root 的认证插件改成caching_sha2_password并设置密码ALTER USER rootlocalhost IDENTIFIED WITH caching_sha2_password BY 你的密码; FLUSH PRIVILEGES;caching_sha2_password是 MySQL 8.0 的默认认证插件安全性比老旧的mysql_native_password好很多。如果你用的客户端版本比较老比如某些上古版本的 PHP mysql 扩展可能会不兼容这个插件那就只能退回到mysql_native_password但我不建议这么做更好的方案是升级你的客户端。3.2 bind-address、端口和防火墙远程连不上的根源本地连得通、远程连不上这是排行榜前三的经典问题。MySQL 默认只监听127.0.0.1也就是只允许本机连接。要允许远程访问需要修改配置文件。配置文件的位置因安装方式而异apt 安装的在/etc/mysql/mysql.conf.d/mysqld.cnfyum/rpm 安装的在/etc/my.cnf。修改其中[mysqld]部分的bind-address[mysqld] bind-address 0.0.0.0 port 33060.0.0.0表示监听所有网卡。如果你只想让特定网段的机器连可以写成具体的 IP但大多数场景下0.0.0.0加上防火墙规则就够了。改完配置文件必须重启服务sudo systemctl restart mysqld然后还有一道防火墙。Ubuntu 上如果开了 ufwsudo ufw allow 3306/tcpCentOS/Rocky 上如果开了 firewalldsudo firewall-cmd --permanent --add-port3306/tcp sudo firewall-cmd --reload最后验证监听状态ss -tlnp | grep 3306看到0.0.0.0:3306就说明 MySQL 已经开始在对外监听了。3.3 创建应用专用账号而不是让程序直连 root远程连接还有一个安全隐患很多人图省事直接放行 root。我强烈不建议这么做root 应该只留给本地管理应用连接应该用独立的账号权限能收多紧就收多紧。CREATE USER app_user% IDENTIFIED BY 强密码; GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO app_user%; FLUSH PRIVILEGES;%表示允许从任意主机连接。如果应用服务器 IP 固定更稳的做法是指定 IPCREATE USER app_user192.168.1.100 IDENTIFIED BY 强密码;这样即使账号密码泄露攻击者也换不了机器连接安全性提升一个档次。顺带一提很多人喜欢把所有权限一股脑给ALL PRIVILEGES包括GRANT OPTION这等于给了这个账号管理其他账号的能力。最小权限原则在数据库这里不是口号是保命用的。3.4 字符集、排序规则和时区数据库的语言环境MySQL 8.0 的默认字符集已经是utf8mb4排序规则是utf8mb4_0900_ai_ci比老版本的utf8mb4_general_ci更合理。但有些场景下你还是需要手动确认或修改。查看当前字符集SHOW VARIABLES LIKE character_set%; SHOW VARIABLES LIKE collation%;如果你想在建库时显式指定CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;关于排序规则utf8mb4_0900_ai_ci是大小写不敏感、口音不敏感的比较规则适合大多数业务场景。如果你需要大小写敏感的查询可以用utf8mb4_0900_as_cs。时区是另一个容易踩的坑。默认情况下 MySQL 使用系统时区但如果你连上来的客户端来自不同时区建议统一设置为 UTC 或者你业务所在的时区SELECT NOW(); SET GLOBAL time_zone 08:00;SET GLOBAL只对当前实例生效重启后会失效。要持久化需要在配置文件里加[mysqld] default-time-zone 08:00之后再执行SELECT NOW()你会发现结果和系统时间对上了。4. 排查实录error 2002、密码策略和 Workbench 连接问题这一节是我们团队在几十台服务器上反复踩坑之后总结出来的问题清单。说实话每一个问题都曾经让我恼火过但排查完回头看其实都有非常清晰的逻辑链路。4.1 经典报错error 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock这个报错的热度在所有 MySQL 问题里排前三。它的字面意思是通过 socket 文件 /tmp/mysql.sock 无法连接到本地 MySQL 服务器。遇到这个报错首先确认一件事MySQL 服务到底有没有在运行systemctl status mysqld # 或者 ps aux | grep mysqld如果服务没在运行那问题就简单了直接启动sudo systemctl start mysqld还有一种情况特别容易迷惑人服务明明在跑但依然报这个错。这就涉及一个知识点——MySQL 的 socket 文件路径不一定是/tmp/mysql.sock。你完全可以在配置文件里把它改到别的地方。查看实际的 socket 路径mysql -u root -p -e SHOW VARIABLES LIKE socket;查出来之后要么把客户端命令里的 socket 路径指过去mysql -u root -p --socket/var/run/mysqld/mysqld.sock要么在配置文件里把 socket 改回/tmp/mysql.sock。这里要特别注意socket 路径修改后其他依赖老路径的程序例如某些 PHP-FPM 配置也要一起改不然它们也会报同样的错。还有一个我差点忽略的场景如果你在 chroot 环境或者容器里跑 MySQL/tmp 目录和宿主机不是一回事socket 文件看不见很正常。这种环境我更推荐直接走 TCP 连接省心mysql -u root -p -h 127.0.0.1 -P 33064.2 密码策略太强导致的连锁反应MySQL 8.0 的validate_password组件默认是开启的。它的默认策略是 Medium要求密码里必须有数字、小写字母、大写字母和特殊字符而且长度不能少于 8 位。这本身没毛病但问题在于很多自动化脚本、配置文件里写的是弱密码安装完一授权就报错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 6;如果用的是 MySQL 5.7变量名不太一样是validate_password_policy和validate_password_length同样是SET GLOBAL方式。不过要提醒一句如果是生产环境别把密码策略关了老老实实用强密码。我见过太多把数据库密码设成123456然后被勒索的案例这不是危言耸听。4.3 MySQL Workbench 连不上的检查清单MySQL Workbench 是官方出的图形化客户端网上关于它的教程非常多。但你有没有发现跟着教程走一遍最后一步总是连不上我的排查顺序是这样第一步确认账号允许远程登录。如果创建用户时写的是userlocalhost那它永远只能从本机连Workbench 从别的机器连肯定不行。修改方式ALTER USER userlocalhost IDENTIFIED BY 密码; RENAME USER userlocalhost TO user%; FLUSH PRIVILEGES;第二步确认认证插件兼容。前面说过 MySQL 8.0 默认caching_sha2_password部分图形化客户端版本过低会报Authentication plugin caching_sha2_password cannot be loaded。升级 Workbench 到最新版基本能解决。第三步检查网络连通性。在 Workbench 所在机器上telnet 目标服务器IP 3306或者用 ncnc -zv 目标服务器IP 3306这不是数据库问题是网络问题。如果连不通去检查服务器防火墙、云安全组、bind-address 设置这些在前面都讲过了。5. 装好配置好之后日常维护还要注意这几个点安装和基础配置做完MySQL 已经可以正常使用了。但如果你想用得久、用得稳下面这些日常操作要养成习惯。5.1 常用管理命令速查很多人装了 MySQL 之后天天就用一个mysql -u root -p进客户端其他系统层面的操作全靠百度。这里我把最常用的几条命令列出来平时用得多记熟了能省不少事。# 查看服务状态 systemctl status mysqld # 启动 / 停止 / 重启 systemctl start mysqld systemctl stop mysqld systemctl restart mysqld # 设置开机自启 systemctl enable mysqld # 查看错误日志排查问题时必看 sudo tail -f /var/log/mysql/error.log # CentOS/Rocky 上日志路径可能是 /var/log/mysqld.log # 查看 MySQL 监听的端口 ss -tlnp | grep 3306数据库层面的操作我提一个建议不要过度依赖图形化工具。比如改表结构、查数据这种事用 Workbench 没问题但像是导出导入、执行批量脚本、排查慢查询命令行效率高得多。我平时用的最多的导出导入命令# 导出整个库 mysqldump -u root -p mydb mydb.sql # 导出单表 mysqldump -u root -p mydb users users.sql # 导入 mysql -u root -p mydb mydb.sql说到mysqldump顺便提一个很多人问过的点导出的时候要不要加--single-transaction这个参数对 InnoDB 表很重要它可以在不锁表的情况下做一致性快照备份。如果你在线上备份这个参数一定要加。5.2 老生常谈但必须做定期备份和恢复演练很多服务器上的 MySQL 从装好那天起就没人碰过备份这是最危险的状态。备份这件事方案不重要重要的是真的去执行。一个最简单的方案写在 crontab 里0 2 * * * mysqldump -u root -p密码 --single-transaction --all-databases | gzip /backup/mysql_$(date \%F).sql.gz这里有个小细节把密码写在命令行里ps能看到进程参数存在安全隐患。更稳妥的做法是把密码写进配置文件/root/.my.cnf[mysqldump] userroot password你的密码然后命令简化为0 2 * * * mysqldump --single-transaction --all-databases | gzip /backup/mysql_$(date \%F).sql.gz光备份还不够我强烈建议你定期做一次恢复演练。我见过不少团队备份文件存了一堆真到要恢复的时候才发现备份是坏的。每个月找一台空闲机器把最新的备份导进去验证一下这个习惯关键时刻能救命。5.3 几个必须知道的 MySQL 8.0 常用语法细节这里我想聊几个热词里出现频率很高的操作它们不是安装配置的问题但恰好是初学者在写完基础建表之后最常问的。UPDATE 语法里的多表更新。很多人不知道 UPDATE 可以一次性更新多张表UPDATE orders o JOIN users u ON o.user_id u.id SET o.user_name u.name WHERE u.status 1;这个特性在数据订正场景下非常好用比先 SELECT 再逐条 UPDATE 高效得多。排序规则与 ORDER BY 的行为。字符集和排序规则会影响字符串字段的排序结果。之前我们把数据库默认排序规则设成了utf8mb4_0900_ai_ci它是不区分大小写的。如果你执行SELECT * FROM users ORDER BY nameapple和Apple会排在一起。如果你需要区分大小写排序可以在查询里显式指定SELECT * FROM users ORDER BY name COLLATE utf8mb4_0900_as_cs;声明存储过程。这个操作看起来复杂其实模板非常固定DELIMITER // CREATE PROCEDURE get_user(IN user_id INT) BEGIN SELECT * FROM users WHERE id user_id; END // DELIMITER ;DELIMITER的作用是临时把语句分隔符从分号改成//这样整个存储过程体才能作为一个整体被提交。我第一次写存储过程时忘了改 DELIMITER结果客户端一看到分号就断句报了一堆语法错误印象极深。如果你需要把字段默认值设为 0也很简单CREATE TABLE example ( id INT PRIMARY KEY AUTO_INCREMENT, status INT NOT NULL DEFAULT 0 );或者修改已有表ALTER TABLE example ALTER COLUMN status SET DEFAULT 0;这些语法点单独看都不难但组合在一起就是日常开发的真实场景。我建议你把这份配置好的 MySQL 环境当成一个实验场把这些语句都亲手跑一遍比看一百篇文档都管用。6. 最后分享几个我踩过坑之后形成的习惯文章写到这儿安装、配置、排查、日常维护的主线都过完了。最后我想分享几个我个人的习惯它们都是真金白银换来的经验。第一个习惯是修改任何配置之前先备份原文件。MySQL 的配置文件改错一个字母可能整个服务就起不来了。我的习惯是改之前先复制一份sudo cp /etc/my.cnf /etc/my.cnf.bak改坏了随时能还原不用靠记忆去恢复。第二个习惯是每次装完 MySQL第一件事不是建库是确认日志路径。后面所有问题排查都离不开日志。Ubuntu 上错误日志在/var/log/mysql/error.logCentOS/Rocky 上在/var/log/mysqld.log。确认好路径等出问题时你就知道去哪找答案了。第三个习惯是用mysql -u root -p登录后先看版本和变量而不是急着写 SQL。SELECT VERSION(); SHOW VARIABLES LIKE %version%;确认版本号能帮你避免很多不同版本语法不兼容的坑。比如 5.7 和 8.0 的密码认证插件就不一样8.0 默认是caching_sha2_password5.7 默认是mysql_native_password你在网上搜到的很多教程要先看清楚它写的是哪个版本的 MySQL。第四个习惯是MySQL 配置调整完不要只看systemctl status要用真实查询验证。服务起来不代表配置生效了。比如你改了字符集重启之后要实际建个表、插条中文数据试一下你改了时区要执行SELECT NOW()对比一下。光看配置文件里写了什么和实际生效的值之间是有距离的。最后再说一句关于学习路径的建议网上那些 MySQL 安装配置教程一抓一大把但很多人只是跟着敲命令敲完就忘了。我见过最快的成长方式是装完之后故意去踩坑——故意把密码设弱看看会报什么错故意改错 bind-address 看远程连接失败是什么表现故意删掉 socket 文件再重启服务看会发生什么。这些坑都踩过一遍你才算真正理解了 MySQL 的行为方式。到那个时候再回头去看任何一篇教程你都能一眼看出它哪里说得对、哪里说得不够严谨。这才是我写这篇长文的真正目的——不只是让你装上 MySQL而是让你理解装完之后这套系统是怎么运转的。
返回列表