ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ubuntu下MySQL安装配置与高频问题排查实战指南

Ubuntu下MySQL安装配置与高频问题排查实战指南 自己折腾服务器和开发环境这些年Ubuntu和MySQL这对组合算是绕不开的老搭档了。无论你是刚接触Linux的学生还是要在生产环境部署JavaWeb项目的开发者大概率都要在Ubuntu上跟MySQL打交道。网上关于MySQL安装的教程不少但要么写得云山雾罩要么直接照搬CentOS的rpm思路在Ubuntu上踩得头破血流。我最早在Ubuntu 16.04上装MySQL 5.7后来一路升级到20.04、22.04中间踩过SSL连接报错、root密码忘记、环境变量搞乱导致命令找不到这些坑。这篇文章就把我在Ubuntu下安装、配置、排查MySQL的完整经验整理出来从装前准备、核心安装步骤、日常运维操作到高频问题排查一条龙讲透。适合刚接触Linux的初学者也适合被MySQL折磨过想彻底搞明白的老手。1. 内容整体设计与思路拆解1.1 为什么选Ubuntu而不是其他发行版Linux发行版几十上百个但Ubuntu在开发者群体里的占比一直很稳。原因不复杂社区活跃、资料多、软件源覆盖全。遇到任何问题基本Google一搜就有前人踩坑的答案。对比一下几个主流发行版你就能明白为什么大家默认选Ubuntu发行版包管理MySQL安装方式上手难度Ubuntu/Debianapt/dpkg官方源直接装依赖自动解决低CentOS/RHELyum/dnf默认源是老版本需额外配源或用rpm包中偏高Arch Linuxpacman滚动更新版本最激进偏高CentOS系装MySQL最麻烦的一点是源里只有老版本MariaDB要装真正的MySQL还得去下载rpm包或者用官方仓库而rpm安装时如果依赖没准备好那才是真正的噩梦。Ubuntu这边就简单很多apt直接搞定依赖一条命令装完这也是我在Ubuntu上装MySQL最省心的地方。1.2 用apt装还是用源码编译装在Ubuntu下装MySQL主流的路径有三条apt install直接装最简单粗暴官网源或系统源里的预编译包安装、升级、卸载都交给包管理器对大多数人是首选。下载官网tar包手动部署适合需要特定版本比如老项目指定MySQL 5.7、或者想自定义安装路径的场景。但依赖问题全得自己解决配置环境变量、初始化数据目录、配systemd服务一套流程走完挺折腾。源码编译安装基本只有二次开发或者极其特殊的需求才会这么干编译一次大几十分钟对普通业务开发没多大意义。我最推荐的是第一种。MySQL 8.0官方早已在Ubuntu源里准备好了除非你项目里明确锁死了某个小版本否则没必要自己从官网下tar包。二进制版本和apt版本在性能上没有任何差别但apt版本能帮你自动管理依赖和服务脚本省下大把时间。有人可能担心apt源里的版本太老。这个顾虑在MySQL 8.0时代基本上不存在了Ubuntu 20.04及之后的源里MySQL 8.0版本会跟着安全更新补丁走。真到了哪天你需要某个特定小版本再考虑下载官方tar包也不迟。1.3 到底该装MySQL还是MariaDB刚接触的人可能被搞懵为什么Ubuntu上装MySQL有时候装出来却是MariaDB这里面的历史原因是2010年后MySQL被Oracle收购MySQL的创始人Monty创建了MariaDB分支并且Debian/Ubuntu的某些版本里默认的mysql-server包被替换为MariaDB的兼容包。如果你在Ubuntu 18.04上直接执行apt install mysql-server装出来的确实是MariaDB容易让人摸不着头脑。但在Ubuntu 20.04及以后mysql-server包恢复为真正的MySQL 8.0。所以版本不同行为差别很大。如果你在旧版Ubuntu上或者对装出来的版本心存疑虑最快的确认方式就是登进去看mysql --version我见过不少人在老教程引导下在Ubuntu上装完MySQL拿root登录密码死活不对最后才发现自己其实是装了个MariaDB很多命令和参数都不一样。所以动手之前先搞清楚版本免得白忙活。2. 核心细节解析与实操要点2.1 在Ubuntu 22.04上安装MySQL 8.0的完整步骤先交代一下环境我以下操作基于Ubuntu 22.04 LTS虽然20.04和24.04操作几乎一致MySQL 8.0。如果是全新系统第一步永远是更新软件源sudo apt update sudo apt upgrade -y这个步骤很多人喜欢跳过觉得反正装软件时apt会自动处理依赖。但我的建议是从一开始就做原因有两个一是系统里如果残留有老版本MySQL相关组件不更新索引直接装容易撞上依赖冲突二是新系统里有些基础依赖如libaio1可能没装全更新一遍能省去后面的麻烦。接下来安装MySQL服务端一条命令搞定sudo apt install -y mysql-server注意这里装的是服务端包含了mysqld进程、数据目录初始化、systemd服务脚本。如果你只需要客户端比如只连远程数据库装mysql-client就够了但大多数情况下我们两个都要直接装server会连带把client也装上。安装过程在Ubuntu 22.04上会自动完成数据目录初始化。这里有个和旧版本很大的不同MySQL 8.0初始安装后root账号的认证方式默认是auth_socket也就是说只要你用系统的root用户或者sudo权限就能直接登进MySQL不需要密码。验证一下是否安装成功systemctl status mysql如果看到active (running)说明服务已经起来了。然后用下面的命令登录sudo mysql能进入mysql提示符就代表安装成功了。2.2 初始安全配置与root密码设置很多新手卡在这一步明明装好了但不知道root密码是啥用密码登录总是失败。前面说了MySQL 8.0默认root走的是auth_socket插件所以你需要先用sudo mysql进去自己设置密码ALTER USER rootlocalhost IDENTIFIED WITH caching_sha2_password BY 你的密码; FLUSH PRIVILEGES;执行完这步root密码就生效了。把caching_sha2_password改成mysql_native_password也是常见的操作因为一些老版本客户端比如老Navicat不支持caching_sha2_password。不过MySQL 8.0官方推荐用caching_sha2_password在安全性和性能上都更好。如果你用的客户端足够新建议保持默认不需要改。设置好密码后跑一下官方自带的安全加固脚本sudo mysql_secure_installation这个脚本会问你几个问题是否设置密码强度、是否删除匿名用户、是否禁止root远程登录、是否删除test数据库。除非你明确知道自己在干什么否则一律Y。特别是“禁止root远程登录”这一项很多人为了方便想选N但安全角度强烈建议Y。远程连接请单独创建业务账号不要让root暴露在网络上。操作完以后可以顺手验证一下密码登录是否正常mysql -u root -p输入刚才设置的密码能进就说明一切OK。2.3 字符集配置为什么你总是看到乱码中文乱码估计是MySQL使用中最高频的痛点之一。在MySQL 8.0里默认字符集是utf8mb4这对中文用户已经很友好了。但如果你是从老项目数据库迁移过来的或者建表时没指定字符集还是会遇到乱码问题。先查看当前的字符集配置SHOW VARIABLES LIKE character_set%;最理想的情况是这样--------------------------------------------------------------- | Variable_name | Value | --------------------------------------------------------------- | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | ---------------------------------------------------------------如果不是这样可以修改配置文件。编辑MySQL配置文件sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf在[mysqld]段下添加[mysqld] character-set-server utf8mb4 collation-server utf8mb4_unicode_ci然后重启服务sudo systemctl restart mysql重新登录查看应该就是utf8mb4全家桶了。这里我要多说两句。老教程里经常会让人改成utf8但utf8在MySQL里是utf8mb3的别名只能存基本平面字符像emoji、生僻汉字这些根本存不进去。utf8mb4才是真正的四字节UTF-8能覆盖所有Unicode字符。从2010年的MySQL 5.5.3开始就有这个选项了但直到8.0它才成为默认值。新库一律用utf8mb4别犹豫。2.4 防火墙与远程连接授权Navicat为什么连不上装好MySQL后大部分人都会遇到一个问题本地登录没问题用Navicat或者别的客户端从别的主机连怎么都连不上。原因就两个防火墙没放行3306端口或者MySQL的用户权限只允许localhost访问。先说防火墙。Ubuntu默认用的是ufw查看3306端口是否放行sudo ufw status如果状态是inactive说明防火墙没开那问题就不在这。如果开着需要放行MySQL端口sudo ufw allow 3306/tcp再说MySQL授权。MySQL用户是按“用户名主机”来区分的rootlocalhost只允许本机连远程主机过来会被拒绝。正确的做法是创建一个专门用于远程连接的用户CREATE USER app_user% IDENTIFIED BY 强密码; GRANT ALL PRIVILEGES ON *.* TO app_user%; FLUSH PRIVILEGES;这里的%表示任意主机也可以指定具体IP比如app_user192.168.1.100更安全。创建用户时还有个小细节。MySQL 8.0默认的密码加密方式是caching_sha2_password如果你的Navicat版本比较老8.0以下可能不认识这个加密方式连接时报Authentication plugin caching_sha2_password cannot be loaded。解决办法有两个一是升级Navicat到16以上二是把用户的认证方式改成老式的ALTER USER app_user% IDENTIFIED WITH mysql_native_password BY 强密码;不过还是要强调一下mysql_native_password属于历史遗留方案新项目尽量用新客户端caching_sha2_password。安全性和性能上新的加密插件都要好很多。3. 实操过程与核心环节实现3.1 忘了root密码怎么重置常见场景复盘这个场景太经典了。我接手过几次同事的开发机MySQL的root密码被前一个人改过谁都不知道是什么项目又急着要跑起来。网上给的通用方案就是skip-grant-tables但在MySQL 8.0下操作细节跟老版本有出入。先停掉MySQL服务sudo systemctl stop mysql然后以跳过权限表的方式启动sudo mysqld_safe --skip-grant-tables 这里有个要注意的点mysqld_safe启动时会以后台方式运行但如果你的系统里mysqld没能正常进入skip-grant-tables模式后面的操作会白做。所以启动后稍等两秒确认进程真的存活了再继续ps -ef | grep mysqld看到mysqld_safe和mysqld进程都在再登录进MySQLmysql -u root注意这种模式下不需要密码就能登录。但坑点来了在skip-grant-tables状态下你直接执行ALTER USER改密码可能会报错因为权限系统压根没加载。更稳妥的做法是先刷新权限表让当前会话获得正常权限FLUSH PRIVILEGES;然后再改密码ALTER USER rootlocalhost IDENTIFIED BY 新密码;改完退出杀掉mysqld进程再正常启动sudo pkill mysqld sudo systemctl start mysql用新密码登录验证mysql -u root -p这个流程我在MySQL 8.0.28和8.0.32上都验证过没问题。核心就是在改密码前一定要执行FLUSH PRIVILEGES不然会撞上权限表未加载的各种诡异报错。3.2 环境变量配置错误导致的mysql命令找不到当你用源码包方式安装MySQL时会遇到一个很典型的问题明明装好了mysql这个命令却提示command not found。这是因为MySQL的可执行文件目录比如/usr/local/mysql/bin没有被加进PATH环境变量。我见过有人去修改/etc/environment文件结果格式写错导致整个系统登录后所有命令都找不到网卡、蓝牙全出问题。这里提供一个安全且永久的配置方法。先确认MySQL的bin目录在哪里。如果是apt安装的默认在/usr/bin一般不需要配。如果是源码安装或tar包部署路径可能在/usr/local/mysql/bin。确认路径后编辑~/.bashrcecho export PATH$PATH:/usr/local/mysql/bin ~/.bashrc source ~/.bashrc这种配法只对当前用户生效不会影响系统其他用户或服务改坏了也只会让当前用户的shell出问题重启终端就好。为什么我不推荐直接改/etc/environment因为那个文件是系统级的里面格式要求非常严格比如不能带export关键字、每行不要有多余空格。一旦写错图形界面都没法正常登录排查起来极其痛苦。配置完成后还需要让MySQL的库文件能被动态链接器找到否则运行mysql时报错libmysqlclient.so: cannot open shared object file。编辑/etc/ld.so.conf.d/mysql.confecho /usr/local/mysql/lib | sudo tee /etc/ld.so.conf.d/mysql.conf sudo ldconfig这步很多人会漏掉等报错了才一头雾水。提前做好后面少绕弯。3.3 常用运维命令与SQL实战装好MySQL只是开始日常用得最多的操作还得熟练。我整理一下自己在生产环境天天用、新手却容易搞混的几个命令。服务管理systemctl status mysql # 查看状态 systemctl restart mysql # 重启 systemctl enable mysql # 开机自启查看数据库和表SHOW DATABASES; USE 数据库名; SHOW TABLES; DESC 表名;这三个命令是入门必会的SHOW系列在排查问题时候特别有用比如SHOW PROCESSLIST;能看当前所有连接在干什么数据库卡住时第一反应就是执行它看看有没有长时间Sleep或Locked的会话。字符串转日期这个是高频率操作强烈建议记牢。业务表里经常有用户传过来的2024-08-15 14:30:00这种字符串需要转成DATE或DATETIME类型再做比较。MySQL提供了STR_TO_DATE函数SELECT STR_TO_DATE(2024-08-15 14:30:00, %Y-%m-%d %H:%i:%s);反过来把日期格式化输出用DATE_FORMATSELECT DATE_FORMAT(NOW(), %Y年%m月%d日);设置默认值为0这个也是高频需求。MySQL 8.0里如果某字段需要默认值0建表时可以直接写CREATE TABLE example ( id INT PRIMARY KEY AUTO_INCREMENT, status TINYINT NOT NULL DEFAULT 0 );如果你用的是老版本MySQL5.7之前某些字段类型比如TEXT、BLOB不允许设置默认值这是一个历史限制8.0时代已经放宽了但建表时养成指定DEFAULT的习惯依然是好习惯。存储过程JavaWeb项目里偶尔会用到存储过程来封装复杂查询逻辑。一个最简单的示例DELIMITER // CREATE PROCEDURE get_user_count() BEGIN SELECT COUNT(*) FROM users; END // DELIMITER ; CALL get_user_count();注意DELIMITER的使用因为默认分号会让MySQL在遇到分号时就结束输入用DELIMITER //先换掉结束符才能完整输入整个存储过程。这个细节写SQL脚本时特别容易踩坑。4. 常见问题与排查技巧实录4.1 SSL连接错误报错信息看不懂怎么办MySQL 8.0默认开启了SSL连接这本身是好事但有时候会带来奇奇怪怪的问题。最常见的一个报错是ERROR 2026 (HY000): SSL connection error: protocol version mismatch或者客户端连接时报SSL connection error: error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol。出现这个问题的原因通常是客户端支持的SSL/TLS协议版本太旧而MySQL 8.0要求的最低版本是TLS 1.2。老客户端尤其是系统自带的旧版libmysqlclient或者老Navicat只支持TLS 1.0/1.1两边匹配不上就报错。解决办法有三种按推荐程度排序第一种升级客户端把Navicat、mysql-connector-java这些更新到支持TLS 1.2的版本。这是最一劳永逸的方案。第二种临时指定--skip-ssl只是紧急排查用不推荐生产环境这么干mysql -u root -p --skip-ssl第三种调整MySQL服务端的ssl配置如果确实有老客户端必须连可以在配置里放宽TLS版本要求[mysqld] tls_version TLSv1.2,TLSv1.3注意MySQL 8.0.16之后的版本tls_version参数只接受TLSv1.2和TLSv1.3老版本参数会自动忽略。别想着把TLSv1和TLSv1.1加回去8.0已经不支持了。如果只是测试环境也可以直接禁用SSL[mysqld] skip_ssl但强烈不建议在生产环境这样干数据在传输过程中就是裸奔的。安全性和便利性的权衡最终还是要自己拿捏。4.2 安装过程中出现错误代码0x80070424的含义这个报错很有意思我一开始是在Windows上装Ubuntu子系统时遇到的但接着在Linux环境配置MySQL时也有不少朋友遇到类似的报错困扰。错误代码: 0x80070424是Windows系统服务的错误意思是“指定的服务未安装或已禁用”。场景通常是你在Windows上通过WSL或者虚拟机操作Ubuntu想在Windows服务管理器里启动某个依赖服务结果服务本身不存在。要注意的是这不属于Linux环境的问题纯粹是Windows层的服务状态不对。在Ubuntu虚拟机里跑MySQL时我更常遇到的是另一个类似的坑启动虚拟机后MySQL服务没有自动起来连接时报Cant connect to local MySQL server through socket。排查步骤systemctl status mysql如果不是active状态直接启动systemctl start mysql如果启动失败看错误日志sudo tail -100 /var/log/mysql/error.log日志里最关键的信息是最后几行。常见的启动失败原因包括数据目录权限不对、磁盘空间满、配置文件的某个参数写错。有一次我在配置里手滑加了一个不存在的变量MySQL直接拒绝启动日志里报unknown variable改掉就好了。这些细节光看报错信息可能一头雾水日志会直接告诉你答案。4.3 忘记Ubuntu系统登录密码和MySQL密码的组合排查作为开发机常常是整个系统密码和MySQL密码一起忘掉。如果你遇到的是这种情况处理顺序要理清先搞定系统登录密码再处理MySQL密码。Ubuntu系统密码重置有一个固定的方法开机时在GRUB菜单选择Advanced options for Ubuntu选recovery mode然后在Recovery Menu里选择root。进入root shell后用passwd 用户名重置密码。这套操作本质上就是通过单用户模式绕过登录认证。平时用得少真到用的时候救命的建议收藏一下。MySQL密码的忘记处理我在前面3.1已经写过了这里就不再重复。需要强调的是以上所有重置操作完成后务必确认一件事检查有没有开启自动更新以及MySQL的binlog是否正常记录。因为密码遗忘往往发生在项目濒临上线或者赶工期的节点数据安全反而比密码本身更重要。4.4 高频问题速查表有些问题遇到太多次了我直接整理成一个速查表按图索骥省得翻来翻去现象可能原因解决办法安装后无法用密码登录root8.0默认auth_socket认证sudo mysql进入后ALTER USER设置密码远程连接超时ufw或iptables未放行3306sudo ufw allow 3306/tcpNavicat连接报plugin错误客户端不支持caching_sha2_password升级客户端或改mysql_native_passwordSSL connection errorTLS版本不匹配升级客户端或服务端配置tls_versionmysql: command not foundbin目录不在PATH路径添加export PATH$PATH:/usr/local/mysql/bin中文乱码字符集不是utf8mb4修改mysqld配置文件并重启我把排查思路提炼成这样先看服务状态再看错误日志最后才动配置。很多人一遇到问题上来就改配置越改越乱。记住一个字稳。4.5 从虚拟机到云服务器的路径差异最后说一个话题很多人在自己虚拟机上把MySQL装好了、一切都正常但一到云服务器上就到处碰壁。这里面有环境差异的问题也有安全策略的问题。虚拟机的网络一般是NAT模式或者桥接模式默认情况下防火墙配置也比较宽松所以MySQL装完就能连。云服务器则不然除了操作系统层面的防火墙还有一个安全组的概念。安全组规则的优先级比系统防火墙还高必须先去云控制台把3306端口加入入站规则否则你在操作系统里把ufw关了也白搭。另一个差异是配置。云服务器的机器配置一般不高内存可能就2G或者4G这时候MySQL 8.0默认的缓冲池大小可能直接把内存吃满导致系统OOM。建议在配置里显式调小一点[mysqld] innodb_buffer_pool_size 256M256M对于2G内存的机器来说是一个比较稳的值既保证查询性能又留出系统和其他服务的余量。我自己实际在云服务器部署时踩过这样一个坑执行apt install mysql-server后系统占用直接飙升到90%。排查下来就是默认配置把缓冲池设置得太大了。改成256M后内存降到40%以下问题解决。配置完成后记得sudo systemctl restart mysql才能让参数生效。这篇内容从头到尾都是我在各种场景里实际折腾MySQL的积累希望能帮你少走点弯路。安装只是第一步后面运维和排查才是真正花时间的地方。如果你按照这篇文章的步骤走下来还是遇到问题优先去看MySQL的错误日志日志里不会说谎。
返回列表