CentOS 8 源码编译安装 MySQL 8 完整指南:从依赖到启动
MySQL 这东西,装起来说简单也简单,yum 一条命令就能跑;说折腾也真折腾,源码编译能把人卡在依赖、权限、初始化好几个坑里。我见过太多刚接触 Linux 的朋友,在虚拟机里装 CentOS 8,想跑个 MySQL 练手,结果卡在 cmake 报错、socket 找不到、服务起不来这些地方,一耗就是一下午。这篇内容就是写给这类朋友的——从零开始在 VMware 虚拟机里的 CentOS 8 上,用源码方式把 MySQL 完整装起来,每一步为什么这么做、容易在哪翻车,我都掰开揉碎讲清楚。源码安装虽然比 yum 麻烦,但它能让你真正搞明白 MySQL 的目录结构、配置文件加载顺序、初始化流程这些底层逻辑,练手价值远高于一键安装。适合刚入门 Linux 和数据库、想打牢基础的同学,也适合需要特定版本 MySQL 做测试的从业者参考。
1. 为什么在虚拟机里偏要用源码装 MySQL
1.1 源码安装和 yum 安装到底差在哪
先把这件事说透,不然很多人装到一半就怀疑人生:明明dnf install mysql-server几分钟搞定,为什么要花一两个小时编译?答案在于可控性和学习价值。
yum/dnf 安装走的是发行版维护者打包好的二进制包,版本、编译参数、安装路径、默认配置全是别人定好的。你拿到的是一个"黑盒",能用,但不知道它内部怎么组织的。而源码安装,从下载源码、配置编译参数、编译、安装到初始化,每一步你都得亲手过一遍,MySQL 的安装目录长什么样、配置文件从哪加载、数据目录在哪、socket 文件放哪,全部由你决定。这个过程走一遍,后面遇到"服务起不来""连不上 socket""配置文件不生效"这类问题,你脑子里有地图,排查起来快得多。
具体差异我列个表对比一下,心里有个数:
| 对比维度 | yum/dnf 安装 | 源码编译安装 |
|---|---|---|
| 安装耗时 | 几分钟 | 30 分钟到 2 小时不等(看机器性能) |
| 版本选择 | 受限于软件源 | 任意版本,官网下载即可 |
| 安装路径 | 分散在系统标准路径 | 可统一指定,如 /usr/local/mysql |
| 编译参数 | 固定 | 完全自定义 |
| 依赖处理 | 自动解决 | 需手动装齐 |
| 学习价值 | 低 | 高,能理解内部结构 |
| 卸载干净度 | 一般 | 删目录即可,干净 |
对于练手和学习,源码安装的价值是实打实的。你在虚拟机里折腾,搞坏了直接快照回滚,成本几乎为零,这正是练源码安装的最佳环境。
1.2 虚拟机环境相比物理机的几个实际好处
在 VMware 里做这件事,比在物理机上折腾有几个明显优势,值得说清楚。第一是快照,装之前打个快照,编译到一半发现参数配错了,直接回滚,不用重装系统。第二是隔离,MySQL 装坏了、端口冲突了、配置文件改乱了,都影响不到宿主机。第三是资源可调,编译 MySQL 挺吃内存的,虚拟机内存给到 4G 以上会顺畅很多,物理机反而不好随便加。
我个人的习惯是:装系统后第一件事打一个"干净系统"快照,装完 MySQL 再打一个"装好 MySQL"快照。这样后面做实验搞乱了,回滚到第二个快照,几分钟就能恢复到一个可用的数据库环境,比重新装一遍省太多时间。
提示:虚拟机内存建议不低于 4GB,CPU 核心给 2 个以上。源码编译 MySQL 8 对内存有一定要求,内存太小编译阶段容易因为 OOM 被杀进程,表现就是编译到一半突然中断,还不一定报明显错误。
1.3 装之前必须确认的几件事
动手之前,有几个前置条件先确认好,能省掉后面一堆麻烦。系统版本确认是 CentOS 8(cat /etc/centos-release),网络能通(后面要下载源码包和依赖),磁盘空间够(源码加编译产物加数据目录,建议预留 10GB 以上),以及关闭 SELinux 或者调整策略——这一条很多人忽略,SELinux 会拦截 MySQL 访问数据目录,导致初始化失败或者服务起不来,报错还特别隐晦。
磁盘空间这块我算一下:MySQL 8 源码包解压后大概 1.5GB 左右,编译产物(build 目录)能到 2-3GB,安装后的程序目录几百 MB,数据目录初始几百 MB。加起来 10GB 是比较稳妥的余量。用df -h看一眼根分区,不够的话提前扩。
2. 编译前的依赖与系统准备
2.1 装齐编译工具链和依赖库
源码编译 MySQL 需要一整套工具链:编译器(gcc/gcc-c++)、构建工具(cmake、make)、以及一堆库(ncurses、openssl、boost 等)。CentOS 8 的软件源里这些都有,一条命令批量装:
dnf install -y gcc gcc-c++ cmake make ncurses-devel openssl-devel \ libaio-devel bison bison-devel libtirpc-devel rpcgen \ perl perl-Data-Dumper perl-Getopt-Long这里解释几个关键依赖为什么必须装。cmake是 MySQL 8 的构建系统,没有它连配置都跑不起来;ncurses-devel是命令行客户端mysql依赖的库,缺了它编译客户端会失败;openssl-devel关系到 SSL 连接和密码加密,MySQL 8 默认用 caching_sha2_password 认证插件,强依赖 OpenSSL;libaio-devel是异步 IO 库,InnoDB 引擎用它做磁盘 IO;bison是语法分析器生成工具,SQL 解析器编译需要它。
注意:CentOS 8 已经停止维护,默认的软件源可能失效。如果
dnf install报 "Failed to download metadata" 之类的错,需要先把软件源换成可用的镜像地址。这一步是很多人卡住的第一个坑,源不通后面全白搭。换源的具体地址这里不展开,思路是把/etc/yum.repos.d/下的 repo 文件里的 baseurl 指向一个当前可访问的镜像。
2.2 关于 Boost 库的特殊处理
MySQL 8 的源码编译有个特殊点:它依赖Boost C++ 库。有两种处理方式,一是系统里装好 boost 开发包让 cmake 自己找,二是让 cmake 在配置时自动下载。我推荐第一种,因为自动下载依赖网络,网络不稳的时候配置阶段会莫名失败。
dnf install -y boost boost-devel装完之后,cmake 配置时加参数-DWITH_BOOST=/usr/include/boost指向系统 boost 头文件目录(具体路径以实际安装为准,可以用rpm -ql boost-devel | grep boost确认)。这样配置阶段就不会去联网下载 boost,稳定性高很多。这个细节很多教程没提,但实际编译时因为 boost 下载失败卡住的人不在少数。
2.3 创建专用的 mysql 用户和组
MySQL 出于安全考虑,不应该用 root 跑。标准做法是创建一个系统用户mysql,专门用来运行数据库进程和拥有数据目录。
groupadd mysql useradd -r -g mysql -s /bin/false mysql-r表示创建系统用户,-s /bin/false表示这个用户不允许登录 shell——它只用来跑服务,不需要交互登录,这样更安全。这一步现在做,后面初始化数据目录和授权都要用到这个用户,先建好省得来回切。
3. 下载源码与 cmake 配置的门道
3.1 选版本与下载源码包
到 MySQL 官方下载页找源码包,选mysql-8.0.xx.tar.gz这种带tar.gz的源码归档(注意别下成编译好的二进制包,二进制包名字里通常带linux-glibc字样)。版本选择上,练手用 8.0 系列的最新小版本即可,太老的版本在新系统上编译反而容易出兼容问题。
下载可以用wget直接在虚拟机里拉:
cd /usr/local/src wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.xx.tar.gz下载完先校验一下文件完整性(官网提供 MD5 或 SHA256),然后解压:
tar -zxvf mysql-8.0.xx.tar.gz cd mysql-8.0.xx源码放/usr/local/src是个约定俗成的习惯,方便管理。解压出来的目录就是源码根目录,后面 cmake 就在这个目录里跑。
3.2 cmake 参数逐个拆解
这是整个源码安装里最关键的环节,参数配错了,后面编译出来的东西可能缺功能或者路径不对。先给一份我常用的配置命令,再逐个解释:
cmake . \ -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ -DMYSQL_DATADIR=/usr/local/mysql/data \ -DSYSCONFDIR=/etc \ -DWITH_INNOBASE_STORAGE_ENGINE=1 \ -DWITH_ARCHIVE_STORAGE_ENGINE=1 \ -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ -DWITH_READLINE=1 \ -DWITH_SSL=system \ -DWITH_ZLIB=system \ -DWITH_LIBWRAP=0 \ -DMYSQL_TCP_PORT=3306 \ -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \ -DDEFAULT_CHARSET=utf8mb4 \ -DDEFAULT_COLLATION=utf8mb4_general_ci \ -DWITH_BOOST=/usr/include/boost \ -DDOWNLOAD_BOOST=0逐个说清楚每个参数的作用和为什么这么设:
CMAKE_INSTALL_PREFIX:安装根目录,所有程序、库、头文件都装到这下面,统一管理,卸载时删这一个目录就干净了。MYSQL_DATADIR:数据目录,数据库文件、日志都在这。单独指定而不是用默认,是为了路径清晰可控。SYSCONFDIR:配置文件目录,设成/etc后,MySQL 会去/etc/my.cnf找配置,符合系统习惯。WITH_SSL=system:用系统自带的 OpenSSL,而不是源码里自带的,减少编译量也便于后续升级。MYSQL_UNIX_ADDR:socket 文件路径。这个特别重要,客户端连本地数据库默认走 socket,路径不对就连不上,报 "Can't connect to local MySQL server through socket"。设成安装目录下,路径明确。DEFAULT_CHARSET=utf8mb4:默认字符集。utf8mb4 才是真正完整的 UTF-8,能存 emoji 和生僻字,别用老的 utf8(它是 utf8mb3 的别名,有坑)。DOWNLOAD_BOOST=0:明确告诉 cmake 不要联网下载 boost,用系统装好的。
提示:cmake 配置阶段如果报某个库找不到,先别急着改参数,用
rpm -qa | grep 库名确认开发包是否装了。很多"找不到 XXX"的报错,本质是只装了运行库没装-devel开发包。
3.3 配置失败最常见的三类原因
cmake 配置这一步是新手翻车高发区,我把最常见的三类原因列出来,遇到报错先对照排查。
第一类是依赖缺失,报错里通常带 "Could NOT find XXX"。解决办法就是回到第 2 章,把对应的-devel包补上。第二类是boost 相关报错,要么是没装 boost-devel,要么是WITH_BOOST路径指错了。第三类是cmake 版本过低,MySQL 8 对 cmake 版本有最低要求,CentOS 8 自带的 cmake 一般够用,但如果报版本相关错误,需要升级 cmake。
配置成功的标志是最后输出一段 "Configuring done" 和 "Generating done",并且没有 error。看到这个就可以进入编译了。如果配置阶段有 warning,大部分可以忽略,但涉及依赖和路径的 warning 要留意。
4. 编译安装与初始化:最耗时的硬仗
4.1 make 编译的时间预期与并行加速
配置通过后,执行编译:
make -j$(nproc)-j$(nproc)表示用所有 CPU 核心并行编译,能显著缩短时间。单核编译 MySQL 8 可能要一两个小时,4 核并行能压到 20-30 分钟。虚拟机 CPU 核心给得多,这里就体现价值了。
编译过程中屏幕会刷大量编译输出,正常现象。要关注的是有没有Error字样。如果编译到一半突然中断,最常见的原因是内存不足被系统杀掉(OOM),表现是进程莫名消失、没有明确报错。这时候要么加虚拟机内存,要么减少并行数(比如make -j2)降低瞬时内存占用。
注意:编译期间别去动源码目录里的文件,也别中途 Ctrl+C 再重来,容易留下半成品导致后续编译状态混乱。真要中断,先
make clean清理再重新编译。
4.2 make install 与目录结构确认
编译完成后安装:
make install安装会把编译产物复制到CMAKE_INSTALL_PREFIX指定的目录。装完去/usr/local/mysql下看一眼,应该有bin、lib、include、share这些子目录。bin里是mysqld(服务端)、mysql(客户端)、mysqladmin等可执行文件,这是后面操作的核心。
装完还要做一件事:把 MySQL 的库路径加到系统动态链接库配置里,否则运行mysqld可能报找不到libmysqlclient之类的错。
echo "/usr/local/mysql/lib" > /etc/ld.so.conf.d/mysql.conf ldconfig4.3 初始化数据目录的正确姿势
这一步是把一个"空壳"变成能跑的数据库实例。先确保数据目录存在且属主是 mysql 用户:
mkdir -p /usr/local/mysql/data chown -R mysql:mysql /usr/local/mysql然后执行初始化。MySQL 8 用--initialize参数,注意区分--initialize和--initialize-insecure:前者会生成一个随机 root 密码并打印在错误日志里,后者 root 密码为空。练手环境我一般用--initialize-insecure,省得去日志里翻密码,但生产环境绝对不能用 insecure。
/usr/local/mysql/bin/mysqld --initialize-insecure \ --user=mysql \ --basedir=/usr/local/mysql \ --datadir=/usr/local/mysql/data初始化成功的标志是数据目录里出现mysql、sys、performance_schema等系统库目录,以及ibdata1、ib_logfile这些 InnoDB 文件。如果初始化失败,去数据目录下找.err结尾的错误日志,里面会写清楚原因。最常见的失败原因是目录权限不对(mysql 用户没权限写数据目录)和SELinux 拦截。
提示:初始化只能对空数据目录执行一次。如果初始化失败想重来,必须先把数据目录清空(
rm -rf /usr/local/mysql/data/*),否则会报 "data directory has files" 之类的错。
5. 配置文件、启动与首次登录
5.1 写一份最小可用的 my.cnf
MySQL 启动时会按顺序找配置文件,/etc/my.cnf是常见位置。写一份最小配置:
[mysqld] basedir=/usr/local/mysql datadir=/usr/local/mysql/data socket=/usr/local/mysql/mysql.sock port=3306 user=mysql character-set-server=utf8mb4 collation-server=utf8mb4_general_ci [client] socket=/usr/local/mysql/mysql.sock default-character-set=utf8mb4这里[client]段的 socket 路径必须和[mysqld]段一致,否则客户端连不上。这个配置看着简单,但把 basedir、datadir、socket 三个路径写对,能避免 80% 的启动和连接问题。
5.2 启动服务与验证
源码安装没有 systemd 服务文件,可以直接用 mysqld_safe 启动(它会监控 mysqld 进程,挂了自动拉起):
/usr/local/mysql/bin/mysqld_safe --user=mysql &启动后验证:
ps -ef | grep mysqld netstat -tlnp | grep 3306能看到 mysqld 进程和 3306 端口监听,说明起来了。然后登录:
/usr/local/mysql/bin/mysql -u root -p因为初始化用的是 insecure,root 密码为空,直接回车进。进去后第一件事就是改密码:
ALTER USER 'root'@'localhost' IDENTIFIED BY '你的强密码'; FLUSH PRIVILEGES;5.3 把 MySQL 加进环境变量和开机自启
每次敲全路径太麻烦,把 bin 目录加进 PATH:
echo 'export PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile source /etc/profile开机自启方面,源码安装可以自己写一个 systemd 服务文件放到/etc/systemd/system/mysqld.service,内容里指定ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf,然后systemctl enable mysqld。这样重启虚拟机后数据库自动起来,不用每次手动敲命令。
6. 那些年踩过的坑与排查链路
6.1 socket 连接失败:从报错到定位的完整过程
这是源码安装最高频的问题,报错长这样:Can't connect to local MySQL server through socket '/tmp/mysql.sock'。注意报错里的路径是/tmp/mysql.sock,而你配置的是/usr/local/mysql/mysql.sock,路径对不上,说明客户端没读到你的配置。
排查链路是这样的:先确认服务端实际用的 socket 路径,ps -ef | grep mysqld看启动参数里有没有--socket,或者直接看my.cnf里[mysqld]段的 socket。然后确认客户端读的是哪个配置——客户端默认会读/etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf等多个位置,如果[client]段没写 socket,它就用编译时的默认值(往往是/tmp/mysql.sock)。解决办法就是在[client]段显式写上和服务端一致的 socket 路径。这个坑的本质是配置加载顺序和段的作用域没搞清楚。
6.2 权限与 SELinux 导致的初始化失败
初始化时报 "Permission denied" 或者进程直接退出,八成是权限问题。检查数据目录属主是不是 mysql(ls -ld /usr/local/mysql/data),以及 mysql 用户对上层目录有没有执行权限。另一个隐形杀手是 SELinux,它会阻止 mysqld 访问非标准路径下的数据目录。临时验证可以setenforce 0关掉 SELinux 再试,如果关掉就好了,说明是 SELinux 策略问题,长期方案是给数据目录打上正确的 SELinux 上下文标签,而不是一直关着。
6.3 编译中断与内存不足的识别
编译到一半进程消失、没有明确报错,先看系统日志dmesg | tail,如果有 "Out of memory: Killed process" 字样,就是 OOM。解决办法是加内存或降并行度。还有一种情况是磁盘满了导致编译失败,df -h一看便知。这两种"无声失败"最容易让人抓狂,因为编译输出里看不出原因,得从系统层面找。
7. 装完之后值得做的几件事
装好只是起点,几个收尾动作能让这个环境更好用。第一,建一个普通业务用户,别一直用 root 操作,CREATE USER 'dev'@'%' IDENTIFIED BY '密码'; GRANT ALL ON 库名.* TO 'dev'@'%';,养成权限最小化的习惯。第二,配置远程连接(如果需要在宿主机用客户端连虚拟机),确认防火墙放行 3306,并且用户 host 允许对应来源。第三,定期备份练手数据,用mysqldump导出一份,顺便把备份恢复流程也练一遍,这比装数据库本身更有实战价值。
我个人在虚拟机里折腾 MySQL 的体会是:源码安装这一遍走下来,后面再看 yum 装的 MySQL,目录结构、配置文件、启动流程全都一目了然,排查问题心里有底。虚拟机快照这个功能一定要用起来,装之前打一个,装好再打一个,折腾坏了回滚,成本几乎为零,这才是虚拟机练手最大的价值。