Linux安装MySQL 8.0完整实战:从Yum仓库到高频故障排查
Linux下装MySQL说难不难说简单吧几乎隔三差五就能在群里看到有人贴出一张报错截图要么是ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock要么是装完之后root密码怎么试都不对甚至还有的连装都没装上直接被yum源里的MariaDB给“截胡”了。这些都是我在自己的服务器和客户现场实打实踩过的坑所以想写一篇真正能落地、能复现的Linux MySQL安装教程把选型逻辑、完整操作步骤、初始化配置和高频故障排查链路都梳理清楚希望能帮你少走几个来回。这篇文章适合三类人第一次在Linux上装MySQL的纯新手、从Windows转过来不太适应命令行的同学以及装过但总在某个环节翻车的“老踩坑人”。内容以CentOS/RHEL系的yum/dnf安装为主同时会覆盖Ubuntu/Debian系和通用二进制包的差异点只要按章节走完大概率能一次跑通。1. 为什么同一个安装教程别人装得成你装不成1.1 三个影响成败的前置认知网上搜“Linux安装MySQL”能搜出一堆教程但很多人拿着教程直接套结果第一步就挂了。原因很简单Linux发行版之间的差异比Windows大得多同一个命令在CentOS 7上能跑在Ubuntu 22.04上可能压根不存在反之亦然。第一个需要建立的认知是包管理器的区别。CentOS/RHEL老版本用yumCentOS 8及以后用dnfUbuntu/Debian用apt。虽然dnf可以兼容yum命令但仓库配置文件的路径、软件包命名规则都不一样。MySQL官方仓库提供了针对不同系统的rpm包和deb包选错了就是白费力。第二个认知是MySQL和MariaDB不是一回事。CentOS 7默认的软件源里有个mysql包但那个包指向的是MariaDB——MySQL被Oracle收购后原开发团队分叉出来的社区版本。如果你直接yum install mysql装出来的东西虽然命令很相似但数据目录结构、配置文件位置、部分系统表都有差异网上针对官方MySQL的教程可能对不上号。这也是很多新手“照着教程做却莫名其妙”的根源。第三个认知是MySQL 8.0和5.7差别很大。现在官方默认推8.0默认认证插件是caching_sha2_password密码策略默认是强校验这些特性在5.7时代都不存在。如果你下载的是8.0却拿5.7的教程来配置很容易在密码、远程连接环节卡住。1.2 该怎么判断“该用哪套命令”在动手之前先用几条命令确认系统基本信息别凭感觉猜# 查看发行版信息 cat /etc/os-release # 查看系统架构 uname -m # 查看包管理器 which yum dnf apt-get 2/dev/null以我自己的经验CentOS 7.x就用yumCentOS 8/Rocky Linux/AlmaLinux用dnfyum命令也兼容Ubuntu 20.04/22.04/Debian用apt。架构基本都是x86_64少数ARM服务器要注意选对二进制包。提示如果你的系统里已经自带了MariaDB建议先确认一下自己到底需要哪个。MariaDB和MySQL在大部分场景下可以互相替代如果你没有特别强制的兼容性需求用系统自带的MariaDB其实更省事。如果确实需要官方MySQL再走下面的卸载清理流程。1.3 一个很容易被忽略的坑残留的旧版本不少人装MySQL失败不是新装的问题而是机器上有残留。以前曾经手动装过MySQL、或者系统自带了MariaDB数据目录、配置文件、服务脚本都会和新装的产生冲突。最常见的现象是新装完MySQLsystemctl start mysqld却提示端口被占用或者数据目录初始化失败。所以在安装之前必须先确认一下是否存在旧版本# 检查是否装了MySQL/MariaDB相关的rpm包 rpm -qa | grep -iE mysql|mariadb # 检查是否已存在数据目录 ls -ld /var/lib/mysql 2/dev/null ls -ld /etc/my.cnf 2/dev/null # 检查3306端口是否被占用 ss -lntp | grep 3306这几条命令的输出决定了后续是直接装还是先清理一波。很多教程不会讲这个准备步骤但这恰恰是线上服务器安装最常踩的雷。2. 安装方式的选择官方仓库、二进制包、源码编译还是容器2.1 四种方式的优缺点对比我见过有些人一上来就编译源码搞得特别复杂。实际上MySQL的安装方式至少有四种每种都有自己的适用场景没必要为了“显得专业”而去编译。安装方式优点缺点适用场景官方Yum/Apt仓库依赖自动解决、升级方便、默认配置规范需要联网、仓库地址需要额外配置绝大多数联网服务器通用二进制包不依赖网络、路径可控、适合离线环境需要手动处理依赖、后续升级麻烦内网环境、特殊定制路径源码编译可自定义编译参数、性能可优化编译时间长、依赖多、容易出错特殊硬件平台、深度优化需求Docker容器部署快、隔离性好、环境一致数据卷管理有门槛、性能略损耗开发测试、微服务场景2.2 为什么我推荐官方仓库如果你问我的意见常规环境我优先推荐官方仓库。原因有三点第一依赖自动解决。MySQL不是单个二进制文件它依赖libaio、ncurses等一堆基础库用通用二进制包的时候缺哪个就得手动装哪个来回折腾。用仓库安装包管理器会把这些依赖一并处理掉。第二后续升级很简单。直接yum update mysql-server或者apt upgrade就能升级小版本安全补丁可以及时打上。二进制包想升级就得重新下载、重新部署很麻烦。第三配置文件和服务脚本规范。官方仓库装出来的服务脚本、日志路径、目录权限都是约定俗成的出了问题网上能搜到大量一致的经验。二进制包如果自定义路径很多默认行为会变得“和别人不一样”。2.3 什么情况选通用二进制包通用二进制包Generic Binary并非一无是处。如果你所在的内网环境无法访问外网或者公司要求MySQL必须装在/opt/mysql这种非标准路径二进制包反而是最佳选择。它本质上就是把官方编译好的文件解压到指定目录然后手动初始化数据目录、创建系统用户、编写服务脚本。操作逻辑不复杂但步骤琐碎。我这里提一下不做展开因为大多数读者用不到。容器方式则适合开发环境快速起一个实例docker run -d --name mysql -e MYSQL_ROOT_PASSWORDxxx -p 3306:3306 mysql:8.0一行搞定。但生产环境的性能和数据卷管理建议还是老老实实用物理机或虚拟机安装。3. 从零开始官方仓库一步步安装MySQL 8.0的完整流程3.1 配置官方Yum仓库我以CentOS 7为例先把官方仓库装上去# 安装官方MySQL Yum仓库 rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm如果是Rocky/AlmaLinux 9把el7替换成el9CentOS 8替换成el8。安装完仓库包后查看一下仓库列表确认生效yum repolist enabled | grep mysql正常情况下会看到mysql80-community这一行。这一步做完系统就知道去哪里找MySQL 8.0的rpm包了。3.2 清理旧的MariaDB残留如果第1步检查发现有MariaDB建议先卸载systemctl stop mariadb # 先停服务 yum remove -y mariadb* rm -rf /var/lib/mysql # 删除旧数据目录这一步要谨慎。/var/lib/mysql里面如果有你之前的重要数据先备份再删。在真实服务器上删除数据目录之前一定要三思。我自己曾经因为图省事直接删结果发现里面是一个测试环境的历史数据虽然不心疼但也被同事提醒了一顿。数据无价操作要规范。3.3 安装MySQL服务端和客户端yum install -y mysql-community-server mysql-community-client这里mysql-community-server是服务端mysql-community-client是命令行客户端。有些教程只装server默认会连带把client装上但为了明确我习惯两项都写上。安装过程会自动创建mysql系统用户和/var/lib/mysql数据目录。装完之后可以用rpm -qa | grep mysql确认版本一般来说会看到mysql-community-server-8.0.x。3.4 启动服务并获取初始密码MySQL 8.0在首次启动时会自动初始化数据目录并生成一个临时root密码这个密码只能通过日志文件查看systemctl start mysqld systemctl status mysqld # 查看初始密码 grep temporary password /var/log/mysqld.log输出类似这样[Note] A temporary password is generated for rootlocalhost: xxxxxxxx把这个临时密码记下来下一步要用。如果日志里没找到可能是/var/log/mysqld.log路径不同用find / -name mysqld.log找一下。3.5 Ubuntu/Debian系统的差异Ubuntu/Debian系统的流程类似但仓库包换成了deb格式# 下载官方apt仓库配置包 wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb dpkg -i mysql-apt-config_0.8.29-1_all.deb # 弹窗里选择MySQL 8.0然后OK apt update apt install -y mysql-serverUbuntu安装过程中会直接让你设置root密码比CentOS少一个“扒日志找临时密码”的步骤。但Ubuntu的MySQL配置文件是/etc/mysql/mysql.conf.d/mysqld.cnf和CentOS的/etc/my.cnf不一样这是一个容易混淆的点。4. 初始化安全配置与基础设置别让数据库“裸奔”4.1 跑一遍安全初始化脚本拿到临时密码后第一件事是登录并跑安全初始化脚本mysql -uroot -p # 输入上面日志里的临时密码登录成功后执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的新密码; FLUSH PRIVILEGES;注意MySQL 8.0 默认密码策略要求密码至少8位且包含大小写字母、数字和特殊字符。如果你设置的密码太简单会直接报ERROR 1819。这也是很多新手觉得自己“密码明明输对了却设置失败”的原因。跑安全脚本的方式有两种一种是交互式执行mysql_secure_installation按提示一步步来另一种是手动执行SQL。我个人更推荐手动SQL因为交互式脚本在自动化部署时不好处理。下面是完整的初始化SQLALTER USER rootlocalhost IDENTIFIED BY StrongPassw0rd; -- 删除匿名用户默认MySQL已经不存在匿名用户这步可以跳过) DROP USER IF EXISTS localhost; -- 删除测试数据库 DROP DATABASE IF EXISTS test; FLUSH PRIVILEGES;4.2 理解MySQL 8.0的密码验证策略安装完成后默认的密码策略是validate_password.POLICY 1MEDIUM级别。这个策略直接影响后续创建用户的体验。如果你是在开发环境希望密码简单一点可以降低策略SET GLOBAL validate_password.policy LOW; SET GLOBAL validate_password.length 6;但这只是在运行时生效重启后会恢复默认。想永久修改需要在/etc/my.cnf的[mysqld]段加上[mysqld] validate_password.policy LOW validate_password.length 6顺便说一下MySQL 8.0里validate_password是插件不是单独的服务。如果SET GLOBAL时报变量不存在多半是插件没有加载需要检查INSTALL COMPONENT file://component_validate_password;是否执行过。4.3 创建专属账号不要总用root我见过太多人所有应用都用root连数据库这是一个很不好的习惯。root在MySQL里拥有全部权限一旦业务连接串泄露等于把整个数据库拱手让人。正确的做法是为每个应用创建独立的账号只授权需要的库CREATE USER app_userlocalhost IDENTIFIED BY AppPassw0rd; GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO app_userlocalhost; FLUSH PRIVILEGES;这里的mydb.*表示mydb库下的所有表。如果应用需要从远程连接把localhost换成%或者具体IP网段。注意app_user%和app_userlocalhost是两个不同的账号可以共存。4.4 统一字符集避免中文乱码MySQL 8.0默认字符集已经是utf8mb4但老版本迁移过来的库可能是latin1或utf8mb3。为了避免中文乱码建议在/etc/my.cnf中显式设置[mysqld] character-set-server utf8mb4 collation-server utf8mb4_unicode_ci [client] default-character-set utf8mb4然后重启MySQLsystemctl restart mysqld登录后查看SHOW VARIABLES LIKE character_set%; SHOW VARIABLES LIKE collation%;如果所有character_set_*开头的变量都是utf8mb4就说明配置生效了。这里有个小技巧character_set_database和character_set_server这两个变量最容易漏因为它们是由建库时的默认值决定的。新建库之前确认好否则后续改起来很麻烦。4.5 设置开机自启这一步最简单但也最容易被忽略systemctl enable mysqld如果你用docker run跑的MySQL要设置restart: always策略否则机器重启后容器不会自动拉起。5. 安装后必踩的几个坑error 2002与连接异常5.1 error 2002的完整排查链路ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock这个报错几乎每个MySQL新手都会遇到。它的字面意思是客户端尝试通过socket文件连接MySQL服务但连接失败。注意这里的关键词是socket文件不是TCP端口。出现这个错误按下面的链路排查第一步确认服务是否在运行systemctl status mysqld如果服务没启动先systemctl start mysqld再看。第二步如果服务在运行确认socket文件的实际位置find / -name *.sock -o -name mysql.sock 2/dev/null通常socket文件应该在/var/run/mysqld/mysqld.sock或者/tmp/mysql.sock具体位置由配置文件决定。可以查看grep -r socket /etc/my.cnf /etc/mysql/ 2/dev/null第三步如果socket文件路径和报错里的路径不一致说明默认找错了。可以直接指定socket路径连接mysql -uroot -p --socket/var/run/mysqld/mysqld.sock或者改用TCP方式连接mysql -uroot -p -h 127.0.0.1 -P 3306我遇到的实际情况是大多数error 2002都是因为服务根本没启动或者服务启动后socket文件被清理了。前者用systemctl start解决后者一般是权限或SELinux问题需要往下查。5.2 MySQL 8.0认证插件导致的连接失败装好MySQL 8.0后如果本地连接正常但从另一台机器用客户端连不上报错往往是Authentication plugin caching_sha2_password cannot be loaded或者Access denied。原因MySQL 8.0默认的认证插件是caching_sha2_password而很多老版本客户端比如5.7时代编译的PHP扩展、老版Navicat不支持这个插件。解决办法有两种第一种创建用户时指定老认证插件CREATE USER app_user% IDENTIFIED WITH mysql_native_password BY password;第二种修改已有用户的认证方式ALTER USER app_user% IDENTIFIED WITH mysql_native_password BY password;或者在/etc/my.cnf里全局指定默认认证插件[mysqld] default_authentication_plugin mysql_native_password不过我个人不建议一上来就全局改默认插件因为这等于放弃8.0的更强认证方式。更好的做法是升级客户端新版本客户端都支持caching_sha2_password。只有实在无法升级客户端时才用mysql_native_password兼容。5.3 防火墙和SELinux连不上的“隐形元凶”如果你从远程连接时发现端口超时、或者一开始能连后来突然连不上多半是防火墙或SELinux的问题。CentOS 7/RHEL 7默认防火墙是firewalld检查3306端口是否放行firewall-cmd --list-ports # 添加端口 firewall-cmd --permanent --add-port3306/tcp firewall-cmd --reload如果你用的云服务器还要在云控制台的安全组里放行3306端口。这一步即使本地防火墙开了安全组不放行也是白搭。SELinux的问题更隐蔽。查看SELinux状态getenforce如果是EnforcingMySQL可能会被限制。解决方式# 允许MySQL网络连接 setsebool -P mysql_connect_any 1 # 或者为3306端口添加SELinux端口映射 semanage port -a -t mysqld_port_t -p tcp 3306如果semanage命令不存在需要先安装policycoreutils-python-utils或者policycoreutils-python包。5.4 数据目录权限错误还有一类比较常见的启动失败场景systemctl start mysqld直接报[ERROR] Could not open required defaults file或者Permission denied。这通常是数据目录或配置文件的属主不对。chown -R mysql:mysql /var/lib/mysql chown -R mysql:mysql /var/run/mysqld chmod -R 750 /var/lib/mysql然后重启服务。这一点在恢复备份、迁移数据目录时特别容易踩因为拷贝文件会改变属主和权限。6. 装好之后的日常管理与常用操作6.1 服务管理的基本命令安装完成、测试能连上后先把这几个命令记牢。我每天在服务器上用得最多的就这几个systemctl start mysqld # 启动 systemctl stop mysqld # 停止 systemctl restart mysqld # 重启 systemctl status mysqld # 查看状态 systemctl enable mysqld # 设置开机自启日志文件默认在/var/log/mysqld.log排查问题时第一件事看这个文件的尾部tail -100 /var/log/mysqld.log6.2 日常高频SQL操作速查安装完之后紧接着面临的就是日常使用。以下是几个我帮别人排查问题时经常用到的SQL也是很多新手刚学MySQL时容易搞混的修改一条记录UPDATE users SET status 1 WHERE id 10;注意MySQL 8.0如果以safe-update模式启动不带WHERE条件的UPDATE会直接报错。这是个保护机制能防止误操作。日常操作中执行UPDATE前最好先用SELECT确认条件SELECT * FROM users WHERE id 10; UPDATE users SET status 1 WHERE id 10;排序查询SELECT * FROM products ORDER BY price DESC LIMIT 10;ORDER BY默认是升序ASC降序要显式写DESC。设置字段默认值ALTER TABLE orders ALTER COLUMN status SET DEFAULT 0;ALTER COLUMN ... SET DEFAULT用于修改默认值很多人容易把它和ALTER TABLE ... MODIFY COLUMN搞混。前者只改默认值后者会重定义整列类型和约束。6.3 保留一个基础备份习惯装好MySQL之后我最想强调的一件事不是配置调优而是备份。我见过太多人在装完之后立刻开始建库建表却从没想过如果数据没了怎么办。最简单的逻辑备份工具是mysqldump一条命令就能备份整个库mysqldump -uroot -p --single-transaction --routines --triggers --events mydb mydb_backup_$(date %F).sql恢复的时候mysql -uroot -p mydb mydb_backup_$(date %F).sql--single-transaction参数是InnoDB引擎下保证备份一致性又不锁表的关键生产环境务必加上。--routines、--triggers、--events分别备份存储过程、触发器、事件很容易被忘掉。个人建议安装配置完成后先把这个备份命令放到crontab里就不用担心数据丢了0 2 * * * /usr/bin/mysqldump -uroot -p密码 --single-transaction --routines --triggers --events mydb /backup/mydb_$(date \%F).sql7. 最后再补充几个实操细节这篇关于Linux MySQL安装的教程主要流程到这里基本结束了但我还有几个实操细节想单独提一下这些都是我真实经历后觉得值得记下来的点。第一个细节装完后别急着调参。我看过很多人装完MySQL第一件事就是改innodb_buffer_pool_size、max_connections觉得自己调优很专业。但实际上初期除非明确知道业务压力否则默认配置已经经过了官方优化。我以前在一台8G内存的服务器上把innodb_buffer_pool_size调到6G结果系统直接卡死因为忘了还有操作系统和其他服务在跑。合理做法是先用默认配置跑一段时间看SHOW ENGINE INNODB STATUS和SHOW GLOBAL STATUS再决定怎么调。第二个细节用mysql_config_editor保存登录凭据别把密码写在命令行里。如果你要把自动备份写进crontab密码写在命令行里会导致两个问题一是ps命令能看到密码有泄露风险二是密码里有特殊字符时shell转义特别容易出错。更安全的做法是mysql_config_editor set --login-pathbackup --hostlocalhost --userroot --password然后备份命令变成mysqldump --login-pathbackup --single-transaction --routines --triggers --events mydb mydb_backup.sql密码不再出现在命令行里日志和进程列表都干净了。第三个细节MySQL 8.0的caching_sha2_password首次连接会走TLS或者RSA密钥交换如果你是在纯内网环境、且客户端版本较老第一次连接可能会卡住或报错Public Key Retrieval is not allowed。解决方法有两个连接串里加allowPublicKeyRetrievaltrue或者用户指定用mysql_native_password。我处理过一个客户环境就是卡在这里折腾半天才发现是JDBC连接串参数问题。第四个细节my.cnf配置文件的层级。Linux下MySQL会依次读取/etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf等文件后面读取的配置会覆盖前面的。如果发现某个参数改了没生效先查一下是不是被后面的配置文件覆盖了。我遇到过一次改了/etc/my.cnf但没生效排查半天发现是/etc/mysql/conf.d/下有个残留的配置文件把它压过去了。踩过几次坑之后我现在装MySQL已经形成了一套固定动作先确认系统版本和包管理器再检查残留接着装官方仓库、安装、启动、查临时密码、改密码、安全初始化、建业务账号、配字符集、开自启、做一次备份最后才交给业务部署。这套流程走下来基本没有再翻过车。你按这个思路走大概率也能一次顺利跑通。