需要哪些系统级依赖才能顺利编译 MySQL 源码
MySQL 8.0+ 源码编译对系统环境要求较严格,缺一个关键依赖就卡在
cmake阶段或链接失败。CentOS/RHEL 7/8、Ubuntu 20.04+ 是主流支持平台,但默认系统几乎都不满足条件。
必须安装的底层工具链和库:
gcc和
g++(建议 ≥ 9.3,MySQL 8.0.33+ 明确要求 GCC 9+)
cmake(≥ 3.21,旧版 cmake 会报
CMAKE_CXX_STANDARD not supported)
make(或
ninja,但 MySQL 官方构建脚本默认走 make)
openssl-devel(RHEL/CentOS)或
libssl-dev(Debian/Ubuntu),否则
SSL library not found
ncurses-devel(终端交互组件,缺失导致
libtinfo链接错误)
zlib-devel(压缩支持,影响
myisampack等工具编译)
perl(≥ 5.14,用于生成部分头文件和测试脚本)
特别注意:
bison必须 ≥ 3.0(语法解析器,低于此版本在
sql/sql_yacc.cc编译时报错),
flex≥ 2.6.0;二者常被忽略,但直接导致
make中途退出。
cmake 配置时最关键的几个选项不能漏
MySQL 不再支持
./configure,所有定制靠
cmake参数控制。漏掉某个开关,可能编译出不含 InnoDB、无 SSL、甚至无法启动的二进制。
最小可行配置示例(假设源码在
/path/to/mysql-server,安装到
/usr/local/mysql):
cd /path/to/mysql-server mkdir build && cd build cmake .. \ -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ -DDEFAULT_CHARSET=utf8mb4 \ -DDEFAULT_COLLATION=utf8mb4_0900_ai_ci \ -DWITH_SSL=system \ -DWITH_ZLIB=system \ -DWITH_INNOBASE_STORAGE_ENGINE=1 \ -DENABLED_LOCAL_INFILE=1 \ -DMYSQL_TCP_PORT=3306 \ -DWITH_SYSTEMD=OFF
说明:
-DWITH_SSL=system:强制用系统 OpenSSL(比内置
yaSSL兼容性好,且避免证书验证异常)
-DWITH_INNOBASE_STORAGE_ENGINE=1:InnoDB 不再默认启用,不加这句编译完
mysqld启动会报
Unknown storage engine 'InnoDB'
-DWITH_SYSTEMD=OFF:除非你明确要 systemd 集成,否则关掉,避免生成
mysql@.service冲突已有部署
-DENABLED_LOCAL_INFILE=1:控制
LOAD DATA LOCAL INFILE,不设则默认禁用(安全策略变化)
常见误配:
-DWITH_SSL=bundled在某些 OpenSSL 3.x 系统上会导致 TLS 握手失败;
-DWITH_ZLIB=bundled可能引发压缩函数符号冲突。
编译过程容易卡住的三个典型现象及对策
不是编译慢,而是卡在特定环节——多数是资源或路径问题,不是代码缺陷。
卡在[ 12%] Building CXX object libbinlogevents/CMakeFiles/binlogevents.dir/src/buffer.cpp.o:通常是内存不足(MySQL 编译峰值内存 ≥ 4GB),关闭其他进程,或加
-j$(nproc)控制并发数(如
make -j2)
make install报错
Permission denied: '/usr/local/mysql':别用
sudo make install,先
sudo mkdir -p /usr/local/mysql && sudo chown $USER:$USER /usr/local/mysql,再普通用户执行 编译成功但
mysqld --initialize失败,提示
Can't find error-message file:说明
cmake时没指定
-DINSTALL_MYSQLSHAREDIR=share,或
make install后
share/english/errmsg.sys路径不对;检查
/usr/local/mysql/share/下是否存在
english/子目录
编译后首次初始化与权限目录的硬性要求
MySQL 8.0+ 的
mysqld --initialize对数据目录权限极其敏感,不是“建个空目录就能跑”。
必须满足:
数据目录(如/usr/local/mysql/data)必须为空,且属主为运行
mysqld的用户(非 root) 若用普通用户初始化,需提前
chown -R mysql:mysql /usr/local/mysql/data(假设用户为
mysql)
--initialize会生成临时 root 密码,输出在 error log(默认
hostname.err),不在终端显示;务必查日志,别等它静默失败 若要用
--initialize-insecure(无密码),必须显式加
--user=mysql,否则因权限不足写入失败
初始化完成后,
mysqld仍可能拒绝启动,常见原因是
/etc/my.cnf或
/usr/local/mysql/my.cnf中指定了不存在的 socket 路径或 pid-file 目录不可写——这些路径必须手工创建并授权。
