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 LTS,x86_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 'root'@'localhost' 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 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的新密码';我个人建议如果是新项目、新工具,优先用“caching_sha2_password”,如果遇到兼容性问题再降级到“mysql_native_password”。毕竟在2025年的今天,主流驱动都支持新插件了。
改完后验证一下:
mysql -u root -p输入密码能进去,就说明OK了。
3.3 创建业务专用账号和授权
实际开发中千万别用root去连业务库,风险太大。创建一个专用的账号,比如“dev”用户,只对某个数据库有权限:
CREATE USER 'dev'@'localhost' IDENTIFIED BY 'dev123456'; CREATE DATABASE IF NOT EXISTS school DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; GRANT ALL PRIVILEGES ON school.* TO 'dev'@'localhost'; 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或者注释掉它。保存退出,重启MySQL:
sudo systemctl restart mysql同时确认防火墙是否放行3306端口。Ubuntu默认是ufw,如果启用了,执行:
sudo ufw allow 3306/tcp修改完远程登录账号的host为“%”:
ALTER USER 'dev'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'dev123456'; RENAME USER 'dev'@'localhost' 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) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 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”是NULL,AVG会自动忽略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 sage=20”能走索引,但如果只查“WHERE sage=20”,索引不生效,因为最左前缀原则。这是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 'root'@'localhost' 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”,数字是INT,MySQL会把字符串列转成数字再比较,索引就废了。查出来慢很正常。检查是否发生类型转换,可以看“EXPLAIN”里的“Extra”字段是否有“Using index condition”或“Using where”,更直接的办法是“EXPLAIN FORMAT=JSON”看“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): Can't connect to MySQL server | 端口未监听、防火墙拦截、bind-address限制 | 检查“netstat -tlnp | grep 3306”,确认监听地址是0.0.0.0 |
| ERROR 1064 (42000): You have an error in your SQL syntax | SQL写错了,重点检查引号、逗号、关键字 | 把SQL复制到一个文本编辑器中高亮检查,注意保留字加反引号 |
| ERROR 1698 (28000): Access denied for user 'root'@'localhost' | root使用了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_time=1”,然后定期用“mysqldumpslow”分析,能帮你找到系统里最拖后腿的SQL。
- 备份恢复演练:不要满足于只做一次“mysqldump”,要真的恢复到一台空机器上,确认数据完整。我身边有同事因为从没演练过恢复,出事情的时候发现备份文件是坏的,那种教训很惨痛。
最后,回答一个大家经常问的问题:Ubuntu下能不能跑MySQL 5.7而不是8.0?技术上可以,安装官方仓库后指定版本“mysql-community-server-5.7”,但5.7已经停止官方维护了,安全漏洞不会得到修复。除非有明确的兼容性限制,否则新项目直接上MySQL 8.0,没有理由重蹈覆辙。我个人在实际操作中的体会是:把环境弄干净,把基础SQL练扎实,比追求花哨工具重要得多。这套Ubuntu + MySQL 8.0的组合,我从大作业用到工作项目,一路踩坑一路补课,现在回头看,很多“诡异报错”其实就是基础配置不规范埋下的雷。希望这篇分享能帮你少走弯路。