资讯动态

Ubuntu下MySQL 8.0保姆级安装配置与实战演练

发布时间:2026/9/9 22:33:34 来源:尧图企业网站定制
1. 为什么我在Ubuntu上折腾MySQL选型与场景分析很多朋友一提到在Ubuntu下安装MySQL第一反应就是去官网下载一个压缩包或者deb包然后一路“下一步”。我早期也是这么干的但踩过几次坑之后我老实了。Ubuntu的软件源里其实已经维护了非常好用的MySQL版本包直接“apt install”就能装好省去了一堆依赖问题。尤其做数据库课程设计、本地开发调试甚至小型生产环境Ubuntu用自带源反而比“官网豪华套餐”更省心。这篇博文我会完全按照自己在Ubuntu 22.04/24.04上实操MySQL 8.0的经验来讲从安装方式选型到安装配置、常用SQL、存储过程、授权管理、Workbench连接、常见坑排查一条龙走完。适合刚接触Linux的数据库新手也适合要交课程设计或者准备数据库面试、需要一套能跑通的环境的同学。先说结论如果你只是想在本地跑一个MySQL用来学习、做课程设计、测试业务代码直接用“apt install mysql-server”就行别去官网折腾。如果你的场景是搭集群、搞高可用、对版本有严格的企业级管控需求再考虑用官方仓库或源码编译我会在后面详细说明原因。2. 安装前的环境准备与选型逻辑2.1 为什么优先选apt源而不是官网压缩包Ubuntu的apt源中提供了“mysql-server”和“mysql-client”两个核心包安装时会自动解决依赖比如“libaio1”、配置文件目录、系统服务脚本等。官网提供的通用Linux压缩包tar.gz虽然“纯净”但需要手动初始化数据目录、手动配置系统服务、手动处理socket路径和pid文件这些对新手来说很容易出幺蛾子。还有一种是添加MySQL官方APT仓库然后通过apt安装官方维护的版本。这种方式的优点是你能拿到Oracle官方编译的二进制包比Ubuntu源里的版本更新比如Ubuntu 22.04自带源默认是MySQL 8.0.35左右官方仓库可能已经更新到8.0.40。缺点是你在“sources.list”里引入了一个外部源有安全风险而且每次系统升级时可能出现“apt update”报错的情况。我自己用的策略是学习环境直接用Ubuntu源生产环境或者需要特定版本时用官方APT仓库但会锁定版本号不随意升级。2.2 开始之前先更新系统并检查是否已有MySQL不管用哪种方式第一步永远是更新索引。这一步虽然简单但很多人忽略导致后面安装时报“Package not found”。sudo apt update sudo apt upgrade -y然后检查系统里是否已经存在MySQL或MariaDB。很多Ubuntu镜像会预装MariaDB因为它和MySQL兼容但如果你要学的是正统MySQL建议先卸载干净避免端口和socket冲突。dpkg -l | grep -E mysql|mariadb如果有输出根据情况决定保留还是卸载。我遇到过一台机器上同时装了MariaDB和MySQL导致“mysql.service”启动失败就是因为“/var/run/mysqld”目录的权限被MariaDB抢先占了。2.3 确认系统版本与架构不同版本的Ubuntu包的版本和配置路径有点差异。查看系统信息lsb_release -a uname -m比如我目前用的是Ubuntu 24.04 LTSx86_64架构apt源里的MySQL版本是8.0.x。如果你的系统是22.04安装步骤完全一样如果是20.04也支持但默认版本可能是5.7或8.0具体以“apt-cache policy mysql-server”为准。3. 保姆级安装与基础配置实操3.1 使用apt完成MySQL 8.0安装这是我推荐给绝大多数人的方式三条命令搞定sudo apt install mysql-server mysql-client -y安装完成后查看服务状态systemctl status mysql正常应该显示“active (running)”。如果没有运行执行“systemctl start mysql”并设置开机自启sudo systemctl enable mysql接下来进入非常重要的一步安全初始化。MySQL 8.0在Ubuntu上安装后默认的root用户是使用“auth_socket”插件认证的也就是说在Linux终端里你用系统root用户运行“mysql”命令可以直接进去不需要密码。但这样没法给应用程序或者远程工具用。处理办法有两种一种是用“mysql_secure_installation”工具另一种是手动改root认证方式。我更推荐两个结合先用auth_socket方式进去再修改root密码并设置为“caching_sha2_password”或“mysql_native_password”。先运行安全脚本sudo mysql_secure_installation这个脚本会提示你设置密码强度、删除匿名用户、禁止root远程登录、删除test数据库等。按照提示做就行注意密码强度校验建议选择“2”强校验但如果你只是本地学习选“0”或“1”也行后面还能改。3.2 修改root用户认证方式解决本地连接和工具连接问题执行完安全脚本后root默认可能仍然是auth_socket或者刚设置的密码。为了能用密码登录我们手动改一下sudo mysql -u root进入MySQL命令行后ALTER USER rootlocalhost IDENTIFIED WITH caching_sha2_password BY 你的新密码; FLUSH PRIVILEGES;这里有两种密码插件MySQL 8.0默认是“caching_sha2_password”比老的“mysql_native_password”更安全但有些旧版客户端和图形工具连不上。如果你用的老版本Workbench或者程序驱动可能报“Authentication plugin caching_sha2_password cannot be loaded”这时可以改成ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的新密码;我个人建议如果是新项目、新工具优先用“caching_sha2_password”如果遇到兼容性问题再降级到“mysql_native_password”。毕竟在2025年的今天主流驱动都支持新插件了。改完后验证一下mysql -u root -p输入密码能进去就说明OK了。3.3 创建业务专用账号和授权实际开发中千万别用root去连业务库风险太大。创建一个专用的账号比如“dev”用户只对某个数据库有权限CREATE USER devlocalhost IDENTIFIED BY dev123456; CREATE DATABASE IF NOT EXISTS school DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; GRANT ALL PRIVILEGES ON school.* TO devlocalhost; FLUSH PRIVILEGES;先解释一下为什么字符集用“utf8mb4”。MySQL旧版的“utf8”其实只支持基本多语言平面像一些生僻字、emoji表情都存不了。而“utf8mb4”是真正的完整UTF-8编码能覆盖所有Unicode字符。从MySQL 8.0开始默认就是utf8mb4但是你在建库时最好显式指定尤其是要兼容老项目时。“school”这个库是为了后面演示用你也可以换成自己课程设计的库名。授权时如果想允许远程连接将“localhost”改成“%”或指定IP。不过要注意开启远程访问前我们必须确认bind-address配置见下一节。3.4 配置远程访问用Workbench或Navicat连接默认情况下MySQL只监听“127.0.0.1”也就是说外部机器连不过来。要想让你的宿主机、局域网电脑连上虚拟机里的MySQL需要修改配置文件。打开配置文件sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf找到这一行bind-address 127.0.0.1改成bind-address 0.0.0.0或者注释掉它。保存退出重启MySQLsudo systemctl restart mysql同时确认防火墙是否放行3306端口。Ubuntu默认是ufw如果启用了执行sudo ufw allow 3306/tcp修改完远程登录账号的host为“%”ALTER USER devlocalhost IDENTIFIED WITH caching_sha2_password BY dev123456; RENAME USER devlocalhost TO dev%;或者干脆新创建一个远程用户CREATE USER remote_dev% IDENTIFIED BY dev123456; GRANT ALL PRIVILEGES ON school.* TO remote_dev%; FLUSH PRIVILEGES;到这一步你的MySQL就可以被局域网内的其他机器访问了。但这里有个安全提醒生产环境千万不能简单粗暴地绑“0.0.0.0”最好绑定特定内网IP并用防火墙限制来源IP否则等于把数据库裸奔在公网比较容易招黑。4. 数据库核心操作从命令行到课程设计必备技能4.1 建模与基础SQL建表、约束、增删改查前面已经建了“school”库现在我们建几张表来演示。假设你要做一个“学生选课系统”课程设计至少需要三张表student学生、course课程、sc选课关系。USE school; CREATE TABLE student ( sno CHAR(9) PRIMARY KEY, sname VARCHAR(20) NOT NULL, ssex ENUM(男,女) DEFAULT 男, sage SMALLINT, sdept VARCHAR(20), CONSTRAINT chk_age CHECK (sage BETWEEN 15 AND 45) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE course ( cno CHAR(4) PRIMARY KEY, cname VARCHAR(40) NOT NULL, cpno CHAR(4), ccredit SMALLINT ); CREATE TABLE sc ( sno CHAR(9), cno CHAR(4), grade DECIMAL(5,2), PRIMARY KEY (sno, cno), FOREIGN KEY (sno) REFERENCES student(sno) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (cno) REFERENCES course(cno) ON DELETE CASCADE ON UPDATE CASCADE );建表的时候有几个细节值得注意主键用“CHAR”定长字符串在InnoDB下因为主键是聚簇索引定长主键比变长“VARCHAR”在页存储上更友好。外键关系里我写了“ON DELETE CASCADE”和“ON UPDATE CASCADE”意思是你删除某个学生他所有的选课记录会自动删掉避免手动维护“孤儿数据”。这在课程设计里很常见但有同事会警惕“级联删除”误操作所以生产环境要根据业务仔细评估。存储引擎用InnoDB理由很简单支持事务、外键、行级锁这是现代业务系统的基本盘。MyISAM虽然读性能在某些场景下不错但连事务都不支持MySQL 8.0里基本把它边缘化了。然后插入一些测试数据INSERT INTO student (sno, sname, ssex, sage, sdept) VALUES (202300101, 张三, 男, 20, 计算机系), (202300102, 李四, 女, 19, 软件工程系), (202300103, 王五, 男, 21, 信息管理系); INSERT INTO course (cno, cname, cpno, ccredit) VALUES (C001, 数据库原理, NULL, 4), (C002, 数据结构, C001, 4), (C003, 操作系统, C001, 3); INSERT INTO sc (sno, cno, grade) VALUES (202300101, C001, 88.5), (202300101, C002, 92.0), (202300102, C001, 76.0), (202300103, C003, NULL);注意“course”表里“cpno”列我没加外键因为课程先修关系有点复杂而且会有NULL值暂时不加约束业务层去保证更灵活。接下来是面试和课程设计里反复出现的查询题随便写几个-- 查询计算机系所有学生的学号、姓名 SELECT sno, sname FROM student WHERE sdept 计算机系; -- 查询选了“数据库原理”但还没考试grade为空的学生名单 SELECT s.sno, s.sname, c.cname FROM student s JOIN sc ON s.sno sc.sno JOIN course c ON sc.cno c.cno WHERE c.cname 数据库原理 AND sc.grade IS NULL; -- 查询每门课程的选课人数和平均分 SELECT c.cno, c.cname, COUNT(sc.sno) AS stu_count, AVG(sc.grade) AS avg_grade FROM course c LEFT JOIN sc ON c.cno sc.cno GROUP BY c.cno, c.cname;这里提个容易踩坑的地方用“AVG”统计时如果“grade”是NULLAVG会自动忽略NULL值但COUNT会统计所有行。对于选课人数你可能想统计成绩非空的人数也可能想统计所有选课人数业务含义不同SQL要写清楚。4.2 索引优化为什么你查询这么慢数据库课程设计里很多人建完表就直接查数据量小没感觉但数据一多就卡。索引的作用可以类比书的目录。没有目录读者只能逐页翻有了目录就能直接定位到那一页。MySQL的InnoDB使用B树索引它在索引节点上存储键值叶子节点存储数据地址或者主键值。来看一个常见场景如果经常按“sname”查询学生那就该给“sname”加索引CREATE INDEX idx_student_sname ON student(sname);但不要盲目加索引。索引会占用磁盘空间每次INSERT/UPDATE/DELETE时还要额外维护索引树属于“以写换读”的典型。我现在习惯是先在常用查询条件列上建索引然后通过“EXPLAIN”验证执行计划。EXPLAIN SELECT * FROM student WHERE sname 张三;看“type”和“rows”字段。如果“type”是“ALL”说明全表扫描数据量大就要优化。如果是你加的索引“const”或“ref”说明走索引了。另外“EXPLAIN”还能看到有没有用到临时表、有没有做文件排序这对优化复杂查询很有帮助。关于索引再多说一句复合索引是有顺序的比如建了“(sdept, sage)”索引那么查询“WHERE sdept计算机系 AND sage20”能走索引但如果只查“WHERE sage20”索引不生效因为最左前缀原则。这是MySQL面试高频考点建议自己动手试一下。4.3 存储过程与触发器从会用到底层逻辑许多数据库课程设计的评分标准里都有“存储过程”和“触发器”这两项。说白了存储过程就是把一段SQL逻辑封装起来通过“CALL”调用减少网络传输提高复用性。8.0里写存储过程的语法和老版本基本一致但注意“DELIMITER”的用法。下面是一个经典的示例根据学生学号统计选课门数和平均成绩。DELIMITER $$ CREATE PROCEDURE get_student_stats(IN p_sno CHAR(9)) BEGIN SELECT s.sname, COUNT(sc.cno) AS course_count, IFNULL(ROUND(AVG(sc.grade), 2), 0) AS avg_grade FROM student s LEFT JOIN sc ON s.sno sc.sno WHERE s.sno p_sno GROUP BY s.sno, s.sname; END$$ DELIMITER ;调用一下CALL get_student_stats(202300101);再来一个触发器当往“sc”表插入成绩时如果成绩不在0到100之间就报错阻断插入。DELIMITER $$ CREATE TRIGGER trg_sc_insert_validate BEFORE INSERT ON sc FOR EACH ROW BEGIN IF NEW.grade IS NOT NULL AND (NEW.grade 0 OR NEW.grade 100) THEN SIGNAL SQLSTATE 45000 SET MESSAGE_TEXT 成绩必须在0到100之间; END IF; END$$ DELIMITER ;“45000”是用户自定义异常的通用状态码配合“SIGNAL”可以主动抛出错误。这种触发器在课程设计里很讨喜既体现业务逻辑又展示了对数据完整性的把控。不过我要泼一盆冷水触发器虽然能实现自动化但它隐式运行不易调试而且在复制场景下可能引起主从数据不一致。所以现在的开发实践中很多人宁可在应用层做校验也不愿多放触发器。课程设计里用一两个展示能力可以但别把业务逻辑全堆在数据库里。4.4 事务与隔离级别实战事务是InnoDB的核心特性ACID这四个字母背下来不难难的是知道怎么用。先看一个银行转账的经典例子START TRANSACTION; UPDATE account SET balance balance - 100 WHERE account_id A; UPDATE account SET balance balance 100 WHERE account_id B; COMMIT;如果这两条UPDATE中间某一条失败执行“ROLLBACK”就能回滚到事务开始前的状态避免钱“凭空消失”。在命令行里做实验时可以故意把第二条SQL写错然后“ROLLBACK”再查余额确认没有被扣除。事务隔离级别这块MySQL默认是“REPEATABLE READ可重复读”。注意MySQL在可重复读隔离级别下通过“MVCC多版本并发控制”解决了不可重复读问题还通过“间隙锁”在一定程度避免了幻读这也是为什么Oracle默认用“READ COMMITTED”而MySQL敢默认“REPEATABLE READ”的原因。我实际使用中经常遇到的是“死锁”问题。两个事务互相持锁等待对方释放InnoDB会自动检测并回滚其中一个事务。解决办法一般是调整SQL顺序、缩短事务时间、合理设计索引。如果需要查看当前锁和事务情况可以查这两个系统表SELECT * FROM performance_schema.data_locks; SELECT * FROM information_schema.innodb_trx;4.5 常见面试SQL窗口函数、WITH语法MySQL 8.0相比5.7最大的优势之一是支持窗口函数和公共表表达式CTE。我在面试题库里经常看到这类题目比如“查询每个系年龄最大的学生”。用窗口函数可以这么写SELECT sno, sname, sdept, sage FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY sdept ORDER BY sage DESC) AS rn FROM student ) t WHERE rn 1;“OVER”子句里的“PARTITION BY”按系别分组“ORDER BY”组内排序“ROW_NUMBER()”生成组内编号。这样一行就能解决“分组取TopN”的经典问题要比老版本用“GROUP BY 临时变量”优雅得多。CTE的典型场景是递归查询比如查课程先修关系的多层依赖WITH RECURSIVE prereq_tree AS ( SELECT cno, cname, cpno, 1 AS level FROM course WHERE cpno IS NULL UNION ALL SELECT c.cno, c.cname, c.cpno, p.level 1 FROM course c JOIN prereq_tree p ON c.cpno p.cno ) SELECT * FROM prereq_tree;这个递归CTE在课程设计里属于“加分项”很多老师看到这种写法会觉得你数据库水平不错。5. 图形化工具与日常管理5.1 MySQL Workbench安装与连接配置很多刚入门的同学不习惯纯命令行我建议命令行和图形化工具两手抓。MySQL官方自带的Workbench在Ubuntu上能用“snap”安装也可以用apt。前者版本新一点后者更稳定。用snap装sudo snap install mysql-workbench-community用apt源装Ubuntu 22.04可能有版本较旧的问题sudo apt install mysql-workbench打开Workbench后新建连接填IP、端口3306、用户名、密码。如果连接不上优先检查三件事MySQL是否监听0.0.0.0用户host是否是“%”防火墙是否放行。Workbench有四个我常用到的功能“Server Status”面板可以快速查看版本、运行时间、连接数。“Users and Privileges”可以图形化创建用户、授权和SQL命令等效。“Server Logs”可以查看error log排查启动问题很方便。EER Model工具可以画ER图课程设计报告里插一张ER图老师看着也舒心。5.2 命令行日常管理导入导出与状态查看课程设计或项目验收时经常要把数据库导出拷到另一台机器上。最常用的就是“mysqldump”mysqldump -u root -p school school_backup.sql只备份表结构不加“-A”只备份数据可以加“-t”只备份某张表可以指定表名。导入时mysql -u root -p school school_backup.sql这里有个常见坑如果你的备份文件里包含“CREATE DATABASE”语句导入时可以不指定库名直接“mysql -u root -p school_backup.sql”。如果没包含需要先建好库再导入否则会报“No database selected”。日常诊断连接数和状态用这两个命令mysqladmin -u root -p status mysql -u root -p -e SHOW VARIABLES LIKE max_connections;“max_connections”默认151在并发量大的场景下不够可以在配置文件里调大。不过也别盲目调大连接数越多内存占用越高每个连接都对应一个线程开销不小。更好用的思路是配合连接池把应用层的数据库连接数限制在合理范围。6. 常见问题排查与性能调优实录6.1 安装后无法启动日志怎么看“systemctl status mysql”显示红色failed时第一步是看error log。位置一般在“/var/log/mysql/error.log”。常见原因有“/var/run/mysqld”目录不存在导致socket无法创建。解决先建目录“sudo mkdir -p /var/run/mysqld”然后“sudo chown mysql:mysql /var/run/mysqld”。磁盘空间满了InnoDB无法写入redo log。用“df -h”查看。配置文件中写了不认识参数MySQL启动直接拒绝。这时候用“mysqld --verbose --help | grep 配置项”查询该参数是否支持。6.2 忘记root密码怎么重置这个问题我遇到不止一次。很多时候不是忘了而是前两天刚改过又没记下来。在Ubuntu上如果root用的是auth_socket直接“sudo mysql -u root”进去重置。但如果你之前改成了密码登录密码又忘了可以用“skip-grant-tables”方式绕过去sudo systemctl stop mysql sudo mysqld_safe --skip-grant-tables 然后直接“mysql -u root”进入修改密码。注意操作完一定要重启MySQL关掉“skip-grant-tables”否则任何人都能免密登录你的数据库极其危险。修改时执行FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED WITH caching_sha2_password BY 新密码; FLUSH PRIVILEGES;6.3 用工具远程连接报“Public Key Retrieval is not allowed”这个报错主要在Navicat或一些Java应用连接MySQL 8.0时出现。原因是“caching_sha2_password”插件在非SSL连接下需要获取RSA公钥来加密传输密码客户端默认不自动获取。解决办法有几种我推荐去连接工具设置里打开“AllowPublicKeyRetrieval”允许获取公钥。如果你不想动客户端也可以把账号改成“mysql_native_password”ALTER USER remote_dev% IDENTIFIED WITH mysql_native_password BY dev123456;不过老实说“mysql_native_password”在现在来看已经算是老一代认证插件安全性弱一些能用新插件就别轻易换。6.4 查询明明走不了索引怎么优化我调试过一条慢SQL表里有几十万数据查询“WHERE year(birthday)2000”结果全表扫描。原因很经典在“birthday”列上用了函数导致索引失效。正确写法是SELECT * FROM student WHERE birthday 2000-01-01 AND birthday 2001-01-01;还有一个常见情况是隐式类型转换比如手机号字段用“VARCHAR”存你查询“WHERE phone 13800000000”数字是INTMySQL会把字符串列转成数字再比较索引就废了。查出来慢很正常。检查是否发生类型转换可以看“EXPLAIN”里的“Extra”字段是否有“Using index condition”或“Using where”更直接的办法是“EXPLAIN FORMATJSON”看“attached_condition”。6.5 内存占用过高如何限制InnoDB缓冲池我的机器是8G内存默认MySQL使用InnoDB缓冲池大小是128MB但如果你跑了很多复杂的查询或者数据量大了内存可能吃紧。查看当前值SHOW VARIABLES LIKE innodb_buffer_pool_size;修改配置文件“/etc/mysql/mysql.conf.d/mysqld.cnf”[mysqld] innodb_buffer_pool_size 512M生产环境这个参数通常建议设置为物理内存的50%到70%但如果是在自己电脑上跑学习环境给个256M或512M就够了别贪多否则会和你的浏览器、IDE抢内存。6.6 常见报错速查表报错信息常见原因解决办法ERROR 1045 (28000): Access denied for user用户名或密码错误或host不匹配确认账号host是否为当前连接来源IP用“FLUSH PRIVILEGES”刷新授权ERROR 2003 (HY000): Cant connect to MySQL server端口未监听、防火墙拦截、bind-address限制检查“netstat -tlnp | grep 3306”确认监听地址是0.0.0.0ERROR 1064 (42000): You have an error in your SQL syntaxSQL写错了重点检查引号、逗号、关键字把SQL复制到一个文本编辑器中高亮检查注意保留字加反引号ERROR 1698 (28000): Access denied for user rootlocalhostroot使用了auth_socket插件而客户端使用密码登录用“sudo mysql -u root”进入后修改root账号认证插件/usr/sbin/mysqld: error while loading shared libraries缺少系统依赖库执行“sudo apt install libaio1t64”或“libaio1”7. 后续还可以怎么玩MySQL生态扩展建议如果你已经能熟练使用以上功能可以再往这几个方向延伸主从复制MySQL 8.0的主从复制配置并不算复杂改两三个配置文件然后“CHANGE MASTER TO”指定主库地址即可。理解“binlog”同步机制是分布式数据库认知的起点。慢查询日志把“slow_query_log”打开设置“long_query_time1”然后定期用“mysqldumpslow”分析能帮你找到系统里最拖后腿的SQL。备份恢复演练不要满足于只做一次“mysqldump”要真的恢复到一台空机器上确认数据完整。我身边有同事因为从没演练过恢复出事情的时候发现备份文件是坏的那种教训很惨痛。最后回答一个大家经常问的问题Ubuntu下能不能跑MySQL 5.7而不是8.0技术上可以安装官方仓库后指定版本“mysql-community-server-5.7”但5.7已经停止官方维护了安全漏洞不会得到修复。除非有明确的兼容性限制否则新项目直接上MySQL 8.0没有理由重蹈覆辙。我个人在实际操作中的体会是把环境弄干净把基础SQL练扎实比追求花哨工具重要得多。这套Ubuntu MySQL 8.0的组合我从大作业用到工作项目一路踩坑一路补课现在回头看很多“诡异报错”其实就是基础配置不规范埋下的雷。希望这篇分享能帮你少走弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价