朋友前不久在Linux服务器上自己编译了一套MySQL,结果卡在了cmake那一步,来回折腾了快两个小时。他看着满屏的-D选项问我:“这些参数到底都是干什么的?哪些必须留,哪些可有可无?”说实话,这个问题我问过自己很多遍。MySQL从源码编译安装这件事,难点从来不在编译本身,而在你对那一大堆编译参数的理解深度——搞懂它们,等于把这个数据库的“骨架”亲手搭了一遍。
很多人在网上找现成的编译命令,复制粘贴一把梭。能用,但一旦遇到报错、想定制功能、或者换了一台机器就懵了。这篇文章我打算把MySQL编译参数从头到尾掰开揉碎讲一遍,包括每个参数默认是什么、选什么值、为什么这么选、踩过哪些坑。同时也给出一套可以直接复制的完整编译部署流程,方便你在CentOS、Ubuntu这类Linux系统上从零搞出一套干净的MySQL实例。适合准备折腾源码安装、做离线部署、或者单纯想把MySQL原理摸透的同学。
1. 为什么要碰编译参数:源码安装的本质是什么
1.1 三种安装方式,三种策略
MySQL的安装方式大致分三类:用发行版自带的RPM或deb包、用官方编译好的二进制tar包、以及从源码现场编译。三种方式解决的问题不一样。
RPM和deb包最省事,但它能装的参数是被打包者锁死的。比如包管理器装出来的MySQL默认把数据目录放在/var/lib/mysql,字符集、插件范围也都固定了。你没法在安装阶段就砍掉不需要的存储引擎,也没法把local_infile默认打开。更麻烦的是,很多定制化编译选项,RPM包你压根看不到。
官方二进制tar包比RPM灵活一些,毕竟可以解压到任意目录。但它的构建配置同样是官方统一编译的,默认开启了很多你未必需要的功能,比如性能诊断、企业版相关组件的一部分依赖等。对绝大多数场景够用,但如果你是安全要求很高的环境、想彻底裁剪体积,或者需要把MySQL装到特定目录配合自己的一套体系,它也不完美。
源码编译安装,说白了就是“自己动手做一份官方二进制”。你用cmake告诉MySQL源码:“我要什么、我不要什么、东西放哪、依赖哪些库。”所以它能提供最强可控性。代价是编译过程耗时、依赖库得齐、出了问题得自己排查。
1.2 什么样的人真正需要源码编译
我的建议是:如果只是装个数据库来跑业务,直接选官方二进制包就行,没必要折腾编译。但如果你属于下面几类情况,源码编译就是正路:
- 有离线部署需求,想把编译好的MySQL连同依赖一起打包带到内网。
- 需要定制安装路径和数据目录,比如公司要求统一挂载到某个业务磁盘下。
- 需要裁剪功能,比如只保留InnoDB,去掉MyISAM、ARCHIVE等不用的引擎。
- 需要固定字符集和排序规则,从一开始就锁定
utf8mb4,免得后面应用连接出现乱码或排序不符合预期。 - 需要结合安全基线,在编译阶段就要禁掉
local_infile、关掉不必要的组件。 - 纯属学习研究,想搞清楚MySQL的构建系统、依赖关系,把基础打牢。
1.3 编译参数本质上是什么
MySQL从5.7时代开始就用CMake作为构建工具,取代了旧的configure脚本。所以现在说的“编译参数”,本质上就是传给cmake的以-D开头的一系列宏定义。每个-DXXX=YYY都会影响两件事:一是源码中的C/C++预处理器宏,二是生成的Makefile里的路径和编译规则。
举个例子,-DCMAKE_INSTALL_PREFIX=/usr/local/mysql会让后续的make install把所有文件放到这个目录。而-DDEFAULT_CHARSET=utf8mb4则会在编译期间把默认字符集写死在二进制里,比在my.cnf里配置更“硬核”。理解这个区别很重要:编译参数是编译时生效的底层配置,运行时参数是进程启动后读取的配置文件,两者互相配合但不完全互相覆盖。
很多人编译好了之后随便写个my.cnf,结果一些变量报错“unknown variable”,就是因为在编译阶段没有启用对应功能,运行时配置自然就认不出来。
2. 编译前的准备:依赖环境与源码包
2.1 依赖库清单先行确认
源码编译MySQL最烦人的就是缺依赖。官方文档列了一堆,实际踩下来核心依赖就那几个:gcc、g++(也就是gcc-c++)、cmake、make、bison、ncurses-devel、libaio-devel、openssl-devel,以及zlib-devel。如果是CentOS 7这类老系统,gcc版本可能偏旧,编译MySQL 8.0会报错,建议先升级devtoolset或者直接选能对应上的MySQL小版本。
我常用的一套命令,CentOS/RHEL系:
yum install -y gcc gcc-c++ cmake make bison ncurses-devel libaio-devel openssl-devel zlib-devel如果是Ubuntu/Debian系:
apt-get install -y gcc g++ cmake make bison libncurses-dev libaio-dev libssl-dev zlib1g-dev注意,Ubuntu 20.04及以上系统的libncurses-dev包名可能带-dev后缀而不是-devel。另外老版本MySQL还依赖perl,新版本基本放开了,但如果你要跑mysql_upgrade或mysql_ssl_rsa_setup这类工具,最好也把perl装上。
2.2 源码包下载与版本选择
源码包可以从MySQL官网下载,也可以从镜像站拉。文件名通常是mysql-8.x.x.tar.gz或mysql-boost-x.x.x.tar.gz。第二个带boost的包会把Boost源码直接打包进来,cmake阶段就不需要额外指定Boost路径,一条-DWITH_BOOST=boost目录就能搞定。
版本怎么选?我的建议是尽量用同大版本的较新小版本。8.0系列选8.0.30以上,因为之前版本在编译依赖和后续性能优化上有差距;8.4和9.x是最新LTS和创新版,追求新特性可以试,但生产环境保守一点。5.7虽然还在一些老项目里大量存在,但它已经接近生命周期尾期,新环境不建议从源码编5.7了。
解压源码包:
tar -xzf mysql-8.0.36.tar.gz cd mysql-8.0.36到这里不要急着执行cmake。先想清楚你要把MySQL装到哪、数据放哪、用什么字符集、打不打开SSL、要不要systemd支持。后面这一大堆问题,都要落实成一行一行的-D参数。
2.3 Boost依赖的处理方式
MySQL 8.0源码编译强依赖Boost库,而且对Boost版本有要求,比如8.0.36要求Boost 1.7.2以上。你系统里如果装了Boost,未必满足这个精确版本要求。此时最简单的方式是下载带-boost的源码包,或者用-DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost让cmake自动下载。
我第一次编译时没注意Boost版本,直接指定系统的Boost路径,结果cmake卡在Could NOT find Boost,翻遍头文件加路径依然不对,最后还是用自动下载方案解决的。所以这块不要在参数上省钱,明确写出-DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost最省心,前提是编译机器能联网。
3. 核心编译参数逐项拆解:每个-D背后都有讲究
3.1 路径类参数:装在哪,数据放哪,配置读哪
CMAKE_INSTALL_PREFIX
这是最基础也最关键的参数,设定安装根目录。默认值是/usr/local/mysql,这也是很多老教程的默认安装路径。实际生产环境经常有自己规划,比如统一装到/opt/mysql或/app/mysql,这没毛病。但注意:参数一旦写在cmake命令里,后续所有工具的默认路径都会跟着它走,比如basedir、plugin_dir、share目录。所以建议一开始就定好,避免装完再挪窝。
MYSQL_DATADIR
指定数据目录。MySQL 8.0的官方二进制默认数据目录编译期通常是/usr/local/mysql/data,但你如果定制了安装路径,数据目录最好也一起显式指定。比如:
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_DATADIR=/data/mysql编译阶段指定的MYSQL_DATADIR会写进默认路径逻辑里,mysqld在读到my.cnf里没有对应项时会拿它当默认值。不过要注意,真正的数据目录权限是由初始化阶段决定的,编译参数只是默认值,运行时还是以配置文件为准。
SYSCONFDIR
指定my.cnf配置文件的默认搜索目录。默认编译是/etc。如果你想让MySQL读自定义位置的配置文件(比如/usr/local/mysql/etc),就在cmake时改掉。需要提醒的是,MySQL读取配置文件的顺序是:先/etc/my.cnf,再SYSCONFDIR下的my.cnf,最后是basedir下的my.cnf,此外还受--defaults-file参数强制指定。所以不要以为编译了SYSCONFDIR就一定会优先读它,这个优先级容易把人绕晕。
3.2 服务类参数:端口、socket与运行用户
MYSQL_TCP_PORT
指定默认TCP端口,默认3306。如果是公司内网有多个MySQL实例并行,可能需要把默认端口改成3307、3308这样。编译参数指定后,mysqld启动时若没在配置文件中显式写port,就会使用编译时的这个端口。平时单实例跑,留默认就行,不用给自己找麻烦。
MYSQL_UNIX_ADDR
指定Unix socket文件路径,默认是/tmp/mysql.sock。这个参数也和热词里常出现的“error 2002 can't connect through socket '/tmp/...'”直接相关。很多本地客户端比如命令行mysql默认走socket连接,如果客户端和服务端对socket路径的理解不一致,连接就会失败。要么显式指定--socket=/data/mysql/mysql.sock,要么保持编译默认和运行时配置一致。我见过有人在cmake里把socket指到/data/mysql/mysql.sock,结果忘了在my.cnf里写,最后客户端走默认/tmp/mysql.sock找不到文件,折腾半天。
MYSQL_USER
这个参数是编译期写入的默认运行用户。MySQL官方推荐用专门的mysql账号跑,不要用root。cmake时-DMYSQL_USER=mysql会在编译后生成的启动脚本和默认配置里体现出来。但注意,编译参数不会自动创建系统账号,你需要手动:
groupadd mysql useradd -r -g mysql -s /sbin/nologin mysql初始化数据目录时也用--user=mysql,这样mysqld进程会以mysql身份运行。如果编译时指定了mysql用户,但系统里根本没这个账号,初始化会报错。这块是新手比较容易忽略的坑。
3.3 字符集类参数:从源头锁定utf8mb4
DEFAULT_CHARSET和DEFAULT_COLLATION
这两个参数直接决定MySQL实例默认字符集和默认排序规则。之前我接手过一个项目,MySQL是从老版本升级上来的,默认字符集是latin1,结果业务部门发现中文乱码,查定位半天就是默认字符集的问题。源码编译时如果能一步到位设置成utf8mb4,后面少很多麻烦。
MySQL 8.0官方二进制默认就是utf8mb4和utf8mb4_0900_ai_ci。如果你是从源码编译5.7,默认可能还是latin1,就一定要显式指定:
-DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_general_ci关于排序规则,utf8mb4_general_ci和utf8mb4_unicode_ci的区别网上讨论很多,简单说:unicode_ci对更多语言排序更准确,但老规则下性能略逊;general_ci更快但排序粗略。8.0里还有utf8mb4_0900_ai_ci,是Unicode 9.0标准,MySQL官方默认。如果在兼容性和速度之间没特殊偏好,建议直接用8.0默认的utf8mb4_0900_ai_ci,别乱改。
还有一个参数**EXTRA_CHARSETS**,控制额外安装哪些字符集,默认是all,即全量编译。如果你做的是极为精简的副本,可以设成none或只留需要的,但一般不建议裁剪,因为后续业务迁移时可能会用到各类字符集,没有就会报错。
MYSQL_COLLATION这个参数在某些版本上不生效,真正关键的是上面的DEFAULT_COLLATION,别搞混。
3.4 依赖类参数:SSL、压缩库与systemd
WITH_SSL
MySQL的SSL支持在编译阶段就决定了。参数可选值是yes、no、system、bundled。system表示使用系统自带的OpenSSL库;bundled则是编译MySQL附带的SSL实现;no就是彻底关掉SSL。
我强烈建议生产环境选system,同时保证系统的openssl-devel已安装。原因很简单:系统的OpenSSL如果出安全漏洞,你单独升级系统包就能覆盖MySQL的SSL依赖,而bundled方式则要重新编译MySQL才能更新库。热词里有“mysql ssl连接错误”,这类问题有相当一部分就出在WITH_SSL选择不当或者系统OpenSSL版本不匹配上。比如你编译时用bundled,之后系统补丁升级了OpenSSL,客户端和服务端协商SSL时版本差异可能引发奇怪错误。
WITH_ZLIB
zlib是压缩库,关系到COMPRESS协议、备份压缩等功能。生产编译建议-DWITH_ZLIB=system或bundled。如果是系统自带zlib且版本太老,选bundled更稳。这个参数出错一般不会立刻暴露,但当你启用压缩协议时才发现行为不对,就晚了。
WITH_SYSTEMD
如果目标机器是用systemd管理服务的Linux(CentOS 7+、Ubuntu 16.04+都是),建议编译时带上-DWITH_SYSTEMD=1。这样安装后会有mysqld.service文件,能用systemctl start mysqld来管理。不带这个参数,就只能用mysqld_safe脚本启停,维护体验差一截。但要注意,开启了systemd支持后,启动时mysqld可能会依赖systemd的Notify机制,手动直接跑mysqld反而有些怪。所以要么编译时统一开启systemd,要么统一用它自带脚本管理,别混着来。
WITH_BOOST需要配合DOWNLOAD_BOOST一起用:
-DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/boost这样cmake构建时如果本目录下没有对应版本的boost,就会自动下载并解压到/usr/local/boost,后续重复编译也不需要重新下载。
3.5 功能裁剪与开发模式参数
ENABLED_LOCAL_INFILE
这个参数控制LOAD DATA LOCAL INFILE是否可用。默认是OFF,即不允许客户端通过local文件导入。这个功能很方便,但有安全风险:如果客户端连接被恶意控制,可能诱导服务端读取客户端本地文件。所以如果业务没有一个强劲的理由非要本地导入,建议默认保持OFF。只要你搞明白这个取舍,编译参数怎么选都不会心虚。
WITH_UNIT_TESTS
编译时会同步构建单元测试,方便开发调试,但对生产环境来说纯属浪费时间。生产编译一定要加-DWITH_UNIT_TESTS=0,能节省不少编译时间。我在8核机器上实测,开测试可以多编大几十分钟。
MYSQL_MAINTAINER_MODE
默认是OFF。开发模式开启后会开启一堆额外的编译器警告,并把警告当错误处理,适合MySQL源码开发者。普通编译务必保持OFF,否则一个无害警告就让你编译失败。
CMAKE_BUILD_TYPE
生产环境用Release,它会开启优化选项,得到性能更好的二进制。除非你是调试崩溃问题,需要走Debug和GDB,否则不要选Debug。Debug版本的mysqld跑业务性能会明显下降,体感上差一个档次。
WITHOUT_ENGINE
MySQL默认编译一堆存储引擎:InnoDB、MyISAM、ARCHIVE、BLACKHOLE、MRG_MYISAM等。如果你想裁剪,可以用-DWITHOUT_ARCHIVE=1 -DWITHOUT_BLACKHOLE=1这类方式关掉。但说句实话,这些引擎占的体积和运行开销极小,剪掉的意义有限。只有在极端精简或安全合规要求下才建议裁剪,一般默认全保留即可。
MYSQLX和**WITH_ROUTER**
MySQL 8.0还有X插件和Router组件的编译开关。X Plugin默认编译,提供MySQL X Protocol支持。如果你跑的是标准连接,不打算用X DevAPI,可以考虑关掉X插件来减少面。Router是独立于server的组件,编译时通常-DWITH_ROUTER=0可以跳过,能缩短一些编译时间。
4. 实操过程:从cmake到跑起一个完整MySQL
4.1 一套完整的cmake配置命令
前面把参数讲透了,下面直接给出一套我在生产环境用过多次、比较稳妥的8.0编译参数组合,可直接对照参考:
cmake . \ -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ -DMYSQL_DATADIR=/data/mysql \ -DSYSCONFDIR=/etc \ -DMYSQL_TCP_PORT=3306 \ -DMYSQL_UNIX_ADDR=/tmp/mysql.sock \ -DMYSQL_USER=mysql \ -DDEFAULT_CHARSET=utf8mb4 \ -DDEFAULT_COLLATION=utf8mb4_0900_ai_ci \ -DEXTRA_CHARSETS=all \ -DWITH_SSL=system \ -DWITH_ZLIB=system \ -DWITH_BOOST=/usr/local/boost \ -DDOWNLOAD_BOOST=1 \ -DWITH_SYSTEMD=1 \ -DENABLED_LOCAL_INFILE=0 \ -DWITH_UNIT_TESTS=0 \ -DMYSQL_MAINTAINER_MODE=OFF \ -DCMAKE_BUILD_TYPE=Release执行后cmake会做环境检测,输出一大段配置信息。看到-- Configuring done和-- Generating done就说明这步过了。如果报错,通常会在最底部给出原因,比如缺库、Boost版本不对、编译器版本过旧。此时别急着重跑,先解决依赖或调整参数再试。
这里想重点强调一下:cmake是增量工具,但你改参数后最好删除CMakeCache.txt再重跑,否则上次的参数会以缓存形式残留,你以为改了某个-D,实际生效的还是旧值。这个坑我踩过不止一次,尤其切换Boost路径、修改数据目录时,旧值直接影响后续编译结果。
4.2 编译与安装阶段
cmake成功后开始编译:
make -j$(nproc)-j参数可以并行编译。$(nproc)会自动读取CPU核心数。机器核数多会快很多,但也要注意内存是否足够。make -j16在8G内存机器上可能直接OOM,编译进程被Kill。一个实用建议:先在top里看下内存,如果是小内存机器,把-j降到4或2,宁可慢一点也别半路崩了。
MySQL 8.0完全编译完,在8核16G内存的环境下大概需要40到60分钟,如果配置低可能要两三个小时。这段时间别闲着,把下一步需要的系统账号、目录都先建好。
编译完成后:
make install这步会把编译好的二进制、库文件、头文件、support-files等拷贝到/usr/local/mysql下。之前我们提到cmake要求的数据目录此时并不会自动创建,make install只装程序,数据目录是后面初始化时的事。
接着创建运行用户和数据目录:
groupadd mysql useradd -r -g mysql -s /sbin/nologin mysql mkdir -p /data/mysql chown -R mysql:mysql /data/mysql chmod 750 /data/mysql4.3 初始化数据目录与启动服务
MySQL 8.0没有mysql_install_db脚本了,改成了mysqld --initialize:
/usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql初始化完成后,日志里会打印一条临时的root密码,格式类似:
[Note] A temporary password is generated for root@localhost: xxxxxxxx这就是网上经常问的“怎么查看MySQL初始密码”的来源。8.0不再支持无密码空登录,必须先拿临时密码登录再改。很多人初始化时没注意终端输出,把密码漏掉了。解决办法是查看错误日志,默认在数据目录下的<hostname>.err文件里,用grep 'temporary password' /data/mysql/*.err就能捞回来。
启动前先写一个简单的my.cnf。因为编译时用了SYSCONFDIR=/etc,所以放到/etc/my.cnf:
[mysqld] basedir=/usr/local/mysql datadir=/data/mysql socket=/tmp/mysql.sock port=3306 user=mysql然后启动:
systemctl start mysqld因为我们编译时加了WITH_SYSTEMD=1,可以这样托管。如果没有这个参数,就用:
/usr/local/mysql/bin/mysqld_safe --user=mysql &登录:
/usr/local/mysql/bin/mysql -uroot -p输入刚刚找到的临时密码,立刻修改root密码:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourStrongPassword';到这里,一个从源码编译的MySQL实例就跑起来了。后续的权限、业务账号、远程访问设置,就跟普通MySQL一样了。
5. 编译安装后的高频问题与排查思路
5.1 error 2002:socket连接失败的典型套路
热词里有一句“error 2002 (HY000): can't connect to local mysql server through socket '/tmp/...'”,这是本地客户端连接最常见的报错。先说结论:这个错绝大多数情况下不是“密码错”,而是“服务不在”或“socket路径不一致”。
排查顺序我建议这样:
- 先确认mysqld进程是否活着:
ps -ef | grep mysqld。如果没进程,就看错误日志。 - 如果进程在,确认socket文件是否存在:
ls -l /tmp/mysql.sock。不存在就说明mysqld没成功建socket,大概率是启动中途崩了。 - 再用客户端显式指定socket试一下:
mysql -uroot -p --socket=/data/mysql/mysql.sock。能连上,说明就是路径不一致。
解决方式要么修改my.cnf里的socket路径,给客户端写入一致的值;要么干脆用-h127.0.0.1 -P3306走TCP连接,绕开socket问题。但注意,root用户的默认认证方式在MySQL 8.0里是caching_sha2_password,走TCP需要SSL或RSA交换,某些场景可能报SSL相关错误,此时可以考虑创建专门的应用账号或者配置mysql_native_password。
5.2 SSL连接错误:编译参数与运行时证书的纠缠
热词里也有“mysql ssl连接错误”。编译期WITH_SSL决定的是mysqld是否支持SSL、用哪种SSL后端,但证书文件是运行时生成的。MySQL 8.0初始化数据目录时会自动生成一组自动签名的SSL证书和密钥,放在数据目录下,常见的文件名是ca.pem、server-cert.pem、server-key.pem、client-cert.pem。
如果启动日志里出现SSL相关报错,比如找不到证书、私钥权限不对,先看数据目录下这些文件是否存在。如果缺失,可以用:
/usr/local/mysql/bin/mysql_ssl_rsa_setup --datadir=/data/mysql再重启。还有一种情况:客户端连接时要求强SSL,但服务端因为编译期WITH_SSL=no根本没启用SSL,就会报“SSL connection error”。这时只能重新编译打开SSL,或者把客户端连接参数里的ssl-mode降级为DISABLED。
我在实际操作中的经验是:能让客户端和服务端都走默认TLS行为最好,别轻易在客户端加--ssl-mode=REQUIRED,因为一旦服务端证书链有问题,排查起来很麻烦。安全策略要求强制SSL时,也要确保证书文件权限是mysql:mysql且600,否则服务端读不了私钥,连接时直接中断。
5.3 cmake缓存残留与参数不生效
刚才说过CMakeCache.txt是元凶。举一个具体场景:你第一次编译时指定了CMAKE_INSTALL_PREFIX=/usr/local/mysql3306,跑了一半发现路径不对,改了命令里的参数为/opt/mysql重跑cmake,结果生成结果还是/usr/local/mysql3306。就是缓存残留。
正确的做法是:
rm -f CMakeCache.txt rm -rf CMakeFiles然后再重跑cmake。尤其是CMAKE_INSTALL_PREFIX这种变量,一旦第一次写入cache,不会因为你第二次命令行里没写就消失,必须清干净。这块建议做进你的部署文档里。
5.4 编译报错速查表
| 现象 | 原因 | 解法 |
|---|---|---|
Could NOT find Boost | Boost路径不对或版本不匹配 | 用DOWNLOAD_BOOST=1自动下载,指定正确版本目录 |
Failed to find libtinfo | 缺少ncurses/ncurses-libs | 安装ncurses-devel或libncurses-dev |
Could not find openssl | 缺少openssl头文件 | 安装openssl-devel后重跑cmake |
No such file or directory: 'c++' | 缺少gcc-c++ | 安装gcc-c++ |
Error: couldn't identify version | cmake版本太老 | 升级cmake到3.x以上 |
| 编译中Killed | 内存不足 | 降-j并发数,加swap |
error while loading shared libraries: libaio.so.1 | 缺libaio运行库 | 安装libaio或libaio1 |
初始化时报--initialize不识别 | 用错了旧版方式 | 确认二进制路径是mysqld而非mysql_install_db |
这些报错如果遇到,先冷静看最末尾的输出,别从头翻log。CMake的错误信息基本都会人性化地指出缺的是哪个库,按图索骥装包就行。
5.5 与运行时配置混淆的误区
还有一个容易踩的误区是“编译参数一定会覆盖运行时配置”。实际规则是:只是默认值。mysqld启动时会按优先级读取my.cnf,命令行参数优先级最高,其次是配置文件,最后才是编译期默认值。
所以编译时指定MYSQL_TCP_PORT=3307,如果my.cnf里写了port=3306,实际监听就是3306。想要某个配置彻底固定不被动摇,光靠编译参数不够,还要配合权限管理控制谁有权限改my.cnf。这一点在做基线安全整改时挺关键,别指望编译参数锁死一切。
6. 一套值得反复使用的推荐参数组合
总结下来,我已经给过一套完整的生产编译命令了。这里再补充两个常见的实际场景组合,供你们直接参考。
第一类是“通用生产环境”推荐:
cmake . \ -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ -DMYSQL_DATADIR=/data/mysql \ -DMYSQL_TCP_PORT=3306 \ -DMYSQL_UNIX_ADDR=/tmp/mysql.sock \ -DDEFAULT_CHARSET=utf8mb4 \ -DDEFAULT_COLLATION=utf8mb4_0900_ai_ci \ -DWITH_SSL=system \ -DWITH_ZLIB=system \ -DWITH_BOOST=/usr/local/boost \ -DDOWNLOAD_BOOST=1 \ -DWITH_SYSTEMD=1 \ -DENABLED_LOCAL_INFILE=0 \ -DWITH_UNIT_TESTS=0 \ -DCMAKE_BUILD_TYPE=Release第二类是“开发测试机快速验证”推荐:
cmake . \ -DCMAKE_INSTALL_PREFIX=$HOME/mysql \ -DMYSQL_DATADIR=$HOME/mysql/data \ -DMYSQL_UNIX_ADDR=$HOME/mysql/mysql.sock \ -DDEFAULT_CHARSET=utf8mb4 \ -DWITH_SSL=system \ -DWITH_BOOST=$HOME/boost \ -DDOWNLOAD_BOOST=1 \ -DWITH_UNIT_TESTS=0 \ -DCMAKE_BUILD_TYPE=RelWithDebInfo开发机上可以用RelWithDebInfo,既有优化又保留调试信息,出问题还能gdb跟一下。装到自己家目录,省去root权限的麻烦,也不需要单独建mysql系统账号,直接当前用户跑。
做这套方案时还需要注意一点:不要盲目照搬别人的cmake参数。个人的建议是——先想清楚三个问题:装在哪个路径、数据放哪个目录、需不需要默认开启额外功能,然后再落实成参数。
另外,编译参数的记录工作值得花三分钟做一下。把完整的cmake命令、make时的内核数和内存情况、时间消耗,统一写进部署文档。因为几个月后你要升级小版本、新增插件时,翻这些记录远比重新试错快。
我自己的习惯是把编译命令保存为一个build.sh脚本放在源码目录里,每次重新编译直接调它,改什么参数也都在里面留痕。这样即使隔了半年再回来,看一眼脚本就能知道这套MySQL是怎么构建出来的。
最后再分享一个小技巧:如果你在同一个机器上想编译多个不同版本或不同参数组合的MySQL,务必给每个build建独立目录。源码包解压后,在源码目录外新建build目录,比如mkdir build-8.0 && cd build-8.0 && cmake ../mysql-8.0.36 ...,这样构建产物互不干扰,CMakeCache.txt也不会因为切换参数而互相污染。我第一次没这么做,直接在源码根目录编,后来想对比不同SSL方案,只能反复删缓存,浪费时间。这个习惯建议一开始就养起来。