绝大多数 mysql 生产环境应该用官方 rpm 包,因其提供标准化初始化、systemd 集成、默认安全配置及路径统一;源码编译仅适用于定制引擎、打补丁或特定审计场景。

生产环境该选 RPM 还是源码编译?
直接说结论:绝大多数 MySQL 生产环境应该用官方 RPM 包,不是源码编译。RPM 提供标准化的初始化流程、systemd 集成、默认安全配置(如 validate_password 插件启用)、以及与 OS 用户/权限模型的对齐;而源码编译在无特殊需求时,只会增加部署不确定性、延长上线时间、且容易漏掉关键安全或性能初始化步骤。
常见错误现象:mysqld 启动失败但日志只显示 Failed to start mysqld.service,实际是没执行 mysqld --initialize 或忽略 /var/log/mysqld.log 里明确的报错(比如 Can't open the mysql.plugin table);这类问题在源码安装中高频出现,RPM 则由 %post 脚本自动完成初始化。
- RPM 安装路径固定为
/usr/bin/mysqld、数据目录默认/var/lib/mysql,便于审计和备份脚本复用 - 源码编译若未显式指定
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql和-DMYSQL_DATADIR=/data/mysql,极易导致路径混乱、SELinux 上下文错乱、systemd 单元文件无法适配 - RHEL/CentOS 8+ 及 Rocky/AlmaLinux 默认禁用 MySQL 模块(
dnf module list mysql显示disabled),需先运行dnf module enable mysql:8.0再安装,否则会装上过时的 5.7 或 mariadb
用官方 RPM 安装必须做的三件事
官方 RPM(mysql-community-server)不会自动启动服务,也不会生成 root 密码——这是设计,不是 bug。跳过这三步,服务起不来,或者连不上。
使用场景:新机器首次部署、CI/CD 流水线中自动化安装、容器外宿主机部署。
- 安装后立即执行
mysqld --initialize --skip-grant-tables是错的——RPM 已内置初始化逻辑,只需运行systemctl start mysqld,它会自动触发mysqld --initialize并将临时密码写入/var/log/mysqld.log - 首次登录必须用日志里的临时密码:
grep 'temporary password' /var/log/mysqld.log,然后用mysql -u root -p登录,立刻执行ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourPass123!'; - 确认
mysql.service已启用并设为开机自启:systemctl enable mysqld;若跳过,重启后服务静默退出,监控可能收不到告警
什么时候才考虑源码编译?
仅当需要定制存储引擎(如启用 rocksdb)、打特定补丁、或严格要求二进制符号表完整(如某些安全审计场景)时,才值得投入源码编译。普通业务系统、云服务器、K8s 节点,都不在此列。
参数差异:源码编译必须显式控制 -DDEFAULT_CHARSET=utf8mb4 和 -DDEFAULT_COLLATION=utf8mb4_0900_ai_ci,否则默认仍是 latin1,后续改库字符集代价极高;RPM 包已预设正确值。
- 编译耗时长(单核 20 分钟起),且
make -j$(nproc)在内存 -j2 -
cmake若漏掉-DWITH_SYSTEMD=ON,生成的二进制无法被 systemd 管理,systemctl status mysql查不到进程 - 源码安装后,
mysql_secure_installation脚本通常不可用(路径不在$PATH),得手动删 test 库、关匿名用户、禁远程 root——这些 RPM 全包在 postinstall 里了
RPM 安装后必须验证的两个检查点
很多线上事故源于“服务起来就等于装好了”的错觉。MySQL RPM 安装成功 ≠ 实际可用,必须人工确认这两项。
性能影响:若 innodb_buffer_pool_size 仍为默认 128M,在 4GB 以上内存机器上会严重拖慢查询;兼容性影响:若未关闭 sql_mode 中的 STRICT_TRANS_TABLES,老应用 INSERT 缺字段可能直接报错而非静默补默认值。
- 执行
mysql -u root -p -e "SELECT @@innodb_buffer_pool_size/1024/1024;",确认数值接近物理内存 50%~75%,否则要改/etc/my.cnf中的[mysqld]段 - 执行
mysql -u root -p -e "SELECT @@sql_mode;",确保不包含ONLY_FULL_GROUP_BY(除非业务明确需要);若有,需在my.cnf中显式设为sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
最常被忽略的是 SELinux 上下文——RPM 安装后,若手动挪过 /var/lib/mysql 到其他分区(如 /data/mysql),必须运行 semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?" 再 restorecon -Rv /data/mysql,否则 systemctl start mysqld 会因权限拒绝静默失败。











