开头
在 Ubuntu 22.04 上部署 MySQL,几乎是每个做后端开发、运维或者自己折腾服务器的朋友都绕不开的一关。我前前后后在各种环境里装过不下几十次 MySQL,从最开始的跟着教程一步一步敲命令,到后来自己踩坑、看官方文档、慢慢摸清楚每个配置项背后的原因,这个过程里积累了不少经验。今天这篇就把我在 Ubuntu 22.04 上安装和配置 MySQL 的完整流程写下来,从零开始,一步步带你走完,同时把我踩过的坑和排查思路也一并分享出来。
这篇文章适合谁看?如果你是刚接触 Linux 服务器的新手,想在自己电脑或者云服务器上装一个 MySQL 数据库用来学习或者跑项目;或者你是老手,但之前用的都是 CentOS 或者 Windows 环境,第一次切到 Ubuntu 22.04 上部署 MySQL;又或者你已经装好了 MySQL,但遇到了一些配置上的问题,比如远程连不上、root 密码忘了、字符集乱码之类的,这篇都能帮你找到答案。
先说结论:Ubuntu 22.04 的官方软件源里自带 MySQL 8.0,用 apt 直接安装是最省事、最不容易出错的方式,完全不需要去官网下载什么 tar 包或者 rpm 包折腾。下面我详细讲整个流程,以及每一步为什么要这么做。
1. 内容整体设计与思路拆解
1.1 为什么选择 apt 源安装而不是编译安装
很多人在装 MySQL 的时候会纠结一个问题:用 apt 装、用官网的 APT 仓库装、还是下载二进制包手动部署?我给你的建议是:如果你没有特殊需求(比如要装特定的小版本、要定制编译参数),直接用 Ubuntu 自带的 apt 源装 mysql-server 就够了。
理由很简单:apt 源里的 MySQL 8.0.34(22.04 对应的版本会随更新变化)是经过 Ubuntu 官方测试的,依赖关系处理得干干净净,装完就能跑,而且后续的apt upgrade会帮你自动处理小版本的安全更新。你不需要手动去管依赖库,也不需要处理复杂的 PATH 环境变量。
相比之下,编译安装虽然能拿到最新的源码和自定义编译选项,但耗时长、依赖多,光是把 CMake 的参数调明白就够你折腾半天的。对于绝大多数场景来说,完全没有必要。
注意:如果你用的是
ubuntu-22.04-server的精简版镜像,某些环境里 apt 源的 base 仓库可能不包含 mysql-server 包。遇到这种情况,先执行sudo apt update,如果还是找不到包,检查一下/etc/apt/sources.list或/etc/apt/sources.list.d/下是否有universe组件的源。
1.2 安装前需要确认的系统环境
在敲第一条安装命令之前,建议你先花两分钟把系统的底子摸清楚。我见过不少人在环境没准备好的情况下硬装,结果后面各种报错。
确认系统版本:
lsb_release -a正常会输出类似这样的信息:
Distributor ID: Ubuntu Description: Ubuntu 22.04.4 LTS Release: 22.04 Codename: jammy确认系统架构,MySQL 官方对不同的 CPU 架构提供了不同的包:
uname -m绝大多数云服务器和 PC 机都是x86_64,如果你是 ARM 架构的机器(比如树莓派、某些国产芯片的服务器),输出会是aarch64。这个信息在后面排查问题的时候会用到。
再确认一下磁盘空间,MySQL 8.0 安装后加上数据库文件,至少预留 5GB 左右的空间比较稳妥:
df -h /1.3 核心方案选型思路
我的整体部署方案是这样的:
- 操作系统:Ubuntu 22.04 LTS(内核版本至少 5.15)
- 数据库版本:MySQL 8.0(apt 仓库自动管理版本)
- 认证插件:默认使用
caching_sha2_password,兼容性出问题时切换到mysql_native_password - 字符集:UTF-8 是默认选项,根据业务需要决定是否修改
- 远程访问:默认监听 127.0.0.1,按需修改 bind-address 并开放 3306 端口
这个方案的优势在于:默认配置足够安全(MySQL 8.0 默认只允许本地访问、默认 root 使用强密码认证),同时保留了足够的定制空间。Ubuntu 的老用户应该知道,在 16.04/18.04 时代,装完 MySQL 之后 root 默认可以通过sudo mysql直接无密码登录,因为这个插件是auth_socket。从 20.04 开始,MySQL 8.0 默认的 root 认证方式变成了auth_socket加caching_sha2_password的组合,但实际体验下来,最常见的还是用sudo mysql先进去再改密码。这个细节我们后面详细讲。
2. 核心细节解析与实操要点
2.1 apt 更新的必要性和潜在问题
安装 MySQL 之前,更新软件源缓存是必须的一步。这不仅仅是"要让系统知道有 mysql-server 这个包",更重要的是,Ubuntu 22.04 发布之后,软件源里的 MySQL 版本会不断地通过-updates和-security仓库收到安全补丁。如果你的系统几个月没有apt update,装到的可能是带着已知漏洞的旧版本。
sudo apt update这个过程可能会遇到两个比较常见的问题:
一个是 GPG 错误,提示类似The following signatures couldn't be verified because the public key is not available,这通常是软件源的公钥过期了,需要手动更新密钥环。另一个是网络问题,提示Failed to fetch,有时候是镜像源不稳定,可以换一个国内镜像源(比如华为云、清华 TUNA),修改/etc/apt/sources.list里的源地址即可。
如果你是在公司内网环境安装,可能还需要配置 apt 代理,在/etc/apt/apt.conf.d/下新建一个文件,写入:
Acquire::http::Proxy "http://你的代理IP:端口"; Acquire::https::Proxy "http://你的代理IP:端口";2.2 安装 mysql-server 的完整命令
接下来安装核心组件:
sudo apt install -y mysql-server这条命令会把mysql-server以及它依赖的mysql-client-8.0、mysql-common、libmysqlclient21等包一起装进去。装完之后,MySQL 服务会自动启动。
检查服务状态:
systemctl status mysql如果看到类似Active: active (running)的输出,说明服务已经正常运行了。此时不管你是怎么最终启动的——通过 systemd 自动启动的服务,sudo service mysql status也可以查看,结果应该是一样的。
实操心得:有些版本的 Ubuntu 装完 MySQL 之后,服务并没有自动启动成功,大概率是因为/var/lib/mysql目录的权限不对,或者系统资源不足(内存小于 512MB 时 MySQL 初始化可能内存不足)。遇到这种情况不用慌,看下面的日志排查:
sudo journalctl -u mysql --since "5 minutes ago"2.3 验证 MySQL 安装版本
安装完成后,验证一下版本信息:
mysql --version输出应该是:
mysql Ver 8.0.xx-0ubuntu0.22.04.x for Linux on x86_64 ((Ubuntu))这里有个容易混淆的点:mysql --version显示的是客户端工具的版本,它和服务器版本通常是一致的,但在某些混合安装场景下可能出现不一致(比如你手动装了 mysql-client 的另一个版本),所以更准确的验证方式是登录数据库后查看version()函数:
sudo mysql -e "SELECT VERSION();"2.4 了解 MySQL 8.0 的认证插件机制
MySQL 8.0 默认的密码认证插件是caching_sha2_password,这是 MySQL 官方在 8.0 里主推的认证方案,比之前的mysql_native_password安全性更高,具体表现在它使用基于 SHA-256 的密码哈希算法,并且支持基于 RSA 密钥对的安全传输。
但这带来一个实际使用中的兼容性问题:很多老项目的第三方库(比如 Python 的旧版pymysql、PHP 5.x 的mysql扩展)只支持mysql_native_password。如果你在用这类老客户端,连接 MySQL 8.0 时会直接报错:
Authentication plugin 'caching_sha2_password' cannot be loaded解决办法通常有两种:
一种是把用户的认证插件改回mysql_native_password:
ALTER USER '你的用户名'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';另一种是升级客户端的驱动库,让它支持新的认证插件。我个人建议优先升级客户端,因为mysql_native_password在 MySQL 未来的版本里会被彻底移除,你不应该让新部署的数据库去迁就旧代码。
2.5 配置文件的基本框架和关键参数
MySQL 的主配置文件在/etc/mysql/mysql.conf.d/mysqld.cnf,这是 Debian/Ubuntu 系的路径习惯,其他发行版不太一样(比如 CentOS 是/etc/my.cnf)。
关于配置,我想重点提醒几个参数:
bind-address:默认是127.0.0.1,表示只允许本地连接。如果需要远程访问数据库,改成0.0.0.0,但这样做的同时必须做好权限管控。port:默认 3306,一般不用改。max_connections:默认值是 151,对于小项目够用。如果连接数打满,会报Too many connections错误。character-set-server/collation-server:默认是utf8mb4和utf8mb4_0900_ai_ci,这是 MySQL 8.0 的默认值,也是官方推荐的新项目配置,不用改。innodb_buffer_pool_size:这是 InnoDB 引擎最关键的性能参数,默认 128MB。如果你的机器内存有 8GB 以上,建议调到物理内存的 50%~70%。
3. 实操过程与核心环节实现
3.1 初始化数据库安全配置
安装好 MySQL 之后,第一步就是运行安全初始化脚本。这个脚本会引导你完成一系列安全设置:
sudo mysql_secure_installation运行之后,它会依次问你几个问题:
第一个问题:是否配置 VALIDATE PASSWORD COMPONENT(密码强度校验组件)?
这一步我建议选择 Y。它会在后续创建用户的时候强制检查密码强度,防止你设置过于简单的密码。如果你只是本地开发用,嫌麻烦可以选 N,但任何在生产环境安装的数据库,都强烈建议开启。
第二个问题:密码强度级别,有 LOW、MEDIUM、STRONG 三个选项。
- LOW:只检查密码长度,至少 8 位
- MEDIUM:还要检查密码是否包含数字、大小写字母和特殊字符,这个也是默认推荐选项
- STRONG:在 MEDIUM 基础上还要检查密码是否在字典里
一般选 MEDIUM 就好。
第三个问题:是否移除匿名用户?
一定要选 Y。匿名用户意味着任何人不需要密码就能连接数据库,这是极大的安全隐患。
第四个问题:是否禁止 root 远程登录?
这里要分场景。如果 root 只用于本机管理,选 Y。如果确实需要 root 远程连接(比如服务器在 IDC 机房,你需要远程管理),选 N,但配合强密码和防火墙白名单使用。我个人的习惯是禁止 root 远程,另外创建一个专门的管理员账号用于远程操作,这样更安全,审计也更清晰。
第五个问题:是否移除测试数据库?
选 Y。测试数据库不能被访问。这个和匿名用户一样都是潜在的风险点。
第六个问题:是否重新加载权限表?
选 Y,让上面所有修改立即生效。
3.2 修改 root 用户密码的实操演示
在 Ubuntu 22.04 上,装完 MySQL 之后 root 用户的认证方式默认是auth_socket,这意味着你可以用系统的 root/sudo 权限免密登录数据库,但用 TCP/IP 和密码方式却登不进去。这个设计让很多第一次接触 Ubuntu MySQL 的人犯迷糊:明明知道 root 密码,却告诉我密码错误?
绕过这个限制,在命令行执行:
sudo mysql即可直接进入 MySQL 的命令行界面,不需要密码。进去之后,把 root 的认证方式改为密码认证:
ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '你的强密码'; FLUSH PRIVILEGES;提示:MySQL 8.0 使用
caching_sha2_password作为默认认证插件。如果你在使用过程中遇到旧的客户端插件无法加载的问题,可以上面的caching_sha2_password改为mysql_native_password,但要注意这只是临时兼容方案,不建议长期使用。
执行完之后,退出,然后测试用密码登录:
mysql -u root -p输入刚才设置的密码,能顺利进入就说明 root 密码认证已经生效了。
实操心得:改密码的时候密码里尽量避免@、$、#这类半角符号——倒不是 MySQL 不允许,而是很多 shell 环境对这些特殊字符有解释,容易把密码搞乱。更纠结的是某些容器编排工具和配置管理工具读取密码时也可能被这些特殊字符坑到。一句话,密码用大小写字母加数字加一个下划线就足够强了。
3.3 创建业务用户和授权
在正式的使用场景里,我们一般不建议直接用 root 连接业务数据库。更好的做法是创建一个最小权限的业务账号,这样即使数据库账号泄露了,攻击者也只能操作明确授权的那几个库表,影响面可控。
进入 MySQL:
mysql -u root -p执行:
CREATE DATABASE IF NOT EXISTS myapp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'MyApp_2024_pass'; GRANT ALL PRIVILEGES ON myapp.* TO 'myapp_user'@'localhost'; FLUSH PRIVILEGES;解释一下这几条语句:
myapp是数据库名,utf8mb4是字符集,支持完整的 Unicode 字符,包括 emoji 表情myapp_user是用户名,localhost表示只允许从本机连接GRANT ALL PRIVILEGES ON myapp.*表示只授权myapp这个库的所有权限,其他库一概碰不了
如果你的应用跑在另一台服务器上,需要远程连接,可以创建这样一个账号:
CREATE USER 'myapp_user'@'192.168.1.%' IDENTIFIED BY 'MyApp_2024_pass'; GRANT ALL PRIVILEGES ON myapp.* TO 'myapp_user'@'192.168.1.%'; FLUSH PRIVILEGES;这里的192.168.1.%是个网段匹配模式,只允许来自 192.168.1.x 这个网段的连接使用这个账号。比直接写%(所有 IP)安全得多。
实操心得:授权语句里如果用了IDENTIFIED BY,一定要放在CREATE USER里写一次就够了,不要在GRANT后面再加密码。虽然 MySQL 允许这种写法(会让它更新用户密码并授权),但这样会把密码和权限绑在一起,时间长了容易找不到真正密码在哪里改过。
3.4 配置远程访问
MySQL 默认只监听本地回环地址,你这是想远程连是连不上的。需要改两处配置:
第一处:修改 bind-address。编辑配置文件:
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf找到这一行:
bind-address = 127.0.0.1改成:
bind-address = 0.0.0.0或者指定具体网卡的 IP:
bind-address = 192.168.1.1000.0.0.0表示监听所有网络接口,包括所有公网 IP。如果你只需要在内网访问,建议指定具体的内网 IP,减少暴露面。另外还有一种做法是注释掉 bind-address 这一行,效果等同于 0.0.0.0。
第二处:确认防火墙放行 3306 端口。Ubuntu 22.04 默认用的防火墙是ufw,先看看状态:
sudo ufw status如果状态是 active,需要放行端口:
sudo ufw allow 3306/tcp如果只想允许某个特定 IP 访问:
sudo ufw allow from 192.168.1.50 to any port 3306 proto tcp改完配置之后,重启 MySQL 使配置生效:
sudo systemctl restart mysql然后确认服务还在运行:
sudo systemctl status mysql远程连接测试,在另一台机器上执行:
mysql -h 你的服务器IP -u myapp_user -p3.5 字符集配置与乱码防范
UTF-8 是 MySQL 8.0 的默认字符集,但你仍然可能遇到乱码问题,尤其是在从旧版本数据库导入数据的时候。
MySQL 8.0 默认字符集是utf8mb4,排序规则是utf8mb4_0900_ai_ci,这个在新创建的数据库里基本不会有乱码。但如果你从 MySQL 5.7 或者更老的版本导入数据,源库用的是latin1或者utf8(注意 utf8 在 MySQL 里并不是真正的全 Unicode,它只能存 BMP 字符),就可能出现乱码或者非法字符错误。
查看当前字符集:
SHOW VARIABLES LIKE 'character_set%';核心的几个变量:
character_set_server:服务器默认字符集character_set_database:当前数据库的字符集character_set_client:客户端发送数据的字符集character_set_connection:连接层字符集
对于已经存在的老数据,转码是比较麻烦的,这里不展开容器外的数据迁移细节。不过有两点很关键:导入数据时用mysql --default-character-set=utf8mb4 -u xxx -p xxx < dump.sql显式指定客户端字符集;建表的时候在CREATE TABLE语句里显式声明字符集,不要依赖全局默认值,这样之后不管环境怎么变都能保持一致性。
3.6 开机自启动设置
Ubuntu 22.04 使用 systemd 管理服务,MySQL 安装后默认就是开机自启的。你可以验证一下:
systemctl is-enabled mysql输出enabled就是已经设置了开机自启。
如果输出的是disabled,说明可能被手动关掉了,开启:
sudo systemctl enable mysql有些人在配置多实例或者自行编译的 MySQL 时,会用init.d下的脚本管理,但标准 apt 安装的版本直接用 systemd 就好,不要去额外配置rc.local——那是老古董的玩法了,还可能和 systemd 冲突。
4. 常见问题与排查技巧实录
4.1 MySQL 服务启动失败排查
这是我见过频率最高的一个问题:sudo systemctl start mysql之后,提示服务启动失败。
排查看日志是第一步:
sudo journalctl -u mysql -n 50常见的失败原因有这几种:
磁盘权限问题:/var/lib/mysql目录的所有者必须是mysql:mysql。如果不对,用:
sudo chown -R mysql:mysql /var/lib/mysql磁盘空间不足:innodb在初始化的时候需要写入临时文件,空间不够会直接失败。用df -h检查。
端口被占用:如果有个残留的 mysqld 进程或者别的数据库占着 3306 端口,也会启动失败。排查:
sudo lsof -i :3306 sudo ss -tlnp | grep 3306找到占用端口的进程后,确认它是不是残留的 MySQL 进程,是的话先停掉再启动服务。
4.2 root 密码忘记的完整处理流程
忘记 root 密码是另一个高频问题,处理手段比较暴力,但很好用。核心思路是:先跳过权限验证启动 MySQL,然后重置密码,再恢复正常启动。
具体操作如下:
先停掉 MySQL 服务:
sudo systemctl stop mysql用--skip-grant-tables模式启动 MySQL:
sudo mysqld --skip-grant-tables --skip-networking &注意加了--skip-networking,这样其他机器连不进来,只能本机操作,安全性有保障。启动之后,用 root 直接免密登录:
sudo mysql -u root登录后,先让权限表重新生效:
FLUSH PRIVILEGES;然后重置密码:
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';退出并重启 MySQL:
sudo mysqladmin -u root -p shutdown sudo systemctl start mysql这里有个小技巧:在skip-grant-tables模式下,直接执行ALTER USER有时会报错,提示你Plugin 'auth_socket' is not loaded,所以先执行FLUSH PRIVILEGES;就能解决。这个坑我踩过一次,记住了。
4.3 远程连接失败的场景化排查
远程连不上 MySQL,原因可能有很多,按顺序排查效率最高:
第一步:确认 MySQL 正在监听正确的地址:
sudo ss -tlnp | grep 3306如果监听的地址是127.0.0.1:3306,那就是配置没生效,改完bind-address之后是否重启了服务。
第二步:确认用户名的主机匹配。你创建的用户是'myapp_user'@'localhost',那即使用了-h 服务器IP连接,MySQL 也只会把它当成 loopback 请求来匹配权限,通常是能连的。但如果创建的是'myapp_user'@'192.168.1.%',而你偏偏从192.168.2.10连接,就会被拒绝。用 root 登录 MySQL 查一下用户表里保存的主机字段:
SELECT user, host, plugin FROM mysql.user;第三步:确认密码是否正确,远程连接的密码和本地登录的密码可能是不同的账号分别设置的,不要下意识觉得密码都一樣。
第四步:确认防火墙和云安全组。云服务器的安全组规则(阿里云安全组、腾讯云防火墙、AWS Security Group)常常是远程连不上的“罪魁祸首”——服务器内置防火墙只管服务器本身,安全组是云平台层面的隔离,两层规则都要放行 3306 端口。
4.4 SSL 连接相关报错
MySQL 8.0 默认开启了 SSL 连接。很多客户端连接的时候如果没有指定 SSL 选项,可能会遇到类似SSL connection error: SSL_CTX_set_tmp_dh ...或者Public Key Retrieval is not allowed的报错。
后者是最常见的,尤其是用 Java 的 JDBC 驱动或者某些图形化客户端连接时,默认不会自动获取服务器公钥。解决方法是在连接参数里加:
allowPublicKeyRetrieval=true&useSSL=false如果是命令行客户端,可以这样连接:
mysql --ssl-mode=DISABLED -h 服务器IP -u 用户名 -p--ssl-mode=DISABLED表示不启用 SSL 加密传输。但请注意:生产环境强烈建议保留 SSL,明文传输密码和数据是不负责任的行为。仅在排错的时候临时禁用。
4.5 Too many connections 问题
连接数打满会报Too many connections,一般发生在并发量较大的场景。
先在命令行强制登录(即使连接数满,root 通常还能挤进去):
mysql -u root -p查看当前的连接数配置:
SHOW VARIABLES LIKE 'max_connections';查看当前正在使用的连接数:
SHOW STATUS LIKE 'Threads_connected';如果确实接近打满,调大 max_connections:
[mysqld] max_connections = 500但是,我在实际运维中见过不少把max_connections调到 5000 以上照扛不住的情况,问题根源往往是连接没有及时释放,应用层的连接池配比不合理。与其无限调大,不如先检查是不是连接泄漏——用netstat -anp | grep 3306 | grep ESTABLISHED | wc -l统计一下当前的真实 TCP 连接数,配合慢日志定位是不是有某个 SQL 长时间占用连接。
4.6 Ubuntu 22.04 卸载 MySQL 的完整步骤
有些人装完发现版本不对或者搞坏了,想彻底重装。卸载也是个有讲究的过程,不完整卸载很容易在重新安装时遇到mysql.service is not running之类的奇怪问题。
清理步骤:
sudo systemctl stop mysql sudo apt purge -y mysql-server mysql-client mysql-common sudo apt autoremove -y手动清理残留的数据目录和配置文件:
sudo rm -rf /var/lib/mysql sudo rm -rf /etc/mysql sudo rm -rf /var/log/mysql检查是否还有残留的 MySQL 进程:
ps aux | grep mysql有的话kill掉。确认所有包都清理干净:
dpkg -l | grep mysql没输出就说明清理完成了。
注意:
rm -rf /var/lib/mysql会把所有数据库文件清空,操作前务必确认有没有需要保留的数据。如果你想留下数据目录只重装软件,把这一步跳过去即可。
5. 性能调优与日常维护经验
5.1 安装后的检查清单
装完 MySQL 之后,我建议你花几分钟做一遍快速体检,确认系统处于一个比较健康的状态:
mysqladmin -u root -p status mysqladmin -u root -p extended-statusmysqladmin status会告诉你运行时间(Uptime)、线程数(Threads)、慢查询数(Slow queries)等信息。如果刚装完就有比较多的慢查询,说明导入的数据或初始化 SQL 可能有问题,不需要担心,但值得注意。
再确认一下 InnoDB 的状态:
SHOW ENGINE INNODB STATUS\G重点关注BUFFER POOL AND MEMORY这一块,看命中率(Buffer pool hit rate)是否接近 100%。如果低于 99%,需要对innodb_buffer_pool_size进行调优。
5.2 基础配置调优建议
不同机器配置、不同业务类型,MySQL 的最佳参数是完全不同的。我只给一个通用的大方向建议:
内存 4GB 以下的机器:保持默认配置即可,不要乱改,改了容易出问题。默认值是保守的,但保守不等于错误。
内存 8GB~16GB 的机器,可以调整这几个参数:
[mysqld] innodb_buffer_pool_size = 4G max_connections = 500 table_open_cache = 1024innodb_buffer_pool_size设置为物理内存的 50% 左右是一个比较通用的起点。比如 8GB 内存就设 4G,16GB 就设 8G。这个参数决定 InnoDB 能在内存里缓存多少数据页和索引页,设小了磁盘 IO 压力大,设太大又会导致操作系统内存吃紧,触发 swap,性能反而下降。
特别注意:如果服务器上还跑着其他服务(比如部署了 Nginx、Redis 或者其他 Java 服务),不要把 MySQL 的参数调得太激进,一定要给其他进程留出足够的余量。
5.3 开启慢查询日志
要定位性能问题,慢查询日志是最直接的工具。MySQL 8.0 默认关闭了慢查询日志。临时开启排查问题:
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 2;这样会记录执行时间超过 2 秒的 SQL。如果你希望永久生效,在配置文件的[mysqld]段里写入:
slow_query_log = 1 slow_query_log_file = /var/log/mysql/mysql-slow.log long_query_time = 2 log_queries_not_using_indexes = 1log_queries_not_using_indexes = 1会记录没有使用索引的查询,这对优化 SQL 帮助很大,但在数据量大的线上环境不要一直开,因为它可能产生非常庞大的日志文件。
重启服务后生效:
sudo systemctl restart mysql然后定期检查慢日志:
sudo tail -n 100 /var/log/mysql/mysql-slow.log5.4 数据备份的常规操作
数据备份是数据库运维的基本功。我最常用的备份方式是mysqldump逻辑备份,简单、通用、不依赖具体的存储引擎。
备份单个数据库:
mysqldump -u root -p --single-transaction --routines --triggers myapp > myapp_backup_$(date +%Y%m%d).sql参数说明:
--single-transaction:InnoDB 表使用事务机制做一致性快照,备份过程中不影响正常读写--routines:备份存储过程和函数--triggers:备份触发器myapp:要备份的数据库名
备份全部数据库:
mysqldump -u root -p --all-databases --single-transaction --routines --triggers > all_databases_backup.sql恢复数据库:
mysql -u root -p < myapp_backup.sql如果备份文件比较大(几个 GB),建议先压缩再传走,在服务器上可以这样:
mysqldump -u root -p --single-transaction myapp | gzip > myapp_backup.sql.gz恢复时先解压再导入:
gunzip < myapp_backup.sql.gz | mysql -u root -p myapp实操心得:不要只做一次备份就完事了。我用cron做了每日备份和每周全量备份的组合,备份文件保留最近 30 天。一个运维事故的“事故”往往就是因为备份缺失或者备份恢复验证没做过,用而宣时才发现备份文件损坏或者恢复不进去。备份文件能不能用,至少每月做一次恢复演练,这是最简单的“保命”手段。
5.5 MySQL 8.0 与旧项目兼容性的实战问题
最后说说兼容性问题。不少朋友在 Ubuntu 22.04 上装 MySQL 8.0 是为了跑一个老项目,这时候常见的问题我帮你列一下:
旧版 PHP 的 mysql 扩展:PHP 5.x 时代用的mysql_connect系列函数,在 PHP 7+ 里已经被彻底移除,更别提连接 MySQL 8.0 了。如果还在用这种代码,需要的不是调数据库,而是先升级代码到mysqli或PDO_MySQL。
WordPress 等 CMS 系统:目前主流的 WordPress 版本都支持 MySQL 8.0,一般不会有大问题。但个别老主题或插件用utf8mb4_general_ci排序规则时可能无法匹配 MySQL 8.0 默认的utf8mb4_0900_ai_ci,导致数据库操作报错。解决办法是在建库建表时显式指定COLLATE utf8mb4_general_ci。
用户密码插件不匹配:老程序的连接层不认识caching_sha2_password,上面已经讲了两种解决办法。从用户体验角度,如果代码一时半会改不了,临时切换成mysql_native_password也无妨,但要做好记录,后续要迁回默认的认证方式。
5.6 日志文件的管理
MySQL 运行久了,日志文件越来越大,也可能把磁盘撑满。常用的日志有这些:
- 错误日志:
/var/log/mysql/error.log - 慢查询日志:
/var/log/mysql/mysql-slow.log(配置后才有) - 二进制日志 binlog:默认关闭,开启后文件在
/var/lib/mysql/下
如果发现磁盘空间越来越小,先看/var/lib/mysql目录下什么东西占空间最大:
sudo du -sh /var/lib/mysql/*binlog 是占空间大户。如果确认不需要基于 binlog 做数据恢复或者主从复制,可以在配置里关闭:
skip-log-bin或者设置自动清理日期:
expire_logs_days = 7注意,MySQL 8.0 里expire_logs_days已经废弃,改成了binlog_expire_logs_seconds,按秒设置:
binlog_expire_logs_seconds = 604800604800 秒就是 7 天。修改后重启 MySQL 生效。
6. 写在最后
如果非要我总结一句心里话,那就是:MySQL 在 Ubuntu 22.04 上的安装其实并不难,apt 一条命令就能搞定,真正的难度在于装完之后的配置、安全加固和日常维护。你踩过的每一个坑——无论是远程连不上、字符集乱码、还是密码认证失败——背后都有它的原因,顺着日志和配置去查,基本上都能找到答案。
我个人还有个建议,就是养成在每次操作前先想清楚“这一条命令下去会影响什么”的习惯。比如rm -rf到底删的是什么、ALTER USER会影响哪些应用、修改bind-address暴露了哪些网络面,想清楚了再动手,数据库出问题的概率会小很多。特别是生产环境,任何操作都建议先在本地或者测试环境演练一遍,再拿到线上干。
最后再分享一个小技巧:安装完成后,把/etc/mysql/mysql.conf.d/mysqld.cnf这个配置文件在改动之前先备份一份,好多问题其实都是配置改乱了,恢复出厂配置立刻就好。另外记得把 root 密码、业务账号信息存在密码管理工具里,不要在聊天工具或者公共文档里明文记录。数据库的安全其实一大半是操作习惯的安全,养成好习惯比会背命令参数要管用得多。