☰
Ubuntu下MySQL压缩包安装全流程:从下载到systemd托管
2026/10/7 3:52:00 网站建设 项目流程

如果你去问身边搞Linux运维或者后端的同事,新装MySQL一般怎么装,十个里面九个会甩给你一句apt install mysql-server,剩下一个可能建议你直接上Docker。这两种方式在日常环境里都没毛病,但最近我在几台Ubuntu服务器上反复实操下来,发现不少场景下压缩包二进制安装才是更省心的路子——尤其是你想锁定MySQL的小版本、希望数据目录和二进制目录彻底分离、或者一台机器上要维护多个独立实例的时候。这篇东西就是围绕“Ubuntu下MySQL压缩包安装”写的完整操作记录,从下载校验、目录规划、初始化数据目录,到systemd接管、常见坑排查,都按我实际跑过的流程展开。如果你正好要在一台干净的Ubuntu上手动部署新版MySQL,又不想被包管理器的小版本绑定,那这篇可以直接拿来当操作手册。

1. 为什么我放着apt和Docker不用,偏要选压缩包手工部署

先说结论:压缩包安装不是最省事的,但它给了你最大的控制权。

1.1 包管理器、Docker、源码编译与二进制包各自的取舍

我先把常见方案拉出来遛一遛,对比一下它们的差异,你就明白为什么我会在这种场景下选压缩包。

安装方式优点缺点适合场景
apt安装mysql-server一条命令完成,依赖自动处理,配置路径统一版本由Ubuntu仓库决定,小版本滞后,升级时可能被换掉配置追求省事、不急着重现线上版本的环境
Docker容器与宿主机隔离,拉起快,多版本切换方便数据卷、端口、网络和权限需要额外设计,调试时多一层微服务开发、需要快速启停的场景
官方源码编译编译参数可定制,能装到任意前缀路径编译耗时长,依赖复杂,升级维护成本高特殊CPU架构、定制插件、需要极简构建的场合
官方二进制压缩包指定小版本,部署路径可控,多实例友好,卸载干净手动处理依赖和初始化流程,有一定门槛生产环境锁版本、单机多实例、数据与程序分离部署

我这次机子上跑的是Ubuntu 24.04 LTS,apt仓库里MySQL还停在8.0的某个小版本,而项目方明确要求使用新推出的9.x系列(创新版,Innovation Release)。用官方二进制包能直接指定到对应版本,数据目录可以放在独立的数据盘上,万一以后要换版本,删掉解压目录再解压一个新的就行,不带一点杂质。这就是压缩包方案最大的吸引力:它的“主目录”和“数据目录”是两个概念,完全掌握在你手里。

1.2 什么情况下我会劝你别用压缩包

当然,压缩包安装也不是万能的。如果你的需求是“随便跑个库让我开发用”,那apt一条命令明显更划算。压缩包方式要自己处理依赖,一台新机器上的libaio、libncurses这类基础库很可能没装,初始化数据目录也得自己跑,出问题的时候排查链路更长。如果机器网络不好、无法从官方镜像站下载大文件,也得优先考虑apt源。

还有一点要提前说清楚:MySQL官方从8.0之后,版本发布策略分成了长期支持版(LTS)和创新版。创新版的功能更新更快,但维护窗口也短,适合对新特性有强需求、且团队有能力快速跟进的场景。你要是拿它做核心生产库,得先掂量好自己的版本升级节奏。这就是我从标题里看到“MySQL9”第一反应要提醒的事。

2. 环境准备:下载前的功课少做一步都会卡住

这一步看着基础,实际上八十%的安装失败都出在准备工作没做全。我按自己的执行顺序整理了一份清单,你照着走就行。

2.1 检查glibc版本和基础依赖

MySQL官方二进制包对glibc版本有要求。Ubuntu不同发行版的glibc版本不一样,在终端跑一下:

ldd --version | head -n1

我这边的输出是ldd (Ubuntu GLIBC 2.39-0ubuntu8.3) 2.39,满足官方预编译包的需求。如果你手头是比较老的Ubuntu版本,比如18.04,glibc还在2.27附近,那就得先评估一下能不能跑新版MySQL,或者干脆选择与此匹配的旧版本。

然后检查两个关键依赖库,这两个缺了会导致mysqld启动时直接报找不到共享库:

dpkg -l | grep libaio dpkg -l | grep libncurses

如果没有,先补齐:

sudo apt update sudo apt install libaio1 libncurses5 libncursesw5 -y

不少教程会把libncurses5省略掉,等到初始化阶段日志里开始报错才回头补装。我实际跑的时候,Ubuntu 24.04的软件源里已经没有libncurses5这个包名了,用的替代方案是libncurses5对应的兼容包。如果你也碰到装不上的情况,就装libncurses-dev和libaio-dev,mysqld的运行需要的是libaio.so.1和libncurses.so.5这类运行库,装dev版本往往也能把运行库带进来。

2.2 下载、校验与目录规划

从MySQL官网下载二进制包时,认准文件名里的linux-glibc2.x-x86_64.tar.xz格式。把包下载到/usr/local/src下,同时下载对应的.sha256校验文件:

sudo mkdir -p /usr/local/src cd /usr/local/src sudo wget https://dev.mysql.com/get/Downloads/MySQL-9.x/mysql-9.x.x-linux-glibc2.28-x86_64.tar.xz sudo wget https://dev.mysql.com/get/Downloads/MySQL-9.x/mysql-9.x.x-linux-glibc2.28-x86_64.tar.xz.sha256

下载完成后先校验完整性再解压。这一步很多人会跳过,但我劝你别省:

sudo sha256sum -c mysql-9.x.x-linux-glibc2.28-x86_64.tar.xz.sha256

看到OK再继续,校验不过就删掉重下,别赌运气。接下来解压到/usr/local,并建立一个不带版本号的软链接,方便后续升级不用改一堆路径:

cd /usr/local sudo tar xvf /usr/local/src/mysql-9.x.x-linux-glibc2.28-x86_64.tar.xz sudo ln -s mysql-9.x.x-linux-glibc2.28-x86_64 mysql

我习惯把程序放在/usr/local/mysql,然后单独建一个数据目录:

sudo mkdir -p /data/mysql

如果你把数据也放在/usr/local/mysql/data,看似省事,但以后要拆数据盘、做迁移,路径全乱掉。规划目录时,至少要想清楚以下四个路径的区别:

  • basedir:MySQL程序所在的根目录,也就是解压出来的目录。
  • datadir:数据文件存放目录,可以放在独立挂载点。
  • socket:本地连接用的Unix socket文件路径,默认在/tmp下,但如果/tmp被清理策略影响,最好放到datadir或/var/run/mysqld下。
  • pid-file:mysqld进程ID存放位置,systemd接管时也需要知道这个路径。

2.3 创建专用系统用户和组

无论你用哪种方式安装,我都不建议直接用root跑mysqld。MySQL官方虽然允许用root初始化,但生产环境里这会带来权限管理混乱和安全隐患。创建专用用户:

sudo groupadd mysql sudo useradd -r -g mysql -s /bin/false mysql

注意-s /bin/false,这个用户不需要登录shell,只需要能运行mysqld进程、读写数据目录。把数据目录权限交给它:

sudo chown -R mysql:mysql /data/mysql sudo chmod -R 750 /data/mysql

权限这里有个比较容易踩的细节:如果数据目录是挂在独立数据盘上的,chown前先确认挂载点没有noexec之类的挂载选项,否则后面初始化binlog、执行工具都可能被拒绝。

3. 初始化数据目录:整个过程中坑最密的一环

这部分是我觉得压缩包安装和apt安装拉开差距最大的地方。apt装完会自动初始化数据库,压缩包装完全靠你自己跑命令,而这条命令行里的参数顺序、目录权限、依赖缺失,任何一个不对都会让你卡在这里干瞪眼。

3.1 写一份最简配置文件再动手

官方二进制包自带一份/usr/local/mysql/my.cnf示例,但我不建议直接复制。在初始化之前,先手工写好一份精简配置,放到/etc/my.cnf:

[mysqld] basedir=/usr/local/mysql datadir=/data/mysql socket=/data/mysql/mysql.sock pid-file=/data/mysql/mysqld.pid log-error=/data/mysql/error.log user=mysql [client] socket=/data/mysql/mysql.sock

这里我把socket放在数据目录下,主要是考虑到/tmp目录在某些系统上会被定期清理,MySQL跑着跑着socket没了,客户端会连不上去,排查起来很迷惑。log-error必须在初始化前就指定好,因为初始化过程中的绝大多数报错都会写进这个日志文件,没有它你根本无从下手。

3.2 执行--initialize初始化并解读日志

配置写好后,切换到mysql用户来初始化:

cd /usr/local/mysql sudo -u mysql bin/mysqld --defaults-file=/etc/my.cnf --initialize --basedir=/usr/local/mysql --datadir=/data/mysql

这一步执行时间长则几十秒,短则几秒。执行完没有输出是正常的,真正的输出都写进了/data/mysql/error.log。打开日志,你会看到类似这样的一行:

[Note] [MY-010454] A temporary password is generated for root@localhost: xxxxxxxx

拿到这个临时密码后,先别急着删日志,等后面第一次登录后再处理。还有一种情况是日志里没有生成临时密码,而是直接初始化失败。最典型的有两类报错。

第一类报错是:

mysqld: error while loading shared libraries: libaio.so.1

这就是我之前提醒过的基础依赖缺失,回到第2.1节补装libaio1,然后重新跑初始化命令。

第二类报错是[ERROR] Could not create directory /data/mysql或者类似权限不足之类的信息,这大概率是/data/mysql的所有者不对,先确认:

ls -ld /data/mysql

如果不是mysql mysql,重新执行chown再初始化。

3.3 初始化参数要分清--initialize和--initialize-insecure

这里有个细节,两次初始化命令的结果差别很大:

  • --initialize会生成一个随机的临时root密码,适合生产环境。
  • --initialize-insecure不会生成密码,root用户本地socket连接时免密登录,适合第一次初始化玩单机测试。

第一次跑我强烈建议用--initialize,让你养成拿到临时密码、然后立刻改密码的习惯。如果你自己大意把数据目录初始化了一部分但没成功,想重置的时候,把/data/mysql清空再重来即可,但清空之前千万确认里面没有别的不该删的东西:

sudo rm -rf /data/mysql/*

清理完再跑一次初始化命令。这条路我走过不止一遍,大多数情况下很快就能过。

4. 启动mysqld并完成安全设置

初始化成功只是第一步,把服务拉起来、把密码改掉、把远程连接权限收紧,这才是真正能用的状态。

4.1 启动时的先后顺序很影响体验

初次启动,我建议先手动前台方式跑一遍,避免直接上systemctl后出问题看不到日志。

sudo -u mysql /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf

如果配置文件没问题,你会看到mysqld在前台运行,终端不再返回,说明进程已经起来了。这时打开另一个终端,用mysqladmin ping检测:

/usr/local/mysql/bin/mysqladmin --socket=/data/mysql/mysql.sock -u root ping

能返回mysqld is alive就说明进程状态正常。如果ping不通,优先看/data/mysql/error.log,里面有明确的原因。最常见的原因是socket路径不一致——配置文件里写的是/data/mysql/mysql.sock,而你命令里没带socket参数,默认去/tmp找,自然连不上。

确认没问题后,用Ctrl+C终止前台进程,再改为后台方式启动:

sudo -u mysql /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf &

或者更规范的做法,用官方自带的mysqld_safe脚本,它能帮你监控进程异常退出:

/usr/local/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &

这里要注意,mysqld_safe如果以root身份执行,会尝试切换到user=mysql去运行mysqld,但如果配置文件中没有明确user=mysql,它反而会以root启动mysqld,日志里会给你警告。所以配置文件里的user=mysql不要省略。

4.2 第一次登录和修改密码

用初始化时生成的临时密码登录:

/usr/local/mysql/bin/mysql --socket=/data/mysql/mysql.sock -u root -p

输入临时密码后,你就进到了MySQL交互终端。立刻执行:

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

有些版本里ALTER USER之后可能还需要设置密码的过期策略,你可以在MySQL终端里确认一下:

SELECT user, host, password_expired FROM mysql.user;

如果某个账户的password_expired是Y,那还得补一步激活动作。这个过程跑完后,顺手把临时密码从error.log里清掉,避免日志被人翻到:

sudo truncate -s 0 /data/mysql/error.log

4.3 安全收尾:执行官方安全脚本和创建远程账号

MySQL安装包里自带了一个安全脚本mysql_secure_installation,它会一步一步引导你删除匿名用户、删除测试数据库、禁用root远程登录。执行:

/usr/local/mysql/bin/mysql_secure_installation

按照提示一路走:设置密码验证强度、移除匿名用户、禁止root远程登录、移除test库、重载权限表。这套流程务必完整走一遍,不要跳过。

如果你确实需要远程访问,正确做法不是放开root的远程权限,而是创建一个专用的远程账号:

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

然后确认my.cnf中监听的地址:

bind_address=0.0.0.0

如果只允许内网访问,就改成具体的内网IP,别图省事全开0.0.0.0。这一步在云服务器上尤其重要,有很多扫描工具会盯默认3306端口。

5. 让MySQL开机自启:用systemd接管实例

每次手动启动实例显然不现实,生产环境里要把mysqld注册成systemd服务,让它在开机时自动拉起来、崩溃时自动重启、日志归journal管理。

5.1 编写service文件时容易被忽略的参数

在/etc/systemd/system/mysql.service里写一个服务文件:

[Unit] Description=MySQL Server After=network.target [Service] Type=simple User=mysql Group=mysql ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure TimeoutSec=300 PrivateTmp=false [Install] WantedBy=multi-user.target

几个要点逐个说:

  • Type=simple意味着systemd认为ExecStart启动的进程就是主进程。mysqld直接跑起来就是前台进程,用这个没问题。如果你用mysqld_safe,那它是个外层守护进程,Type要改forking或者干脆不用mysqld_safe。
  • User=mysql和配置文件里的user=mysql保持一致。如果你这里写了systemd用mysql用户,而mysqld配置文件里没写,MySQL有时候会警告你用root权限运行。
  • PrivateTmp=false很关键。systemd的PrivateTmp=true会给服务创建独立的临时目录,导致MySQL内部使用的临时文件路径被重定向,某些场景下会出现找不到Socket或者临时目录权限错误。我在新版本上踩过这个坑,默认的PrivateTmp行为变了以后,socket明明生成了却连不上,折腾很久才定位到。

写完后重新加载systemd配置并启动:

sudo systemctl daemon-reload sudo systemctl enable mysql sudo systemctl start mysql sudo systemctl status mysql

看到active (running),再执行一次:

systemctl is-enabled mysql

输出enabled,说明开机自启已经生效。

5.2 多实例场景下的扩展思路

压缩包安装一个很顺手的场景是单机跑多个MySQL实例。只需要为每个实例准备一套目录、一份配置文件和一个端口,再注册一个独立的systemd服务。

比如第二个实例,数据目录放到/data/mysql3307,端口用3307,socket命名mysql3307.sock。写第二份/etc/my3307.cnf:

[mysqld] basedir=/usr/local/mysql datadir=/data/mysql3307 port=3307 socket=/data/mysql3307/mysql3307.sock pid-file=/data/mysql3307/mysqld3307.pid log-error=/data/mysql3307/error.log user=mysql

再复制一个mysql3307.service,把ExecStart改成--defaults-file=/etc/my3307.cnf。同一个二进制目录跑两个独立实例,数据完全隔离,互不干扰。这是apt方式不太好做到的灵活性。

6. 实战中反复遇到的坑和排查思路

最后这部分,我把近期部署和帮人排查时遇到的典型问题整理成完整的排查链路。这些都是不看日志就猜不出来的问题,遇到时可别急着卸载重装。

6.1 mysqld进程起来了,但客户端连不上

现象:系统里有mysqld进程,ps aux | grep mysqld看得到,systemctl status也显示active,但mysql -uroot -p一执行就报错Can't connect to local MySQL server through socket '/tmp/mysql.sock'。

我建议按下面这个顺序排查:

  1. 先看客户端参数里用的socket路径,是不是跟我一样用的是/tmp/mysql.sock。
  2. 看MySQL实际生成的socket在哪:ls -l /data/mysql/*.sock。
  3. 核对/etc/my.cnf的[client]段落和[mysqld]段落是不是一致。
  4. 用--socket参数显式指定再连一次:mysql --socket=/data/mysql/mysql.sock -u root -p。

如果socket路径刚才还没生成,那就要重点看error.log里有没有[ERROR] Can't start server: Bind on unix socket address这种报错。如果socket端口/data/mysql目录的写权限有问题,MySQL启动时会无声无息地失败,日志却只写一半。这种时候回到第3.1节,确认目录权限和user设置。

6.2 开机自启后服务起不来,手动又能起来

这个现象很诡秘:手动systemctl start mysql正常,reboot之后怎么都不亮。排查时可以执行:

systemctl status mysql journalctl -u mysql -n 50

journal里如果有Failed to open file '/data/mysql/mysql.pid'这类提示,十有八九是systemd在启动时机上数据盘还没挂载好。你可以在service文件的[Unit]段加一句:

After=network.target local-fs.target Requires=local-fs.target

加重依赖顺序后,试试systemctl daemon-reload再重启。这个问题在你把datadir放到独立数据盘、且不在/etc/fstab里设置挂载顺序时会特别常见,压缩包部署的目录习惯会放大这个坑。

6.3 初始化时报mecab字符集错误

如果你安装的是带全文检索支持的新版MySQL,初始化时可能出现:

[ERROR] [MY-010244] Missing data for mecab charset

这不是致命问题,多半是二进制包解压不完整,或者你只拷贝了bin目录而没拷贝share目录。确认解压时有没有中断,/usr/local/mysql/share目录是否存在,重新完整解压一遍即可。

6.4 版本升级时怎么保住数据

压缩包升级的优势在这里体现得最明显。你不需要卸载旧版,只要在停机后把旧数据目录做个物理冷备,然后解压新版二进制包,调整软链接,再以同一份配置启动:

sudo mv /usr/local/mysql /usr/local/mysql.bak sudo tar xvf mysql-new-version.tar.xz -C /usr/local sudo ln -s mysql-new-version /usr/local/mysql sudo systemctl start mysql

启动前先跑一次:

/usr/local/mysql/bin/mysqld --verbose --help | grep datadir

确认新的二进制包和配置里的datadir对得上,避免升级完发现数据目录读错了。如果小版本跨度较大,官方建议先用mysql_upgrade工具升级系统表,新版本有些会自动在启动时升级,但手工跑一遍更稳妥。

写在最后的操作体会

我实际操作下来的最大感受是:压缩包安装把“装软件”变成了“部署服务”,中间多出来的每一步都是了解MySQL运行机制的好机会。apt帮你隐藏的那些细节——socket文件、pid文件、数据目录权限、依赖库——在压缩包方案里全部暴露出来,一旦你亲手配好一套,再回头看那些报错和日志,理解完全是两个层面。如果你打算在Ubuntu上长期维护MySQL,我非常建议拿一台测试机完整走一遍这个流程,遇到问题别急着问搜索引擎,先养成看error.log和journalctl的习惯,绝大多数问题都能在日志里找到答案。多实例、目录规划、systemd托管这三板斧熟练之后,你会发现比包管理器方案踏实得多。

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

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

立即咨询