
不管你是刚把 Ubuntu 装好、想搭个本地开发环境还是给服务器部署业务库MySQL 基本上都是绕不开的一环。我这些年帮人排查过不少这类问题发现多数人卡住的点根本不在 SQL 上反而是安装这一步就摔了跟头——要么装完不知道初始密码是什么要么装完死活连不上要么字符集对不上导致程序报错。这篇文章我就把 Ubuntu 下安装 MySQL 的完整链路拆开讲清楚从版本选型、安装方式、安全初始化到常用配置和排障思路一次性聊透。内容覆盖 Ubuntu 22.04 和 24.04 LTS 这两个主流版本默认带的都是 MySQL 8.0 系列这也是目前最稳的组合。1. 装之前先弄明白几件事1.1 为什么强烈建议用 apt 直接装很多新手一搜安装教程看到源码编译安装就开始头皮发麻其实完全没必要。Ubuntu 的官方软件源里就有 MySQL直接apt install mysql-server是最省事、最不容易出错的方式。为什么我强调这一点因为源码编译安装 MySQL 是个大工程——你要装 cmake、boost、gcc 一堆依赖还要处理各种版本匹配问题折腾下来半天就没了。之前有个朋友非要去官网下载 tar.gz 源码包自己编结果光解决cmake和boost版本不兼容就耗了两个晚上。而用 apt 装的好处有几个依赖关系自动帮你处理、安装完系统服务自动注册、以后升级安全补丁也方便。你不需要关心 MySQL 具体装在了哪个目录apt会按照 Debian 的目录规范放好文件配置统一在/etc/mysql下数据默认在/var/lib/mysql。对于绝大多数人来说这就够了。注意如果你用的不是官方源而是自己加的第三方源那版本可能比较旧或者不太稳定。建议保持默认官方源装出来的版本就是 Ubuntu 官方测试过的版本虽然不一定是最新但稳定性和兼容性最有保障。1.2 版本选择不是“越新越好”Ubuntu 仓库里的 MySQL 版本是跟着系统版本走的。比如 Ubuntu 22.04 官方源里是 MySQL 8.0.3x 左右Ubuntu 24.04 里是 MySQL 8.0.3x 及以上的小版本。至于热搜词里那个“mysql 9.7”现在官方已经出了 MySQL 9.x 系列但它是 Innovation 版本也就是创新版功能更新快但维护周期短。我个人的实测感受是生产环境老老实实用 8.0 LTS 系列就对了。为什么这么选MySQL 8.0 是长期支持版本bug 修复和安全更新都有保证而且大部分云厂商、框架、中间件对 8.0 的适配已经非常成熟。你如果贸然上 9.x很可能遇到某个 ORM 库或者老项目里的语法不兼容到时候排查起来非常痛苦。开发机上想尝鲜另说但你要给项目用还是克制一点好。另外提一句老掉牙的 MySQL 5.7。如果你的机器是 Ubuntu 18.04 或更早版本仓库里可能还是 5.7那属于老古董了能升级就升级吧。8.0 和 5.7 的差异不是一星半点特别是认证插件、字符集、窗口函数这些底层变化真没必要抱着旧版本不放手。1.3 确认环境和系统干净程度安装之前先做几步检查能帮你省掉后面大量排查时间。第一步看系统版本lsb_release -a这里要留意 32 位还是 64 位的问题。现在的 Ubuntu 基本都是 64 位MySQL 8.0 也只支持 64 位系统如果你用的是老旧的 32 位镜像那就别折腾了换个操作系统吧。第二步检查系统里是不是已经存在 MySQL 或者 MariaDB。Ubuntu 的软件源里其实默认带的是 MariaDB 的元包因为 MariaDB 是 MySQL 的一个分支很多人混淆。如果之前装过 MariaDB 再装 MySQL端口和 socket 文件都会冲突。检查命令dpkg -l | grep -E mysql|mariadb如果有残留服务先停掉、卸载干净再继续。你也不想装到一半发现端口被占用那体验真的很糟心。2. 完整安装过程实录2.1 更新软件源并开始安装这一步没什么技术含量但千万不要跳过。先把软件包索引刷新一下确保拉到的是最新包列表sudo apt update然后安装 MySQL 服务器sudo apt install mysql-server -y如果你是在一个刚装的 Ubuntu 系统上操作可能还会提示你安装一些依赖包比如libaio1、libncurses5之类的不用管自动装上就好。国内网络环境不好的话可能会比较慢你可以考虑换个国内的 apt 源换源的过程就不展开说了总之就一句话换源只改/etc/apt/sources.list或/etc/apt/sources.list.d/下面的文件改成对应版本的国内镜像地址就可以。安装过程通常一两分钟就结束了。装完以后检查一下服务状态sudo systemctl status mysql正常情况下输出里应该有active (running)说明服务已经起来了。如果没有看一下日志再判断后面我会讲常见的启动失败原因。服务还没起来的也别着急sudo systemctl start mysql先手动拉起来再排查问题。2.2 查看版本和基本信息确认装完以后最基本的验证是看版本mysql --version正常输出类似mysql Ver 8.0.36-0ubuntu0.22.04.1 for Linux on x86_64这样。看到版本号以后你心里就有底了。接着用 root 试着登录一下sudo mysql注意这里不是mysql -u root -p而是直接sudo mysql。原因在于 Ubuntu 仓库里的 MySQL 8.0root 用户默认用的是auth_socket认证插件它不认密码只认 Unix 系统用户身份。只要你当前系统用户是 sudo 权限就能直接进 MySQL。这一步可以说是整个安装过程里最容易引起困惑的地方——很多朋友在这一步输入密码却发现密码根本不存在其实是认证方式的问题后面我会展开讲。进去以后顺手执行几条命令确认一下SELECT VERSION(); SELECT port; SELECT datadir;正常会看到版本号、3306 端口和数据目录路径/var/lib/mysql。到这里最基础的那一层就算打通了。2.3 和 root 密码较劲MySQL 8.0 的认证机制变化这一步是整个安装过程里最值得多写几句的地方因为你迟早会被它绊倒。上面提到过Ubuntu 默认的 root 用户用的是auth_socket插件所以你在命令行想用密码登录 root 是登不进去的密码压根就没有被设置过。很多人网上搜“mysql的初始密码是什么”然后跑到/etc/mysql里翻配置文件甚至去看/var/log/mysql/error.log其实都不用根本没有所谓的初始密码。这就是个认知偏差。解决方式也很简单两条路不走弯路的方式一保持auth_socket不动日常就用sudo mysql进库管理。这种方式适合自己本机开发用安全上也没毛病因为能拿到 sudo 权限的人本来就能玩坏系统。更常规的方式二把 root 换成常规的密码认证。执行以下 SQLALTER USER rootlocalhost IDENTIFIED WITH caching_sha2_password BY 你的强密码; FLUSH PRIVILEGES;这里用了caching_sha2_password是 MySQL 8.0 的默认认证插件比老版的mysql_native_password安全性高很多。有些老项目里用的客户端连接库版本太老不支持这个新插件会报Authentication plugin caching_sha2_password cannot be loaded的错误。如果遇到这种情况你可以单独给这个老客户端建一个专用账号用mysql_native_password但千万别把全局默认改回去安全上得不偿失。改完以后退出再用密码验证一下mysql -u root -p输入密码能进去就说明这部分搞定了。注意MySQL 8.0 默认的密码策略是validate_password组件生效的密码要求至少 8 位并且包含大小写字母、数字和特殊字符。你要是设了个太简单的密码系统会直接拒绝执行 ALTER USER报ERROR 1819。本地开发嫌麻烦可以调低策略级别但生产环境请务必保持强密码。2.4 跑一遍安全初始化脚本MySQL 安装包里有自带的安全初始化脚本名字叫mysql_secure_installation。运行一下sudo mysql_secure_installation它会带你做一轮安全的配置每一步都有提示包括设置 root 密码如果你之前没设过、删除匿名用户、禁止 root 远程登录、删除 test 测试库、重新加载权限表。这些选项全部建议选 Yes。很多人嫌麻烦直接跳过这步个人实测下来这步真不该省。匿名用户看起来不起眼但它意味着任何人不需要密码就能以某个用户身份连上数据库这在有公网 IP 的机器上就是纯粹的裸奔。而 test 库虽然只是默认测试库生产环境里留着它同样是个隐患。有人可能会说我本地开发机哪来那么多讲究我的回答是养成好习惯的成本远比出了问题再补救低得多。跑一遍这个脚本前前后后不到一分钟磨刀不误砍柴工。3. 核心配置与调优装完只是开始3.1 字符集设置utf8mb4 不是可选项MySQL 8.0 其实默认字符集已经是utf8mb4了但以前从 5.7 升上来或者手动初始化过的库可能还是老配置。字符集设置不对最典型的症状就是中文显示成问号或者程序写中文报Incorrect string value错误。字符集为什么必须用utf8mb4而不是utf8因为 MySQL 里的utf8实际上最多只支持 3 个字节存不了 emoji 表情和一些生僻字。utf8mb4才是真正的完整 Unicode 编码它向下兼容utf8所以没有任何理由继续用老的utf8。查看当前字符集配置SHOW VARIABLES LIKE character_set%;如果发现不是 utf8mb4修改 MySQL 配置文件。Ubuntu 下 MySQL 的配置入口是/etc/mysql/my.cnf但实际内容都是 include 进来的真正的业务配置建议放在/etc/mysql/mysql.conf.d/mysqld.cnf里。在[mysqld]段下加三行[mysqld] character-set-server utf8mb4 collation-server utf8mb4_unicode_ci skip-character-set-client-handshake前面两个好理解第三个是什么意思它让服务端不再接受客户端单独指定的字符集强制统一用服务端配置这样即使你的连接串里charset参数漏写了也不会出现乱码。改完重启sudo systemctl restart mysql实测下来这一步能避免掉很多“我以为我设置了、其实没设上”的鬼故事。3.2 远程访问配置三步打通缺一不可经常有朋友问为什么 MySQL 在 Ubuntu 上装好了程序连不上如果你用的是同一台机器基本不会有问题一旦你试图从另一台机器连过来就需要检查三个层面。第一步改绑定地址。MySQL 默认只监听本机回环地址127.0.0.1这也是一层安全防护。要让别的机器能访问把/etc/mysql/mysql.conf.d/mysqld.cnf里的bind-address改成0.0.0.0。sudo sed -i s/^bind-address.*/bind-address 0.0.0.0/ /etc/mysql/mysql.conf.d/mysqld.cnf改完重启生效。第二步开放防火墙端口。Ubuntu 上如果你启用了 ufw默认会挡掉 3306 端口。执行sudo ufw allow from 192.168.1.0/24 to any port 3306我最推荐的做法是只允许内网网段访问而不是直接ufw allow 3306对全网开放。数据库这种核心资产少暴露一点是一点。第三步给用户授权。MySQL 里的账号是“用户名 来源主机”绑定的默认的 root 只允许localhost登录。你需要新建一个用户或修改 root 的限制CREATE USER app192.168.1.% IDENTIFIED BY 强密码; GRANT ALL PRIVILEGES ON *.* TO app192.168.1.%; FLUSH PRIVILEGES;这里192.168.1.%表示来自该网段的机器都可以用这个账号登录。如果你只想让某一台机器连就把%换成具体 IP。更精细的姿势是只授某个库的权限GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO app192.168.1.%;授最小权限是基本原则。很多人图省事直接给 root 开远程一旦密码泄露别人拿到的就是数据库的全部权限这跟把家门钥匙送人没什么区别。3.3 基础性能参数先动这几个就够用系统默认的 MySQL 配置是比较保守的适合小内存 VPS。如果你的机器内存比较充裕比如 8G 以上可以适当调整几个参数。先看当前配置SHOW VARIABLES LIKE innodb_buffer_pool_size; SHOW VARIABLES LIKE max_connections;innodb_buffer_pool_size是 InnoDB 的缓存池大小也是 MySQL 内存使用的头号大户。一般建议设为物理内存的 60% 到 70%。比如机器有 8G 内存可以设为5G左右。当然别傻乎乎地把全部内存都给 MySQL系统本身、PHP/Python/Java 等应用进程也要吃内存。max_connections默认是 151如果你的业务并发比较大可以适当调到 300 或者 500。但要注意每个连接都会占用线程栈和内存调得太高可能 OOM。我试过在 2G 内存的机器上把max_connections调到 1000结果 MySQL 还没撑爆系统先 swap 起来了。修改方式同样是在/etc/mysql/mysql.conf.d/mysqld.cnf的[mysqld]段下innodb_buffer_pool_size 5G max_connections 500改完别忘了重启。这里的核心思想是先改这几个硬参数其他的缓存、日志、排序相关的参数等你真正遇到性能瓶颈了再根据业务特性去调别一上来就整花活。4. 常见问题与排查技巧实录4.1 忘了 root 密码不用重装三分钟找回这个场景太常见了尤其是那些“先部署再给客户交付”的项目密码是前任配的交接文档里什么都没写。很多人的第一反应是重装 MySQL但完全没必要。Ubuntu 上 MySQL 8.0 找回密码的办法先停掉服务然后用跳过授权表的方式临时拉起服务。sudo systemctl stop mysql sudo mysqld_safe --skip-grant-tables 注意这里要确保目录权限正常mysqld_safe需要以 mysql 用户运行如果你是 root 执行加上--usermysql。临时启动后免密进入mysql -u root然后刷新权限并重设密码FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED WITH caching_sha2_password BY 新密码;重置完退出把刚才临时起的进程关掉再正常启动sudo pkill mysqld_safe sudo systemctl start mysql这个方法也适用于数据库还能启动但密码忘了的常规场景。核心原理就是--skip-grant-tables让 MySQL 跳过所有权限校验这么危险的事只能在本地临时用用完立刻恢复。4.2 安装后服务起不来大概率是这几种原因我在 Ubuntu 上遇到过几次 MySQL 启动失败排查路径基本固定。首先看日志sudo tail -100 /var/log/mysql/error.log最常见的一种是数据目录权限不对。之前我用rsync从旧服务器同步数据目录到新机器忘了改属主MySQL 起不来。解决办法sudo chown -R mysql:mysql /var/lib/mysql还有一种情况是磁盘满了/var/lib/mysql所在分区写不进数据服务也会启动失败。用df -h看一下磁盘空间如果满了先清理大文件再启动。再有一种是配置文件写坏了。比如字符串拼错或者缩进不对mysqld会拒绝启动。这种情况下error.log里会有明确的unknown variable提示把改坏的那行注释掉或者改回来就行。启动失败的问题八成跑不出这三类目录权限、磁盘空间、配置语法。按顺序查基本能解决。4.3 无法远程连接到 MySQL按这个顺序排查远程连不上这个问题我见过无数个案例。最烦人的是那种“我明明配置了 bind-address 0.0.0.0为什么还是连不上”。我的排查顺序是这样的先确认 MySQL 确实监听在所有网卡上ss -lntp | grep 3306正常输出应该是0.0.0.0:3306而不是127.0.0.1:3306。如果只有 127.0.0.1说明 bind-address 没生效检查有没有改错配置文件。然后从客户端机器上测试端口通不通telnet 服务器IP 3306如果端口不通那就是防火墙或者云安全组的问题。Ubuntu 上ufw status看看规则云服务器还要去控制台的安全组里放行 3306 端口。端口通了之后再尝试用 MySQL 客户端连接mysql -h 服务器IP -u app -p如果报Access denied那就是用户授权的问题回到前面那一步重新GRANT一下。如果报Host xxx is not allowed to connect to this MySQL server同样是授权问题用户来源主机没匹配上。远程访问是一个链路问题端口、防火墙、账号授权、监听地址任何一环断了都连不上。按顺序走一遍不会超过五分钟就能定位。4.4 安装源选择不当MySQL 和 MariaDB 的混乱Ubuntu 软件源里有个让人容易踩坑的细节很多教程说apt install mysql但如果你敲的是apt install mysql或者apt install mysql-client可能会装成 MariaDB 的客户端。因为 Ubuntu 把默认的mysql-client元包指向了 MariaDB 分支。怎么判断自己装的是不是真 MySQLmysql --version如果输出里带MariaDB字样说明你装的是 MariaDB不是 MySQL。MariaDB 兼容 MySQL 的很多语法但它毕竟不是 MySQL某些行为细节上是有差异的比如权限表的处理方式、GTID 的实现逻辑用的工具链也不一样。如果你确认自己要的是 MySQL就认准mysql-server这个包名。另外有些人会跑去官网下 MySQL APT 仓库的 deb 包自己配置这条路也可以走能拿到比 Ubuntu 自带更新的版本。但代价是你要自己管理这个第三方源的升级。多数场景下 Ubuntu 自带的 MySQL 版本完全够用没必要徒增维护成本。5. 装好之后日常使用还需要注意什么5.1 备份不能只靠 mysqldumpMySQL 装好只是个起点学会日常运维才不容易翻车。最基础的备份逻辑是逻辑备份和物理备份分开理解。逻辑备份用mysqldumpmysqldump -u root -p --single-transaction --routines --triggers --databases mydb mydb_$(date %F).sql--single-transaction是在 InnoDB 引擎下做到不停机热备的关键它利用事务特性让备份期间的数据保持一致快照不会锁表。--routines和--triggers是顺带把存储过程和触发器一起备份这两个东西经常被人遗漏恢复的时候才追悔莫及。但逻辑备份有个缺陷数据量大了以后恢复速度很慢。如果你有几百 G 的业务库备份和恢复都是灾难。这时候就要考虑物理备份直接用xtrabackup这类工具把整个/var/lib/mysql目录打包。我个人的经验是小库几 G 以内用 mysqldump 完全没问题大库上物理备份 binlog 增量备份的组合才靠谱。备份这块平时看起来没用真到数据误删的时候才能体会到什么叫救命稻草。5.2 binlog 日志的正确姿势说到 binlog就多提一嘴。MySQL 8.0 默认是开启 binlog 的但很多人根本不理解它有什么用。binlog 是 MySQL 的二进制日志记录所有更改数据的操作两个核心场景数据恢复和时间点回滚。举个例子今天凌晨 3 点跑了全量备份下午 4 点有人手滑执行了 DELETE 删了核心表。这时候你只需要把全量备份恢复回去再通过 binlog 把凌晨 3 点到下午 4 点之间的操作重放一遍数据就完整找回来了。没有 binlog 的话中间这几个小时的数据就是永久性丢失。查看 binlog 状态SHOW VARIABLES LIKE log_bin;我的建议是保持默认开启同时把binlog_expire_logs_seconds设成一个合理的值比如 7 天binlog_expire_logs_seconds 604800这样系统会自动清理 7 天前的 binlog 文件不会让你的磁盘被日志撑爆。5.3 升级和打补丁要克制Ubuntu 系统更新时偶尔会带出 MySQL 的小版本升级这个不必抗拒sudo apt upgrade正常跟着升就好。但大版本升级比如 5.7 升 8.0 或者 8.0 升 9.x千万要谨慎。MySQL 的大版本升级是不可逆的特别是 5.7 到 8.0数据字典、认证插件这些底层都要重构。升完再想降回去基本只能靠全量备份恢复。所以升级之前一定做好两件事全量备份 在测试环境先演练一遍。关于 MySQL 的官方 APT 仓库如果你之前手动配置过升级时它会提示你选择要不要启用某些模块比如 MySQL Workbench、Router 这些。这些组件装不装看你需求但核心的mysql-server一定要跟上安全更新。5.4 别忘了 MySQL Workbench 或者命令行工具命令行操作对新手来说确实有门槛记不住命令很正常所以我会建议你装一个可视化工具。Ubuntu 下可以装 MySQL Workbenchsudo apt install mysql-workbench不过说实话MySQL Workbench 这个工具有点重启动速度一般。如果只是日常看看数据、跑跑查询我更推荐轻量级的方案。比如用mysql命令行配一个.my.cnf文件每次登录不用敲密码和账号[client] user root password 你的密码 host localhost然后在命令行直接敲mysql就能进体验会好很多。也可以用 DBeaver 这类通用数据库工具连 MySQL、PostgreSQL、SQLite 都能一把梭适合平时要同时管多种库的情况。写在最后的真心话东西是死的人是活的。Ubuntu 下装 MySQL 这件事网上教程一抓一大把但为什么还有人天天踩坑问题就出在大部分教程只告诉你“怎么做”不告诉你“为什么这么做”。比如 root 密码为什么设不了bind-address 为什么不生效服务为什么起不来这些问题只有真正经历过才会懂。我写这篇文章的初衷就是把这些“为什么”一次性讲透让你看完不只是会敲命令而是脑子里有一个清晰的排查链路。再分享一个小技巧改完任何 MySQL 配置文件先用mysqld --validate-config检查一下再重启别急着直接刷服务。这条命令会帮你提前发现配置里的语法错误省掉“服务起不来又不知道错在哪”的尴尬。反正我用这个习惯之后几乎没有再因为配置错误而折腾过 MySQL 了。