资讯动态

CentOS 8 下用 Linux 通用二进制包安装 MySQL 8.0.25 完整实战

发布时间:2026/10/20 8:20:45 来源:尧图企业网站定制
1. 为什么选Linux通用二进制包而不是包管理器1.1 两种安装方式的核心差异CentOS 8 上装 MySQL 8.0.25 社区版绕不开一个选择到底是走 dnf/yum 仓库直接装还是下载官方提供的 Linux 通用二进制包手动部署我个人的答案是在生产环境、离线环境和需要精确控制目录结构的场景里二进制包安装远比包管理器可靠。这不是说 yum 不好而是两者的定位完全不同。yum 安装走的是系统仓库或第三方仓库它会自动解析依赖、自动生成 systemd 服务、自动把配置放到 /etc/my.cnf看起来确实省事。但问题恰恰出在“自动”两个字上——你无法精确控制装到哪个目录、无法随意定义数据目录、更无法在一个机器上同时跑两个不同版本的 MySQL 实例。而 Linux 通用二进制包也就是官方 tar.xz 包把一切都交给你自己目录自己定、配置自己写、启动方式自己选自由度完全不同。从版本管理角度看通用二进制包也更干净。MySQL 官方对每个版本都提供独立的 tar 包下载下来解压就是一个完整的 MySQL 目录。想升级就换软链接指向新版本目录想回滚就把软链接指回去整个过程可以控制在分钟级。而 yum 升级是原地覆盖旧版本文件、配置、数据文件混在一起出问题后想干净回退非常麻烦。1.2 二进制包安装的适用场景什么情况下我推荐你放弃 yum、老老实实下载官方 tar 包这里总结几类典型场景内网离线环境很多机房根本没有外网dnf 仓库源要么不可用、要么是内部镜像且版本滞后。这时候把 tar 包下好带进去解压即用完全不依赖网络和仓库状态。多实例部署一台机器上要跑多个 MySQL 实例比如 3306、3307、3308 三个端口分别服务不同业务。yum 安装默认只有一个实例体系想多开得费很大力气去改脚本。二进制包天然支持多目录、多配置文件每个实例一套独立目录互不干扰。版本锁定和精确测试你想在测试环境完整复现生产环境的某一个具体版本比如 8.0.25 这个版本yum 仓库不一定有二进制包却可以精确到小版本。对于需要做版本兼容性验证的团队这是刚需。数据目录独立于软件目录二进制包安装可以把 bin、lib、share 这类程序文件放在系统盘把 datadir 单独挂到大容量数据盘这种灵活布局在 yum 安装中几乎做不到。其实还要提一个隐性的好处二进制包是在官方环境中编译好的依赖的 glibc 版本明确标明比如 8.0.25 对应的包要求 glibc 2.12 以上。CentOS 8 的 glibc 版本是 2.28完全兼容性能上也和源码编译的版本没有明显差异。你不用在服务器上装编译器、不用等待漫长的编译过程解压之后稍微配置就能跑起来。提示如果你的业务没有特殊要求而且服务器能正常访问外网 yum 源用官方 yum 仓库安装没什么不对。但如果你遇到的是上面任意一种场景这篇二进制包安装的流程就是你的刚需。2. 安装前准备环境与依赖检查2.1 版本匹配与系统环境确认这次安装的目标版本是 MySQL 社区版 Server 8.0.25它对应的官方 Linux 通用二进制包名称类似mysql-8.0.25-linux-glibc2.12-x86_64.tar.xz。注意这里的glibc2.12是最低要求并不代表必须跑在 CentOS 6 上。CentOS 8 自带 glibc 2.28向下兼容 2.12 编译的程序所以直接用就好。上机第一步先确认系统架构和 glibc 版本uname -m ldd --version | head -n 1正常情况下你会看到x86_64和ldd (GNU libc) 2.28之类的输出。如果你的机器是 aarch64ARM 架构就下载对应的 aarch64 版本包操作流程完全一样。这一步看似多余但我亲眼见过有人把 x86_64 的包传到 ARM 机器上解压然后初始化时报Exec format error浪费了大半天时间。还需要确认几个基础工具的可用性tar、xz、useradd、chown。这些在最小化安装的 CentOS 8 里基本都有如果提示找不到先执行dnf install -y tar xz which2.2 依赖库准备与常见坑二进制包虽说是“免编译”但 MySQL 服务本身依赖一些动态链接库。最常见的坑是libaio这个库在 CentOS 8 最小化安装时默认不装。MySQL 的 InnoDB 引擎在启动时会通过 libaio 发起异步 IO没有它初始化会直接失败。装依赖库dnf install -y libaio ncurses-compat-libs perl numactl-libs逐一说下为什么需要这些libaioInnoDB 异步 IO 的底层支持缺它初始化时报error while loading shared libraries: libaio.so.1。ncurses-compat-libsMySQL 8.0.25 的 mysql_secure_installation 等客户端工具在终端交互时会用到旧版 curses 兼容接口CentOS 8 默认只带新版不装这个可能出现终端显示异常。perlMySQL 8.0.25 里的mysql_ssl_rsa_setup和部分脚本依赖 perl 环境虽然我们不一定会用到但装上免得后续折腾。numactl-libsMySQL 8.0 引入了 NUMA 感知特性不同内存架构的机器上表现不同装这个库可以避免某些硬件环境下 mysqld 启动时出现 NUMA 相关的内存分配错误。装完之后可以用ldconfig -p | grep验证关键库是否存在ldconfig -p | grep libaio ldconfig -p | grep libncurses依赖这一关准备到位后面初始化就少很多幺蛾子。这一步我强烈建议不要跳过宁可多花两分钟检查也不要等到mysqld --initialize报错了再回来补。2.3 目录规划与系统用户创建二进制包安装最大的自由就是目录规划。我的习惯是程序目录放/usr/local数据目录放在独立数据盘。假设数据盘挂载点是/data整体规划如下路径用途/usr/local/mysql软链接指向当前使用的 MySQL 版本目录/usr/local/mysql-8.0.25-linux-glibc2.12-x86_64实际程序目录/data/mysql_3306/datadir数据库数据文件目录/data/mysql_3306/log错误日志、慢查询日志、binlog 目录/data/mysql_3306/tmp临时文件目录先创建专用系统用户MySQL 不允许用 root 身份直接运行 mysqld需要独立账号groupadd mysql useradd -r -g mysql -s /sbin/nologin mysql-r表示创建系统账号-s /sbin/nologin禁止该账号直接登录 shell。这一步是安全底线如果允许 MySQL 账号登录系统一旦数据库被拖库攻击者可能通过低权限账号做更多操作。目录上把要放数据的位置先建好mkdir -p /data/mysql_3306/datadir mkdir -p /data/mysql_3306/log mkdir -p /data/mysql_3306/tmp chown -R mysql:mysql /data/mysql_33063. 解压部署与基础配置3.1 下载与解压从 MySQL 官方下载页面找到 8.0.25 版本的 Linux Generic tarball或者在服务器上直接用 wget 拉取。官方下载域名在国内访问速度有时不稳定建议下载完成后比对一下 MD5 校验值wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.25-linux-glibc2.12-x86_64.tar.xz md5sum mysql-8.0.25-linux-glibc2.12-x86_64.tar.xz解压并创建软链接tar -xf mysql-8.0.25-linux-glibc2.12-x86_64.tar.xz -C /usr/local/ ln -s /usr/local/mysql-8.0.25-linux-glibc2.12-x86_64 /usr/local/mysql chown -R mysql:mysql /usr/local/mysql /usr/local/mysql-8.0.25-linux-glibc2.12-x86_64这里必须解释一下为什么用软链接而不是直接重命名目录。软链接的好处是版本升级时极其顺滑新版本目录解压到 /usr/local校验无误后把mysql这个链接替换成新版本数据目录不动程序层面就是一个版本切换。万一新版本有问题一条ln -sfn就能秒回滚。这招在线上环境救过我一次印象极其深刻。解除系统自带的 mariadb 或旧 mysql 客户端软件的干扰。CentOS 8 默认带了 mariadb-libs它和 MySQL 客户端工具存在文件冲突rpm -qa | grep mariadb dnf remove -y mariadb-libs注意这只会移除 MariaDB 的库文件不影响已有的数据。如果有正在跑的 MariaDB 服务那要先迁移数据这不是本文范围但务必清楚这一点。3.2 配置文件 my.cnf 编写8.0.25 的初始化参数比 5.7 规范了很多配置文件我建议直接放在/etc/my.cnf并显式指定所有关键路径。这样最直观迁移到任何机器都能快速理解这套实例的结构。这份配置是我基于生产环境验证过的模板你可以直接参考[mysqld] # 基础路径 basedir/usr/local/mysql datadir/data/mysql_3306/datadir socket/tmp/mysql_3306.sock pid-file/data/mysql_3306/log/mysql_3306.pid log-error/data/mysql_3306/log/error.log tmpdir/data/mysql_3306/tmp # 连接与端口 port3306 mysqlx-port33060 bind-address0.0.0.0 # 字符集 character-set-serverutf8mb4 collation-serverutf8mb4_0900_ai_ci # InnoDB 参数 innodb_buffer_pool_size1G innodb_log_file_size256M innodb_flush_log_at_trx_commit1 innodb_file_per_table1 # 连接数与超时 max_connections500 wait_timeout600 interactive_timeout600 [client] port3306 socket/tmp/mysql_3306.sock default-character-setutf8mb4 [mysql] default-character-setutf8mb4几个容易踩坑的点必须单独拎出来讲。第一socket路径不要放在数据目录下。我看到很多教程把 socket 写到 datadir 里一旦数据目录权限或磁盘出问题客户端连不上、服务端也起不来排查起来非常被动。放 /tmp 下是通用做法注意多实例时 socket 文件名要区分端口号比如mysql_3306.sock和mysql_3307.sock。第二innodb_buffer_pool_size的值要结合机器内存来定。通用准则是设为物理内存的 60% 到 70%但前提是这台机器只跑 MySQL。如果是混部署比如还跑着 Nginx 和 PHP-FPM建议降到 40% 左右。8.0 版本里这个参数可以在线调整但初始值设置合理能少走很多弯路。第三character-set-server和collation-server在 8.0 里的默认值就是 utf8mb4但显式写出来更保险。这里有个细节8.0 的默认排序规则是utf8mb4_0900_ai_ci如果你的业务代码里有针对旧版排序规则的硬编码需要提前看清楚。3.3 首次初始化数据库实例初始化是二进制包安装中最核心、也最容易出问题的一步。MySQL 8.0.25 使用mysqld --initialize完成数据目录初始化执行时必须指定相关路径cd /usr/local/mysql bin/mysqld --defaults-file/etc/my.cnf --initialize --usermysql这里两个参数需要深入理解--defaults-file指定配置文件的绝对路径。注意 mysqld 对默认配置文件的读取顺序是/etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf如果你手动指定了配置文件会跳过其余位置的配置。多实例部署时每个实例必须有独立的--defaults-file否则后面的实例会把第一个实例的配置捡起来互相干扰。--initialize表示执行“初始化安装”。它会创建系统表、InnoDB 系统表空间、数据字典并会为 root 用户生成一个随机临时密码这个密码会写到错误日志文件里。还有一个--initialize-insecure参数初始化后 root 账号无密码只建议在测试环境用。初始化过程一般持续一到两分钟期间没有任何输出log-error 会记录全过程执行完返回 0 就代表成功。初始化完成后立刻去查看临时密码grep temporary password /data/mysql_3306/log/error.log会看到类似[Note] A temporary password is generated for rootlocalhost: xxxxxxxx这样的记录。这个密码一定要保存好只能用一次第一次登录后就必须修改。如果初始化时报错了别急着反复执行——先看错误日志这个文件的信息量远比你瞎猜要准确得多。注意初始化成功后不要再用 root 权限去把 datadir 里的文件 chown 给 mysql 用户之外其他账号也不要手动改动 datadir 里生成的文件结构。系统表和数据字典的权限关系在初始化那一刻就固定了。4. 启动服务与连通性验证4.1 标准启动方式与 systemd 接入初始化完成后最简单直接的启动方式是使用 MySQL 自带的mysql.server脚本/usr/local/mysql/support-files/mysql.server start这个脚本本质上是封装了mysqld_safe的启动逻辑会自动读取 basedir 下的配置并拉起 mysqld 进程。但直接用这个脚本有个问题它不会随系统开机自启每次重启机器都要手动执行一次。既然 CentOS 8 用的 systemd那就配置一个规范的 systemd unit 文件不仅开机自启进程异常退出还能自动拉起。创建/etc/systemd/system/mysqld.service[Unit] DescriptionMySQL Server 8.0.25 Afternetwork.target [Service] Typesimple Usermysql Groupmysql ExecStart/usr/local/mysql/bin/mysqld --defaults-file/etc/my.cnf LimitNOFILE65535 Restarton-failure RestartSec5s TimeoutSec300 [Install] WantedBymulti-user.target几个参数说明Typesimple表示 ExecStart 启动的就是主进程mysqld 本身是前台运行模式不是 daemon。Usermysql和Groupmysql保证 mysqld 以专用账号运行但要注意 mysqld 内部还会检查是否以 root 身份启动并自行切换这里的配置是为了让 systemd 层就锁定运行身份。LimitNOFILE65535调大文件描述符上限。MySQL 在高并发下需要大量文件句柄systemd 默认限制很可能不够。这个值不设置好连接数上到一两千的时候会莫名出现Too many open files。Restarton-failure让 systemd 在 mysqld 非正常退出时自动拉起业务高峰期少一分人工介入的风险。启动并设置开机自启systemctl daemon-reload systemctl start mysqld systemctl enable mysqld systemctl status mysqld这里有个非常容易犯的错直接systemctl start mysql。因为系统里可能曾经装过其他 MySQL 相关的服务文件导致服务名冲突或者找不到。我的建议是统一用mysqld作为服务名在启动前先systemctl status mysqld看一下有没有服务冲突。4.2 修改密码与基本安全加固服务起来之后用命令行客户端连进去改密码。用之前保存的临时密码/usr/local/mysql/bin/mysql -uroot -p -S /tmp/mysql_3306.sock输入临时密码进入后第一件事就是改 root 密码。MySQL 8.0 的密码修改语法和 5.7 有区别不要再用SET PASSWORD PASSWORD(xxx)这种老写法ALTER USER rootlocalhost IDENTIFIED BY YourStrongPassword2025; FLUSH PRIVILEGES;注意 MySQL 8.0.25 默认开启了validate_password组件。它要求密码至少 8 位并且包含大小写字母、数字、特殊字符中的至少三类。如果你设置的密码过于简单会出现ERROR 1819 (HY000): Your password does not satisfy the current policy requirements。这是安全组件在工作不建议直接禁用它而是应该让业务账号的密码符合规范。root 账号只用于本地管理业务账号单独创建。8.0 里创建一个应用账号并授权的方式CREATE USER app_user% IDENTIFIED BY AppPass2025; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX ON app_db.* TO app_user%; FLUSH PRIVILEGES;这里有两个细节特别值得提。第一是%号代表允许任意主机登录如果业务服务器 IP 固定强烈建议把%换成具体的 IP比如192.168.1.10这样可以极大减少账号被爆破的可能性。第二是 MySQL 8.0 默认的授权粒度更细致建用户和授权是分开的语句习惯 5.7 里一条GRANT ALL ON db.* TO userhost IDENTIFIED BY pass写法的朋友要改改思维了。关于mysql_secure_installation这个官方安全脚本8.0 里它默认仍然存在但它需要交互式操作且部分逻辑对二进制包安装方式适配一般。我更推荐手动执行关键的几步改 root 密码已完成、删除匿名账号、禁止 root 远程登录、删除 test 库。手动 SQL 反而更可控DELETE FROM mysql.user WHERE User; DROP DATABASE IF EXISTS test; FLUSH PRIVILEGES;4.3 远程连接设置与防火墙放行二进制包安装的 MySQL 默认bind-address0.0.0.0监听所有网卡这一步在配置文件中已经处理好。但 CentOS 8 的 firewalld 默认会拦截外部对 3306 端口的访问必须放行firewall-cmd --permanent --zonepublic --add-port3306/tcp firewall-cmd --permanent --zonepublic --add-port33060/tcp firewall-cmd --reload firewall-cmd --list-all3306 是 MySQL 主端口33060 是 MySQL X Protocol 协议端口。如果你的业务只走传统连接33060 这个端口可以不加少暴露一个端口就少一分攻击面。这一点在安全审计时经常被问到很多人的 MySQL 实例就是因为在防火墙里把 33060 也放开了被扫描工具探到后引发了无关要的告警。防火墙配置完成后在客户端机器上验证mysql -uapp_user -p -h 192.168.x.x -P 3306能正常登录就算整个链路通了。注意如果连不上先检查bind-address是否真的是 0.0.0.0再排查防火墙状态最后看错误日志。我见过很多次用户把问题归结为“MySQL 没启动”结果systemctl status一看服务活得好好的纯粹是防火墙没放行。5. 常见问题与排查方法5.1 部署阶段典型问题速查表装得多了遇到的问题是重复的。我把二进制包部署 MySQL 8.0.25 过程中最常见的问题和直接解法整理成一张速查表问题现象根本原因解决方案mysqld: error while loading shared libraries: libaio.so.1缺少 libaio 依赖库dnf install -y libaiomysqld: Cant read dir of /var/lib/mysql/配置文件中 datadir 未生效检查配置文件路径确认 datadir 指向 /data 下的独立目录[ERROR] --initialize specified but data directory exists数据目录已存在且非空备份旧数据后清空目录或换个新目录重新初始化[ERROR] Could not open required defaults file配置文件路径找不到检查 /etc/my.cnf 是否存在文件权限是否 644Authentication plugin caching_sha2_password cannot be loaded客户端工具版本太旧升级客户端到支持 caching_sha2_password 的版本或改用 Native 插件ERROR 1045 (28000): Access denied for user rootlocalhost密码错误或临时密码已过期使用--skip-grant-tables方式重置 root 密码/usr/lib64/libstdc.so.6: version CXXABI_1.3.11 not found系统 libstdc 太旧dnf update libstdc 或安装新版 gcc 运行时库Failed to start mysqld.service: Unit not foundsystemd 服务文件未创建编写 /etc/systemd/system/mysqld.service这里重点说两个坑。第一个是数据目录已存在导致的初始化失败。很多新手重新执行初始化时不清理之前生成的错误文件导致重复报错。安全起见确定要重新初始化时把整个 datadir 目录清空而不是只删几个文件rm -rf /data/mysql_3306/datadir/*但这句话必须搭配一个强烈提醒一定要确认这个目录里没有你要保留的数据库数据否则删完哭都来不及。我自己的习惯是重装阶段宁可多备份备份到一个完全独立的目录。第二个是缓存数据库旧的系统库干扰。CentOS 8 自带的 MariaDB 客户端库文件和 MySQL 的 libmysqlclient 冲突装完 MySQL 后执行mysql --version提示的还是旧客户端这种混乱状态在调用 API 时最容易暴露。确认当前生效的版本/usr/local/mysql/bin/mysql --version which mysql如果which mysql出来的路径不是/usr/local/mysql/bin/mysql说明 PATH 优先级有问题需要调整环境变量echo export PATH/usr/local/mysql/bin:$PATH /etc/profile.d/mysql.sh source /etc/profile.d/mysql.sh5.2 排错思路与日志解读排查 MySQL 启动问题错误日志是第一现场。二进制包安装时我们把log-error指向了/data/mysql_3306/log/error.log所有关键诊断信息都会写在这里。用下面这串命令能快速定位问题tail -n 100 /data/mysql_3306/log/error.log grep -i error /data/mysql_3306/log/error.log | tail -n 20几个高频错误日志的解读[ERROR] [MY-010262] Cant create/write to file /data/mysql_3306/tmp/xxx临时目录不存在或没权限确认 tmp 目录存在且属主是 mysql。[ERROR] [MY-010931] InnoDB: Operating system error number 13 in a file operation.通常是目录权限或 SELinux 上下文问题。权限问题的解法是chown -R mysql:mysqlSELinux 问题则要检查 Web 服务上下文[ERROR] [MY-011071] InnoDB: Unable to lock ./ibdata1有另一个 mysqld 进程在占用数据目录多半是重复启动了实例。用ps -ef | grep mysqld确认并停掉多余进程。关于 SELinuxCentOS 8 默认是 Enforcing 状态。虽然二进制包安装的 MySQL 程序位于 /usr/local/mysql 下SELinux 默认策略可能限制其对 /data 目录的访问。最简单也最稳妥的处理方式不是关 SELinux而是给 MySQL 数据目录设置正确的上下文semanage fcontext -a -t mysqld_db_t /data/mysql_3306(/.*)? restorecon -Rv /data/mysql_3306如果实在没有条件装semanage工具再用setenforce 0临时放宽——但务必记住这只是排查手段不是长期解法。把 SELinux 彻底关闭来换取服务正常运行在等保和内部安全审计阶段会直接亮红灯我建议尽量保持系统默认安全策略只针对 MySQL 所需目录放行。6. 实操过程中的另外两个小细节6.1 环境变量与命令行工具链上面已经提到 PATH 设置但实际项目里还有一层容易漏掉man手册路径和include头文件路径。数据库开发同学需要在机器上编译程序时调用 MySQL 头文件缺失会让编译过程找不到mysql.h。把下面几行追加到/etc/profile.d/mysql.shexport PATH/usr/local/mysql/bin:$PATH export CPLUS_INCLUDE_PATH/usr/local/mysql/include:$CPLUS_INCLUDE_PATH export C_INCLUDE_PATH/usr/local/mysql/include:$C_INCLUDE_PATH然后重载环境变量确认mysql --version输出 8.0.25 版本号。到这里整套工具链就跟系统包管理器安装的体验一致了而且所有路径都是完全可控的。6.2 多实例扩展思路如果不需要可跳过二进制包安装最大的优势之一就是多实例这里简单提一下扩展思路。每个实例需要独立的配置文件和独立的目录mkdir -p /etc/mysql-3307 cat /etc/mysql-3307/my.cnf EOF [mysqld] basedir/usr/local/mysql datadir/data/mysql_3307/datadir socket/tmp/mysql_3307.sock port3307 pid-file/data/mysql_3307/log/mysql_3307.pid log-error/data/mysql_3307/log/error.log EOF初始化时/usr/local/mysql/bin/mysqld --defaults-file/etc/mysql-3307/my.cnf --initialize --usermysql启动时同理每个实例指定自己的配置文件。systemd 服务文件也各自独立。这套方案在测试环境模拟一主两从的复制架构时非常好用一台机器开三个实例端口分别为 3306、3307、3308相互之间完全隔离。7. 一些经验总结与升级建议二进制包安装 MySQL 8.0.25 这套流程我前后在测试环境和生产环境跑过不少次整体感受是只要前期的依赖检查和目录规划做扎实后面基本不会有意外。相比 yum 安装它多花在准备上的十几分钟会在后续的版本管理和故障排查中成倍赚回来。关于版本升级提一个建议。8.0.25 是一个已经有一定历史沉淀的版本如果你的场景需要用到更新的功能比如新的数据字典特性、性能优化补丁后续升级路径是下载新版 tar 包解压到 /usr/local 目录mysqld --version确认版本无误停掉旧实例替换软链接启动新实例最后跑一遍mysql_upgrade8.0 版本在启动时会自动检查并升级数据字典这一点比 5.7 省心很多。最后分享一个我踩过几次坑后养成的习惯在/etc/my.cnf的顶部加一行注释标明这个配置对应的 MySQL 版本、部署日期、部署人和业务用途。这在多人协作的服务器上价值巨大——三个月后另一位同事接手这台机器看到注释就能立刻明白整套实例的背景信息不至于对着配置一头雾水。安装工具千千万能让后来人快速理解你的部署意图也是运维工作里很重要的一环。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑