又到了要在 Ubuntu 上装 MySQL 的环节。说实话,网上这类教程一抓一大把,但真正能一路跟下来不出错的没几个。我自己在 Ubuntu 22.04 上装过不下十次 MySQL 8.0,从刚开始照着文档敲命令就翻车,到现在几分钟完事,中间踩过的坑基本都集中在源、认证插件和服务启动这三块。这篇就把我的完整操作流程、选型逻辑和排错经验写下来,无论是刚接触 MySQL 的新手,还是被环境折腾过的老手,照着走都能少绕点弯。
先说明白这篇覆盖什么:系统是 Ubuntu 22.04 LTS,MySQL 版本以 8.0 为主,同时会聊到 5.7 在老机器上的安装思路。安装方式上我会重点讲 apt 官方仓库这条最省心的路径,再补充打包安装的适用场景。配置、调优、SSL 连接问题和服务排错都会涉及,内容偏实操,命令可直接复制。
1. 安装前的系统准备与环境确认
1.1 先用三条命令确认系统状态
很多人装 MySQL 失败,第一步就错在没搞清楚自己到底用的什么系统。Ubuntu 22.04 和 20.04 在软件源策略上有差别,连内核版本都会影响 MySQL 的编译依赖。建议先执行以下三条命令:
lsb_release -a uname -a free -hlsb_release -a会显示发行版版本号,看到22.04 LTS就说明系统层面没问题。uname -a查看内核架构,这里要注意,绝大多数云服务器和笔记本是x86_64,但如果你是树莓派或者 ARM 架构的服务器,后面选的安装包就必须是 ARM 版本,这点很容易忽略。
free -h是看内存的。MySQL 8.0 在默认配置下,跑起来大概吃 300MB 到 500MB 内存,如果你只有 1GB 内存的小机器,后面配置调优时就得把innodb_buffer_pool_size调小,否则系统很容易卡死。我在一台 512MB 内存的旧机器上试过装 MySQL 8.0,不调参数直接默认启动,机器 swap 直接被占满,整个系统几乎无响应。
1.2 更新软件源和基础依赖
确认系统没问题后,先做一轮常规更新。这个步骤的作用是让 apt 的软件索引同步到最新,避免安装时因为索引过旧而拿不到正确的包版本。
sudo apt update sudo apt upgrade -y sudo apt install -y wget curl gnupg2 lsb-release这里装gnupg2是为了后面导入 MySQL 官方签名密钥。MySQL 官方仓库的包都有 GPG 签名,不导入密钥的话,apt 会直接拒绝安装并报NO_PUBKEY错误,这是新手最常见的一个坑。
另外,如果你的服务器上有旧版本的 MySQL、MariaDB 或者其他 MySQL 分支,建议先清掉,否则端口 3306 冲突会引发各种诡异问题。检查命令:
dpkg -l | grep -E "mysql|mariadb"如果有输出,先备份好数据,然后sudo apt remove --purge把旧包清干净,再继续。我遇到过一台机器上同时装了 MariaDB 和 MySQL 的,结果两个服务抢同一个数据目录,报错信息完全看不出是端口问题。
2. 安装方式选型:apt 官方仓库与本地二进制包
2.1 为什么优先选 apt 官方仓库
Ubuntu 自带的软件源里其实就有 MySQL,但版本通常比较旧,而且并非 MySQL 官方维护。比如 Ubuntu 22.04 默认软件源里的是 MySQL 8.0.34 左右的某个构建版本,更新节奏跟不上官方。更关键的是,用系统自带的源安装,后续如果需要官方技术支持、需要特定补丁,很难保证一致性。
我的建议是:只要是联网环境,一律用 MySQL 官方 apt 仓库。理由有三个:
第一,版本可控。你想装 8.0 最新小版本还是指定某个历史版本,都能通过 apt 列表查到并精确安装,不会出现"想装 8.0.36 结果 apt 给了你一个 8.0.28"的错位。
第二,升级方便。之后官方发布新小版本,一条sudo apt upgrade就能带上 MySQL 内核更新,不需要重新下载安装包做原地升级。
第三,依赖管理省心。MySQL 依赖的libaio1、libnuma1这些库,apt 会一并帮你装好。自己下 tar 包的话,这些依赖全得手动处理,少一个库服务就起不来。
2.2 官方 tar 包安装适合什么场景
当然,apt 仓库不是万能的。如果你在离线内网环境,或者需要非常规的 MySQL 版本(比如 5.7.44 这种官方源里没有的),就得用官方提供的mysql-8.0-something-linux-glibc2.17-x86_64.tar.xz这类二进制包。
tar 包安装的核心流程是:解压、创建 mysql 用户、初始化数据目录、改配置文件、用mysqld_safe或 systemd 启动。步骤多,但每一步都可控,适合需要深度定制目录结构的生产环境。
不过我要提醒一句:如果只是自己学习或日常开发,别用 tar 包。我见过太多人因为 tar 包漏配某一步,折腾一整天最后发现是datadir权限不对,这种时间成本完全没必要。
2.3 两种方式的选型对比
| 对比维度 | apt 官方仓库 | 官方 tar 包 |
|---|---|---|
| 安装难度 | 低,两条命令搞定 | 高,涉及初始化数据目录、权限配置 |
| 版本控制 | 官方仓库内的版本可选 | 任意版本,可离线安装 |
| 依赖管理 | apt 自动处理 | 手动处理,缺失容易启动失败 |
| 升级维护 | 简单,apt upgrade 即可 | 复杂,需重新下载并替换二进制 |
| 适用场景 | 联网环境、开发测试、大多数生产 | 内网离线、特殊版本需求 |
我自己的习惯是:个人电脑和普通服务器用 apt 仓库;只有内网环境和版本强约束的容器场景,才会选择 tar 包。
3. 核心实操过程:apt 仓库完整安装 MySQL 8.0
3.1 添加 MySQL 官方 apt 仓库
先到 MySQL 官方下载页找到 apt 仓库的 deb 包地址。这一步可以直接用下面这串命令:
wget https://dev.mysql.com/get/mysql-apt-config_0.8.26-1_all.deb sudo dpkg -i mysql-apt-config_0.8.26-1_all.deb执行dpkg -i的时候,屏幕会弹出蓝色配置界面,让你选择要启用哪些 MySQL 产品。默认选项是 MySQL 8.0,直接按方向键选中 OK 回车即可。如果不小心选错了版本,之后可以用sudo dpkg-reconfigure mysql-apt-config重新配置。
装完这个配置包后,先做一次软件源刷新:
sudo apt update这个时候仔细看 apt 输出的信息,如果末尾出现类似Get:18 https://repo.mysql.com/apt/ubuntu jammy InRelease这样的行,说明官方源已经成功加入。看不到的话就别往下走了,回头查dpkg -i那一步是不是报错了。
3.2 安装 mysql-server
源就绪后,安装命令非常简短:
sudo apt install -y mysql-server这个命令会把mysql-server、mysql-client、mysql-common以及一堆依赖包一并装好。装完我习惯先确认版本号:
mysql --version正常会看到类似mysql Ver 8.0.35 for Linux on x86_64的输出。这一步确认的不只是版本,还能间接验证客户端工具是否装全。
需要注意,Ubuntu 22.04 上通过官方 apt 仓库安装的 MySQL 8.0,默认的 root 认证方式是auth_socket,也就是说用系统 root 用户身份直接登录 MySQL 可以不输入密码。这是 Ubuntu 对 MySQL 的特有改法,很多新手在这一步会卡住:明明没设密码,却怎么都登不进去。
如果只想先快速验证服务是否正常运行,就用这个方式登录:
sudo mysql -u root能进入mysql>提示符就说明服务正常。这个细节很重要,我先写在这里,后面讲安全配置时会继续展开。
3.3 初始化与安全配置
MySQL 8.0 的初始化在 apt 安装时已经由 postinst 脚本自动完成了,数据目录默认在/var/lib/mysql,不需要手动执行mysqld --initialize。但这不代表开箱即用,下一步就是跑官方安全脚本:
sudo mysql_secure_installation脚本会依次问你几个问题:设置 root 密码、是否移除匿名用户、是否禁止 root 远程登录、是否删除 test 数据库、是否刷新权限表。
我的建议是:一律选 y,但 root 密码这一项要特别注意。如果你前面通过sudo mysql -u root进入过数据库,并且 root 用的还是auth_socket,那这个脚本设置密码时会要求你先输入当前 root 密码。此时直接回车可能不行,得先手动把 root 的认证方式改成密码认证才行。
改认证方式的 SQL 是这样的:
ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '你的强密码'; FLUSH PRIVILEGES;caching_sha2_password是 MySQL 8.0 默认的密码认证插件,安全性比 5.7 时代的mysql_native_password高不少。但因为一些老客户端不兼容,需要兼容旧程序的情况下,你可能会想改回mysql_native_password。我的建议是能不用就不用,除非某个老应用实在连不上,否则别牺牲安全性。
3.4 客户端连接测试
安全配置完成后,用普通方式验证连接:
mysql -u root -p输入刚才设置的密码,进入 mysql 命令行后执行:
SELECT VERSION();看到版本号输出,说明安装和认证体系已经完整。此时我还会顺手做一件事——创建一个专门用于应用连接的账号,不建议所有程序都直接用 root 连库:
CREATE USER 'app'@'localhost' IDENTIFIED BY 'app_password'; GRANT ALL PRIVILEGES ON app_db.* TO 'app'@'localhost'; FLUSH PRIVILEGES;这个习惯能少很多事。后续如果某个应用连接出了问题,你可以直接通过权限回收来隔离风险,不用动 root 密码。
4. 配置调优与运行管理
4.1 配置文件里最值得动的几个参数
MySQL 的主配置文件在/etc/mysql/my.cnf,但这个文件本身只是入口,真正的配置段分散在/etc/mysql/conf.d/和/etc/mysql/mysql.conf.d/里。建议在mysql.conf.d下新建一个独立配置文件,比如custom.cnf,这样升级或者重装时不会被覆盖。
sudo vim /etc/mysql/mysql.conf.d/custom.cnf内容写上最核心的几项:
[mysqld] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql log-error = /var/log/mysql/error.log character-set-server = utf8mb4 collation-server = utf8mb4_0900_ai_ci max_connections = 300 innodb_buffer_pool_size = 1G slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2character-set-server和collation-server是中文场景的必备项。不统一字符集,以后写中文数据很容易出现乱码,查询排序也有幺蛾子。innodb_buffer_pool_size是 InnoDB 引擎的内存缓冲池,通常设为物理内存的 60% 到 70%。4GB 内存的机器设 1G 起步,内存小就调低。slow_query_log开启慢查询日志,配合long_query_time = 2把超过 2 秒的 SQL 记录下来,这是后续性能排查的线索来源。
改完配置后重启服务才能生效:
sudo systemctl restart mysql4.2 systemd 服务管理的正确姿势
MySQL 在 Ubuntu 22.04 上的服务名是mysql,不是mysqld。这个差别很关键,因为很多人从 CentOS 那边过来,习惯敲systemctl start mysqld,结果发现服务不存在。
日常管理就用这三条:
sudo systemctl status mysql sudo systemctl restart mysql sudo systemctl enable mysqlenable这一步很多人会忘。虽然 apt 安装时默认就设了开机自启,但如果你的服务器经过某些初始化脚本的"清洗",自启配置被关掉,重启后就可能连不上数据库。
查看服务是否自启:
systemctl is-enabled mysql输出enabled就是正常的。
4.3 连接数、进程与端口检查
服务启动后,用端口检查确认 MySQL 在监听:
sudo ss -tlnp | grep 3306看到LISTEN状态并且进程名是mysqld,就说明网络层面正常。如果是云服务器,还需要去控制台的安全组里放行 3306 端口的入站规则,否则外部客户端永远连不上,这个和系统防火墙没关系,是云厂商的安全策略。
如果想查看当前的连接数:
SHOW STATUS LIKE 'Threads_connected';这个值如果长期接近max_connections的上限,就要考虑是否是连接未释放或者确实需要扩容。常见的应用端问题里有连接池配置过小、事务长时间不提交占着连接不放等,先调整应用代码,别一上来就盲目调大max_connections。
4.4 远程连接与账号权限
默认配置下,MySQL 只监听本地127.0.0.1,外部客户端连不上。在custom.cnf里改一行:
bind-address = 0.0.0.0然后重启服务。但这里必须提醒:改成0.0.0.0意味着所有网卡都对外开放 3306 端口。如果你的服务器直接暴露在公网,建议配合防火墙只放行特定 IP 来源,不要裸奔。
同时,远程连接还需要一个非 localhost 限定的账号:
CREATE USER 'remote_user'@'192.168.1.%' IDENTIFIED BY 'remote_pass'; GRANT ALL PRIVILEGES ON *.* TO 'remote_user'@'192.168.1.%'; FLUSH PRIVILEGES;'192.168.1.%'表示只允许这个网段的机器连接,比'%'安全得多。
5. 常见问题排查与避坑实录
5.1 安装后无法用密码登录 root
这个我之前提过了,绝大多数情况是因为 root 默认走auth_socket认证。有些教程会让直接跳过mysql_secure_installation,但这会留下匿名用户和测试库的隐患。
处理思路:用sudo mysql -u root进入,强制把 root 改成caching_sha2_password认证并设置密码,然后再执行mysql_secure_installation就不会卡住了。
ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '密码'; FLUSH PRIVILEGES;如果你之前已经创建过非 root 用户且能登录,也可以直接在正常连接下执行这条 SQL。
5.2 启动失败且错误日志指向 datadir 问题
sudo systemctl start mysql后马上变 failed,第一反应不是反复重启,而是看错误日志:
sudo tail -100 /var/log/mysql/error.log常见的是:
[ERROR] [MY-012592] [InnoDB] Operating system error number 13 in a file operation.这是权限问题。数据目录/var/lib/mysql/的属主必须是mysql用户,如果被误改成 root,MySQL 就无法写入。修复:
sudo chown -R mysql:mysql /var/lib/mysql sudo systemctl start mysql如果是目录初始化不完整,日志会提示找不到系统表文件,那就得走初始化流程。备份数据后,把数据目录清空,重新初始化:
sudo mysqld --initialize --user=mysql注意这条命令会生成一个临时 root 密码,会打印在终端上,务必记下来,首次登录要用。
5.3 SSL 连接错误
MySQL 8.0 默认启用 SSL。很多客户端连接时报错和证书有关。最常见的情况是 JDBC 驱动版本太老,不支持 8.0 的 SSL 协商方式。
客户端连接时关闭 SSL 作为临时方案:
mysql -u app -p --skip-ssl但这不是长久之计。可靠做法是把 JDBC 连接串加上:
useSSL=false或反过来,指定证书验证路径:
useSSL=true&requireSSL=true&verifyServerCertificate=false需要说明的是,MySQL 8.0 的 SSL 默认用的是自签名证书,生产环境建议替换成机构签发的证书。替换后注意datadir下生成的ca.pem、server-cert.pem、server-key.pem文件的属主和权限,不要随意 chmod。
5.4 端口被占用导致启动异常
如果日志出现:
[ERROR] [MY-010743] [Server] Can't start server: Bind on TCP/IP port: Address already in use说明 3306 被其他进程占用。查看:
sudo ss -tlnp | grep 3306如果是之前的 MySQL 残留进程,直接杀掉再启动。如果被其他程序占用,就需要改 MySQL 的默认端口,在配置里加:
[mysqld] port = 3307之后客户端连接要显式指定端口。改端口是一种妥协方案,优先还是把 3306 断出来。
5.5 Docker 安装 MySQL 时的对应问题
现在很多人不再直接在系统里装 MySQL,而是用 Docker。如果你已经用 Docker 方式部署 MySQL,在 Ubuntu 22.04 下要注意 volume 权限和数据持久化问题。
最典型的是容器启动后立即退出,日志提示:
[ERROR] [MY-011259] [Server] Can't open the mysql.plugin table.大概率是挂在 volume 的数据目录权限不对。容器里的 mysql 用户 UID 是 999,你需要把宿主机目录属主改成 999:
sudo mkdir -p /data/mysql sudo chown -R 999:999 /data/mysql docker run -d --name mysql8 -p 3306:3306 \ -v /data/mysql:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=strongpass \ mysql:8.0如果你的宿主机同时存在直接安装的 MySQL,先停掉或改端口,避免容器和本机服务冲突。
5.6 5.7 版本在 Ubuntu 22 上的安装选择
Ubuntu 22.04 发布时,MySQL 5.7 已经处于生命周期尾部,官方 apt 仓库不再维护 5.7 的 Ubuntu 22 版本包。所以如果你想装 5.7,简单的apt install mysql-server-5.7是行不通的。
可行的路径是官方 tar 包安装,或者使用 Docker。我强烈建议直接 Docker 部署 5.7,因为手动在 Ubuntu 22 上跑 5.7 的 tar 包,往往会遇到libncurses.so.5缺失的问题,这是 Ubuntu 22 移除旧库导致的连锁反应。已经没有维护价值的 5.7 遇到系统库不兼容,本身就是一个信号:能升级到 8.0 就尽早升级。
5.7 安装后需要立刻做的一次备份
不管你是用 apt 装的还是 Docker 跑的,安装完成后建议立刻做一次逻辑备份,验证整条备份链路是通的。在 MySQL 8.0 环境下用自带工具即可:
mysqldump --single-transaction -u root -p --all-databases > /backup/all_databases_$(date +%F).sql--single-transaction在引擎是 InnoDB 时不锁表,适合在线备份。如果你的业务停顿窗口允许,也可以用--lock-all-tables物理一致性更强。
后续做增量备份或者跨机同步的话,就得考虑 XtraBackup 这类物理备份工具,配合 binlog 做时间点恢复。Ubuntu 22 上装 XtraBackup 也是走 Percona 官方源,离线环境就很麻烦,所以趁现在能联网,把备份脚本先跑一遍。
6. 从安装到上线的完整自检清单
整个流程走完后,我习惯用一张清单确认没有遗漏。这里免费分享出来,每次装完照着过一遍:
| 检查项 | 命令 | 预期结果 |
|---|---|---|
| 服务状态 | systemctl status mysql | active (running) |
| 开机自启 | systemctl is-enabled mysql | enabled |
| 数据库版本 | mysql -V | 版本号正常 |
| root 密码登录 | mysql -u root -p | 能进入命令行 |
| 字符集 | SHOW VARIABLES LIKE 'character_set_server'; | utf8mb4 |
| 端口监听 | sudo ss -tlnp | grep 3306 | LISTEN |
| 慢查询日志 | cat /var/log/mysql/slow.log | 文件存在可写 |
| 备份链路 | mysqldump ... > test.sql | 无报错 |
完成这些检查后,MySQL 处于一个比较健康的初始状态。之后如果想把数据库从内网同步到其他系统,比如基于 Flink 做 MySQL 到 ClickHouse 的同步链路,前提就是公网或专线可达、binlog 开启、账号具备对应复制权限,这些都可以在初始安装阶段就预留好,而不是等业务跑起来再回头折腾。
我自己每次装完 MySQL 后,必定会做的一件事是把错误日志路径和慢查询日志路径写进自己的记事本,方便后续巡检。很多问题不是安装时就爆出来的,而是运行几天后才逐渐显现,有日志在手,排查起来完全不在一个量级。
装好 MySQL 只是开始,后续的监控、权限管控和备份策略才是真正让人省心的部分。希望这篇教程能帮你一次装好、顺利跑起来。