Ubuntu下MySQL压缩包安装全流程:从下载到systemd托管

发布时间:2026/10/7 3:52:19
Ubuntu下MySQL压缩包安装全流程:从下载到systemd托管
如果你去问身边搞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 LTSapt仓库里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.04glibc还在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-devmysqld的运行需要的是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看似省事但以后要拆数据盘、做迁移路径全乱掉。规划目录时至少要想清楚以下四个路径的区别basedirMySQL程序所在的根目录也就是解压出来的目录。datadir数据文件存放目录可以放在独立挂载点。socket本地连接用的Unix socket文件路径默认在/tmp下但如果/tmp被清理策略影响最好放到datadir或/var/run/mysqld下。pid-filemysqld进程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 usermysql [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 rootlocalhost: 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找自然连不上。确认没问题后用CtrlC终止前台进程再改为后台方式启动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身份执行会尝试切换到usermysql去运行mysqld但如果配置文件中没有明确usermysql它反而会以root启动mysqld日志里会给你警告。所以配置文件里的usermysql不要省略。4.2 第一次登录和修改密码用初始化时生成的临时密码登录/usr/local/mysql/bin/mysql --socket/data/mysql/mysql.sock -u root -p输入临时密码后你就进到了MySQL交互终端。立刻执行ALTER USER rootlocalhost 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.log4.3 安全收尾执行官方安全脚本和创建远程账号MySQL安装包里自带了一个安全脚本mysql_secure_installation它会一步一步引导你删除匿名用户、删除测试数据库、禁用root远程登录。执行/usr/local/mysql/bin/mysql_secure_installation按照提示一路走设置密码验证强度、移除匿名用户、禁止root远程登录、移除test库、重载权限表。这套流程务必完整走一遍不要跳过。如果你确实需要远程访问正确做法不是放开root的远程权限而是创建一个专用的远程账号CREATE USER app192.168.1.% IDENTIFIED BY 强密码; GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO app192.168.1.%; FLUSH PRIVILEGES;然后确认my.cnf中监听的地址bind_address0.0.0.0如果只允许内网访问就改成具体的内网IP别图省事全开0.0.0.0。这一步在云服务器上尤其重要有很多扫描工具会盯默认3306端口。5. 让MySQL开机自启用systemd接管实例每次手动启动实例显然不现实生产环境里要把mysqld注册成systemd服务让它在开机时自动拉起来、崩溃时自动重启、日志归journal管理。5.1 编写service文件时容易被忽略的参数在/etc/systemd/system/mysql.service里写一个服务文件[Unit] DescriptionMySQL Server Afternetwork.target [Service] Typesimple Usermysql Groupmysql ExecStart/usr/local/mysql/bin/mysqld --defaults-file/etc/my.cnf ExecReload/bin/kill -HUP $MAINPID Restarton-failure TimeoutSec300 PrivateTmpfalse [Install] WantedBymulti-user.target几个要点逐个说Typesimple意味着systemd认为ExecStart启动的进程就是主进程。mysqld直接跑起来就是前台进程用这个没问题。如果你用mysqld_safe那它是个外层守护进程Type要改forking或者干脆不用mysqld_safe。Usermysql和配置文件里的usermysql保持一致。如果你这里写了systemd用mysql用户而mysqld配置文件里没写MySQL有时候会警告你用root权限运行。PrivateTmpfalse很关键。systemd的PrivateTmptrue会给服务创建独立的临时目录导致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端口用3307socket命名mysql3307.sock。写第二份/etc/my3307.cnf[mysqld] basedir/usr/local/mysql datadir/data/mysql3307 port3307 socket/data/mysql3307/mysql3307.sock pid-file/data/mysql3307/mysqld3307.pid log-error/data/mysql3307/error.log usermysql再复制一个mysql3307.service把ExecStart改成--defaults-file/etc/my3307.cnf。同一个二进制目录跑两个独立实例数据完全隔离互不干扰。这是apt方式不太好做到的灵活性。6. 实战中反复遇到的坑和排查思路最后这部分我把近期部署和帮人排查时遇到的典型问题整理成完整的排查链路。这些都是不看日志就猜不出来的问题遇到时可别急着卸载重装。6.1 mysqld进程起来了但客户端连不上现象系统里有mysqld进程ps aux | grep mysqld看得到systemctl status也显示active但mysql -uroot -p一执行就报错Cant connect to local MySQL server through socket /tmp/mysql.sock。我建议按下面这个顺序排查先看客户端参数里用的socket路径是不是跟我一样用的是/tmp/mysql.sock。看MySQL实际生成的socket在哪ls -l /data/mysql/*.sock。核对/etc/my.cnf的[client]段落和[mysqld]段落是不是一致。用--socket参数显式指定再连一次mysql --socket/data/mysql/mysql.sock -u root -p。如果socket路径刚才还没生成那就要重点看error.log里有没有[ERROR] Cant 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 50journal里如果有Failed to open file /data/mysql/mysql.pid这类提示十有八九是systemd在启动时机上数据盘还没挂载好。你可以在service文件的[Unit]段加一句Afternetwork.target local-fs.target Requireslocal-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托管这三板斧熟练之后你会发现比包管理器方案踏实得多。