☰
Ubuntu安装MySQL 8完整指南:从APT配置到性能优化与排错
2026/10/6 4:03:45 网站建设 项目流程

说实话,有一个项目标题写的是"Ubnutn Linux安装MySql8",一眼就能看出来是把 Ubuntu 拼错了,但也不影响理解——就是要在 Ubuntu 上把 MySQL 8 装好、配好、跑起来。我这些年折腾过不少 Linux 服务器,不管你是云服务器、虚拟机还是家里的迷你主机,只要想跑 MySQL 8,大概率都会踩到几个同样的坑。

这篇文章我打算完整走一遍我在生产环境里常用的安装流程和配置方案,从环境准备到安装、配置、优化、排错都会覆盖到。我的建议是已经有一定 Linux 基础、想快速搞定 MySQL 8 的朋友可以直接照着操作;如果你是刚接触 Linux 的新手,先把常用的几条命令弄明白,再动手也会顺很多。

1. 装 MySQL 8 之前,先把环境和思路理清楚

1.1 安装方式三选一,别一上来就敲 apt install

很多人看到"安装 MySQL"第一反应就是apt install mysql-server,但这在 Ubuntu 上其实不一定是最优解。Ubuntu 系统的软件源里确实有 MySQL 的包,但版本通常不是最新的,而且一旦你后面要挂 MySQL 官方的工具链或监控组件,用的还是官方仓库更稳妥。

从实际项目出发,我会按场景做选择:

安装方式适合场景优点缺点
Ubuntu 官方源安装测试环境、快速验证、不折腾命令简单、系统集成度高版本可能滞后,升级策略不够灵活
MySQL 官方 APT 仓库生产环境、需要长期维护版本新、补丁及时、工具链完整需要额外配置 apt 源
通用二进制 tar 包内网部署、高度定制化需求目录可控、不依赖系统包管理初始化、维护都要手动来,门槛较高

我个人最推荐的是第二种,也就是走 MySQL 官方 APT 仓库。虽然第一次配置仓库时感觉多了一步,但后续的升级、维护非常省心,各版本之间的切换自由度也高。很多用户装完就不管了,等遇到安全漏洞才想到要升级才发现系统源里根本没有新版本,这种酸爽我经历过,所以先把方案选对很重要。

1.2 先确认系统版本和残留环境

动手之前,先花两分钟确认环境。有些朋友拿到的服务器是别人用过的,里面可能残留着旧版 MySQL、MariaDB 或者混乱的配置文件,直接装新的很容易起冲突。

打开终端,依次执行:

# 查看Ubuntu版本 lsb_release -a # 查看是否已有mysql或mariadb相关包 dpkg -l | grep -E "mysql|mariadb" # 查看3306端口是否被占用 ss -tlnp | grep 3306

我遇到过的情况是这样:一台 Ubuntu 20.04 的机器上装了 MariaDB,端口还占着 3306,新装的 MySQL 自然启动不了。还有些系统里残留了/etc/mysql目录下的旧配置,导致新的 MySQL 服务读取到了奇怪的参数。

如果有 MariaDB 或旧 MySQL,我们通常先停掉服务再卸载干净:

sudo systemctl stop mariadb sudo systemctl disable mariadb sudo apt remove --purge mariadb-* mysql-*

不过这里有个经验之谈:卸载 mysql 相关包时,不要顺手把/etc/mysql目录也删了,因为 MySQL 官方仓库安装时也会往这个目录写配置,留着至少能对照一下默认配置长啥样。当然,如果确定要全新环境,暴力删了也问题不大。

1.3 检查网络与基础依赖

MySQL 安装过程需要从 Ubuntu 和 MySQL 官方仓库拉取大量依赖包,如果服务器出口网络有限制,会出现下载失败、pkgs 冲突这些幺蛾子。建议先更新一次软件包列表:

sudo apt update

如果卡住或报错,多半是源的问题。这时候可以检查/etc/apt/sources.list里的源配置,国内服务器可以换成国内镜像源。换源这个操作网上一堆教程,我这里就不展开了,但要提醒:换源后务必要apt update验证源是否可用,不然很容易在安装时翻车。

另外有个小坑,某些精简版 Ubuntu(比如 Docker 镜像里裁剪过的)可能没有装 wget、tar 这些基础工具,提前装好:

sudo apt install -y wget tar gnupg lsb-release

尤其要注意 gnupg,MySQL 官方 APT 仓库导入 GPG 密钥时需要用到,很多安装教程里没提,但缺了它你会卡在导入密钥那一步。

2. 完整安装流程,从 APT 源到能用

2.1 配置 MySQL 官方 APT 仓库

上面我们选了官方 APT 仓库的方案,接下来就实际操作。先从 MySQL 官方下载仓库配置文件:

cd /tmp wget https://dev.mysql.com/get/mysql-apt-config_0.8.33-1_all.deb

这个.deb文件的内容是告诉系统去哪里找 MySQL 的软件仓库,安装过程会弹出来一个图形化配置界面,让你选要使用的 MySQL 版本。默认就是 MySQL 8.0,直接选择 OK 即可。

sudo dpkg -i mysql-apt-config_0.8.33-1_all.deb sudo apt update

更新完软件源后,可以验证一下是否已经能看到 MySQL 8.0 的包:

apt-cache policy mysql-server

如果结果里有mysql-server指向repo.mysql.com的地址,说明仓库配置成功。

注意:有些版本的 apt 源配置文件名里带着具体版本号,比如/etc/apt/sources.list.d/mysql.list,后续如果要切版本,修改这个文件就行。平时不建议动它。

2.2 安装 MySQL Server 与初始化

仓库准备好之后,安装就变得很简单:

sudo apt install -y mysql-server

这个过程会下载并安装 mysql-server、mysql-client、mysql-common 等一堆包。重点来了——安装完成后的初始 root 认证方式会让很多人懵。

MySQL 8.0 安装在 Ubuntu 上,root 账号默认用的是auth_socket插件认证,意思是只要你是系统 root 用户(或 sudo 用户),就可以免密登录 MySQL。这是 Debian/Ubuntu 系特有的默认设置,初衷是安全,但对不熟悉的人来说非常不直观。

验证一下:

sudo mysql

能进入到 MySQL 命令行,说明安装成功。查看 root 的认证方式:

SELECT user, host, plugin FROM mysql.user WHERE user='root';

此时 root 对应的 plugin 大概率是auth_socket。如果你要使用 root 远程登录或通过密码方式访问,需要手动改掉。我用得最多的方式是改成标准的密码认证,并设置强密码:

ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '你的强密码'; FLUSH PRIVILEGES;

这里要特别说一下:MySQL 8.0 默认的认证插件已经从mysql_native_password改成了caching_sha2_password。如果你的客户端工具很旧,比如老版本的 PHP、Navicat 11 或更老的驱动,可能不支持新插件。遇到这类情况,要么升级客户端驱动,要么把用户改动成IDENTIFIED WITH mysql_native_password BY '密码'。但从长远看,尽量兼容新插件才是正路,老插件的安全性已经不太行了。

2.3 跑一遍安全加固脚本

MySQL 自带了一个安全加固脚本,用来清理匿名用户、测试数据库、禁用 root 远程登录等。执行:

sudo mysql_secure_installation

这个脚本会问你几个问题:

  • 密码强度校验(VALIDATE PASSWORD COMPONENT)
  • 是否移除匿名用户
  • 是否禁止 root 远程登录
  • 是否删除 test 数据库
  • 是否重新加载权限表

我一般都会选择开启密码强度校验,并移除匿名用户和 test 库。这里有个实际坑:脚本开启密码校验组件后,要求你设置的密码必须包含大小写字母、数字和特殊字符,如果密码强度不够会一直提示,直到你输入满足条件的密码。如果你只是想快速搭建环境,这一步可以先跳过校验组件的安装,后面手动配置时再补上。

2.4 设置字符集与存储引擎默认值

MySQL 8.0 其实默认字符集就是 utf8mb4 了,比 5.7 时代默认 latin1 要靠谱得多。不过我还是建议在主配置里显式声明,避免不同客户端连接时出现编码猜测不一致的问题。

编辑 MySQL 配置文件:

sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

在[mysqld]段落里加上:

[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_0900_ai_ci

utf8mb4_0900_ai_ci是 MySQL 8.0 默认的排序规则,也是官方推荐的。相比旧的utf8mb4_general_ci,它对 Unicode 的支持更完整,排序更遵循现代规则。如果你还在用 5.6 或 5.7 的备份文件导入到 8.0,注意兼容性,尽量统一成utf8mb4_0900_ai_ci,不然后面数据排序和比较结果会有细微差别。

同时,考虑到实际业务需求,我通常也会设一下时区:

default-time-zone = '+08:00'

如果你的业务是跨时区的,不要硬设这个值,而是让各会话自己设置time_zone,否则时间数据会乱。

改完配置后,重启服务:

sudo systemctl restart mysql

确认状态:

sudo systemctl status mysql

如果状态是 active (running),说明服务正常。

3. 性能与安全配置,这才是生产环境的关键

3.1 innodb_buffer_pool_size 怎么算

很多同学装完 MySQL 就急着往里灌数据,但生产环境里一个关键参数就能决定数据库的生死——innodb_buffer_pool_size。这个参数控制 InnoDB 缓冲池大小,缓冲池用来缓存表数据和索引,直接影响读写性能。

一个常用的经验值是:如果机器内存被 MySQL 独占,缓冲池可以设为物理内存的 60%-70%。如果机器上还跑着 Nginx、PHP、Java 应用等,那就要保守一点,建议定在 40%-50%。

假设你的服务器内存为 8GB,上面还跑着一个 Java 应用,那么可以这样设定:

innodb_buffer_pool_size = 4G

修改配置后重启生效。另外 MySQL 8.0 还支持在线调整这个参数,不需要重启:

SET GLOBAL innodb_buffer_pool_size = 4 * 1024 * 1024 * 1024;

这里有个单位坑:innodb_buffer_pool_size的单位是字节,所以4G要写成4294967296,如果直接在配置里写4G,MySQL 识别不了。配置文件的写法是允许带 G 的,但 SQL 里在线修改时不许。

3.2 连接数与最大并发

另一组常见参数是max_connections和max_connect_errors。默认的 151 个连接往往不够用,尤其当应用连接池、后台任务、监控程序同时连接时,很容易爆连接。

查看当前连接情况:

SHOW VARIABLES LIKE 'max_connections'; SHOW STATUS LIKE 'Threads_connected';

一般来说,一台普通应用服务器把max_connections调到 500 到 1000 是比较合理的。但要注意,连接数不是越大越好,每个连接都会占用内存;如果应用里出现大量休眠连接,调大数量反而耗尽内存。

我建议同时做两件事:一是调大max_connections,二是缩短wait_timeout和interactive_timeout,让闲置连接更快释放:

max_connections = 500 max_connect_errors = 1000 wait_timeout = 600 interactive_timeout = 600

wait_timeout是普通连接的空闲超时,interactive_timeout是交互式连接(比如客户端工具)的空闲超时。把这两个值设置在 10-15 分钟,能有效避免连接被僵尸进程占满。

3.3 二进制日志与数据安全

MySQL 8.0 默认已经开启了二进制日志(binlog),用于复制和恢复。但默认的保留时间和大小需要关注,否则日志文件会越攒越多,把磁盘撑爆。

在配置文件中可以设置:

log-bin = /var/log/mysql/mysql-bin binlog_expire_logs_seconds = 604800 max_binlog_size = 100M

binlog_expire_logs_seconds = 604800表示保留 7 天的 binlog。max_binlog_size = 100M是单个 binlog 文件的大小上限,超过后自动滚动下一个文件。

要说明一点:很多人在测试环境装完 MySQL 之后,会发现/var/lib/mysql目录膨胀得很快,80% 的情况是 binlog 没清理。如果对时间点恢复(PITR)没有需求,可以按天保留 2-3 天的 binlog 就足够。

数据目录千万别放到系统盘根分区底下,不然日志一膨胀,整个系统就不动了。我的习惯是,如果有单独的数据盘,就把datadir指过去:

datadir = /data/mysql

改这个参数时,记得把旧数据目录的文件完整复制过去,比如:

sudo rsync -av /var/lib/mysql/ /data/mysql/ sudo chown -R mysql:mysql /data/mysql

3.4 最小化账户权限与远程访问

生产环境的 MySQL,一定要给应用创建单独账号,而不是让应用去连 root。这算是最基础的安全意识。创建这样一个业务账号的典型方式:

CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY '强密码'; GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app_user'@'192.168.1.%'; FLUSH PRIVILEGES;

这里192.168.1.%限定来源 IP 网段,比%远程访问安全得多。尽量保持最小权限,按业务需要给权限,别图省事给一个ALL PRIVILEGES。

远程访问还需要确认 MySQL 监听的地址。默认情况下,MySQL 只监听本机地址,配置文件里:

bind-address = 0.0.0.0

设为0.0.0.0表示监听所有网卡,这样远程就能访问了。如果只允许特定网段的机器访问,也可以绑定到对应网卡 IP。防火墙需要放行 3306 端口:

sudo ufw allow from 192.168.1.0/24 to any port 3306

还有个看似小事但其实影响很大的配置:skip_name_resolve。如果远程连接很多,每次都做反向 DNS 解析会拖慢连接速度。我一般会在内网环境开启:

skip-name-resolve = ON

注意,开启后 MySQL 的授权表里必须使用 IP 而不是主机名匹配用户,否则连接会被拒。

4. 排错笔记:那些一碰就碎的坑

4.1 root 密码明明设置了却登不进去

这个问题出现频率极高,场景通常是:你用sudo mysql能进,执行了ALTER USER设置了密码,然后退出再用mysql -u root -p登录,却一直报密码错误。

原因多半是之前的auth_socket认证导致 MySQL 缓存了旧信息,或者你修改密码时语法不对。其实sudo mysql能进,说明服务正常,关键是密码修改这一步有没有真正生效。

重新认证一次,进入 MySQL 后查看当前认证方式:

SELECT user, host, plugin FROM mysql.user WHERE user='root';

如果 plugin 还是auth_socket,说明修改没成功。重新执行:

ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '你的新密码'; FLUSH PRIVILEGES;

改完后再试。这里有个很关键的经验:如果你使用的 MySQL 客户端是 8.0 之前的老版本,连接时会报Authentication plugin 'caching_sha2_password' cannot be loaded,这是客户端不兼容导致的,处理办法是把用户改回mysql_native_password。但如前所说,生产环境还是建议升级客户端。

如果连sudo mysql也进不去了,那多半是 MySQL 服务异常或者权限文件损坏。这时候的恢复手段是停机后以--skip-grant-tables方式启动:

sudo systemctl stop mysql sudo mysqld --skip-grant-tables &

跳过授权表启动后,MySQL 不会校验用户名密码,你可以直接登录并修复用户信息。修复完一定要重启服务并撤销 skip 参数,否则等于裸奔。

4.2 连接失败时提示 "Can't connect to local MySQL server through socket"

这个错误信息很经典。字面意思是"通过 socket 连接本地 MySQL 失败",其实背后原因有好几种可能。

检查 MySQL 进程是否存在:

sudo systemctl status mysql

如果服务是死掉的,先看日志排查启动失败原因:

sudo tail -100 /var/log/mysql/error.log

日志里最常见的一类是权限问题。比如/var/lib/mysql目录的属主不对,MySQL 进程没有写权限,启动日志就会报错。解决方式:

sudo chown -R mysql:mysql /var/lib/mysql sudo chown -R mysql:mysql /var/run/mysqld

如果服务是活的但客户端仍然报 socket 错误,检查 socket 文件路径是否一致。Ubuntu 上默认 socket 文件在/var/run/mysqld/mysqld.sock,但如果你手动改了配置文件,而客户端连的还是旧路径,自然连不上。查看实际 socket 路径:

sudo mysql -e "SHOW VARIABLES LIKE 'socket';"

如果发现不一致,可以让客户端指定 socket 路径连接:

mysql -u root -p -S /var/run/mysqld/mysqld.sock

或者干脆就用 TCP 方式连接:

mysql -u root -p -h 127.0.0.1 -P 3306

4.3 AppArmor 拦截导致数据目录或日志问题

Ubuntu 默认开启了 AppArmor,给 MySQL 设置了一套访问控制策略。如果你把数据目录、日志文件放在非默认路径,MySQL 操作这些文件时会被 AppArmor 拦截,启动和运行都会报权限错误。

排查方法很直接,看系统审计日志:

sudo grep "apparmor" /var/log/syslog

如果看到类似apparmor="DENIED"的条目,基本就是 AppArmor 限制了。

解决办法有两种。一是把 MySQL 配置路径纳入 AppArmor 允许范围,编辑/etc/apparmor.d/usr.sbin.mysqld,加入你的数据目录路径,然后重新加载 AppArmor:

sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld

二是干脆关掉对 MySQL 的保护(仅限测试环境),禁用相关 profile:

sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld

生产环境不建议关 AppArmor,但如果你确定自己的路径配置没问题,可以在 AppArmor 配置里显式放通。

4.4 升级或迁移过程中出现的导入报错

从 MySQL 5.7 迁移到 8.0,或者从别的机器导出 SQL 再灌入新库,经常会碰见语法兼容性问题。MySQL 8.0 中有一些用法被标记为废弃,导入旧备份时可能出现报错,比如:

  • 5.7 版本的查询缓存相关配置在 8.0 已移除
  • 系统表结构改变,直接复制数据文件(datadir)跨版本使用非常危险
  • 分区表语法变得严格,旧的HASH分区写法可能有问题

最稳妥的迁移方式是逻辑备份 + 导入,推荐使用官方工具mysqldump:

mysqldump -u root -p --single-transaction --routines --triggers --all-databases > backup.sql

在新库上导入:

mysql -u root -p < backup.sql

如果数据量很大,可以考虑使用官方提供的MySQL Shelldump 工具(util.dumpInstance / util.dumpSchemas),它支持并行导出导入,速度比 mysqldump 快很多。

这里必提一个坑:如果导入过程中报最前面的SET语句错误,多半是字符集问题。可以试着加参数重新导出:

mysqldump -u root -p --default-character-set=utf8mb4 --single-transaction --routines --triggers --all-databases > backup.sql

导入时同样指定字符集,可以避免一堆乱码和报错。

4.5 磁盘满与文件句柄限制

还有一个生产环境常见但容易被忽略的问题——磁盘满了。MySQL 数据目录所在的挂载点如果满了,会报Table full或直接拒绝写入。看磁盘占有率:

df -h

常见的大头集中在 binlog、慢查询日志和临时文件。清理 binlog(注意是按需清理)可以这样操作:

PURGE BINARY LOGS BEFORE NOW() - INTERVAL 2 DAY;

同样要注意的是文件句柄限制。有些系统默认对进程能打开的文件数限制很低,在高并发下,MySQL 会报Too many open files。检查当前限制:

ulimit -n

可以临时调高,也可以永久写入/etc/security/limits.conf:

mysql soft nofile 65535 mysql hard nofile 65535

改完后要重登或者重启相关服务生效。这类问题虽然不常出现在小规模部署中,但一旦发生就是比较严重的故障,提前预防很有必要。


从我实际踩过的坑来看,安装 MySQL 8 本身不算难,真正花时间的是安装后的一系列配置和排错。不同的 Ubuntu 版本、不同的内核安全策略、不同的历史残留,都会让"标准安装"变得不那么标准。我的建议是:装之前把环境看清楚,装完立刻把安全加固和日志策略配好,哪怕开发环境也别裸奔。后面你真正把数据放进去、把业务跑起来的时候,系统稳定性和可恢复性才是最关键的东西。

最后再分享一个小技巧:如果你需要在多台机器上重复安装 MySQL 8,别一台台手动敲命令,用debconf-set-selections预置安装选项或者写一个 shell 脚本把仓库配置、安装、初始加固全串起来。我自己就维护过一套内部脚本,在 Ubuntu 20.04/22.04 上批量装完就是一台可以直接接业务的 MySQL 服务器。把这个自动化思路早点落地,后期能省下大把时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询