
最近在ARM64架构的机器上部署 CentOS 7 MySQL 5.7网上搜了一圈资料大多针对 x86_64真正能在硬件平台上直接照抄的其实不多。这篇文章把我完整的实操过程整理出来从环境确认、方案选型到依赖安装、源码编译、初始化配置以及最后的坑点排查一次性说清楚给同样在 ARM 环境里折腾数据库的朋友一个参考。这篇文章适合三类人一类是拿到了 ARM64 服务器比如鲲鹏、飞腾这类平台需要在上面跑存量业务的一类是在嵌入式或 Android BSP 方向做开发需要顺手搭一套 CentOS 7 环境的还有一类是手头没有真机打算用 QEMU 模拟 ARM64 先演练流程的。无论哪种情况只要目标是在 ARM64 上跑 MySQL 5.7这套流程都适用。1. 装之前先把三件事搞清楚架构、版本和方案1.1 先确认你的硬件到底是不是 ARM64很多人拿到机器就开始敲 yum install结果装到一半发现架构不对白忙活一场。所以我建议第一步永远先确认硬件信息。uname -m uname -a cat /etc/redhat-release如果输出是aarch64那就是 ARM64 架构如果是x86_64下面内容可以参考但很多坑不会踩到。再用lscpu看看 CPU 核数和内存大小这个在后面编译的时候非常关键直接影响用-j参数开多少个并行任务。我见过有人拿一台 ARM 开发板装 CentOS 7内存只有 2G结果编译到一半直接被 OOM 杀掉。所以先看清楚自己的家底再决定后面怎么干。顺带说一句ARM64 的 CentOS 7 镜像和 x86_64 不一样通常要从镜像站点的altarch/7目录下载官方叫 Alternative Architectures。如果你准备自己装系统记得找对应 aarch64 的 ISO别下错版本。1.2 为什么 MySQL 5.7 在 ARM64 上不能直接拿来主义在 x86_64 机器上装 MySQL 5.7大家已经习惯了“yum install mysql-community-server”三步走但到了 ARM64 上这条路往往走不通。原因很简单官方针对 aarch64 的 MySQL 5.7 rpm 包覆盖并不完整。尤其是 CentOS 7 的 aarch64 环境直接配置官方 yum 仓库后经常出现“没有可用软件包”或者依赖解析失败的情况。我去查过几次也试过强制安装 rpm 包最终都被依赖关系绊住了。所以在这种情况下最稳妥、也最通用的方案就是源码编译安装。源码编译的好处是不依赖第三方是否做好了 ARM 包只要编译器能跑软件就能装上去。代价也很明显——耗时长过程繁琐中间任何一个依赖缺失都会卡住。另外还有一个“替代品”选择Percona Server 5.7 提供了 aarch64 的二进制包安装很轻松。如果业务上不强制要求“MySQL 官方版本号”而且团队愿意接受兼容性变化这条方案也能落地。但如果你想保持官方原汁原味的 5.7那源码编译就是主力方案。1.3 安装方案怎么选源码编译、rpm 包、Percona 兼容包我把几种方案整理成一个对比表一目了然方案优点缺点适用场景官方 yum 仓库安装配置简单一条命令aarch64 包覆盖不全经常找不到 5.7先试一把不行就换rpm 包强制安装安装速度快ARM 包难找依赖解析麻烦很少成功不推荐官方源码编译通用性强可定制不依赖 ARM 包编译时间长需要手动管理推荐方案Percona 5.7 二进制包有完整 aarch64 包安装快非官方 MySQL 版本审计可能不认业务允许时可用我最终选的是“官方源码编译”。这个过程虽然折腾但一旦把依赖关系和编译参数搞明白后面遇到任何 ARM 平台的数据库需求心里都有底。2. 编译前的依赖准备与基础环境调整2.1 安装编译工具链CentOS 7 的 cmake 版本是个大坑源码编译 MySQL 5.7 必须用到 cmake版本要求是 3.0 以上。但 CentOS 7 自带的源里默认 cmake 版本只有 2.8.12直接执行 cmake 配置一定会报错CMake 2.8.12 is lower than required version 3.0解决办法是安装 cmake3命令是yum install -y epel-release yum install -y cmake3装完之后系统里会多一个cmake3命令后面配置的时候用cmake3而不是cmake。这个坑几乎每个人都会踩提前说清楚能省很多时间。除了 cmake3编译工具链和依赖库也一并装齐yum install -y gcc gcc-c make ncurses-devel bison openssl-devel libaio-devel numactl-devel perl逐个解释一下为什么需要这些gcc、gcc-c编译 C/C 代码的基本工具链MySQL 5.7 源码编译必须有。ncurses-devel终端文本界面库MySQL 客户端和部分工具依赖。bison语法分析器生成器MySQL 源码编译过程中要用到。openssl-develMySQL 的 SSL 连接功能依赖 OpenSSL 开发库。libaio-devel异步 I/O 库InnoDB 的 native AIO 特性会用到运行的时候也需要libaio.so.1。numactl-develNUMA 相关开发库MySQL 在分配内存时会用。确认一下 gcc 版本和 cmake3 是否可用gcc --version cmake3 --version到这里编译环境就准备好了。2.2 下载源码包与准备 Boost 库依赖MySQL 5.7 源码编译还有一个特殊要求必须指定 Boost 库。5.7 系列从很早就开始依赖 Boost 1.59.0如果本机没有对应版本的 Boostcmake 配置阶段会直接报错。官方下载页面其实提供了一个“一揽子”方案——mysql-boost-5.7.44.tar.gz这个包里面已经把 Boost 1.59.0 的源码打包进去了省去单独下载的麻烦。我在实际使用中强烈推荐这个包尤其是国内网络环境省一次下载就少一次折腾。cd /usr/local/src wget https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-5.7.44.tar.gz tar zxf mysql-boost-5.7.44.tar.gz cd mysql-5.7.44解压之后源码目录下会有一个boost/子目录后面 cmake 配置时直接-DWITH_BOOST./boost就行。这里还要提醒一句如果你选择下载不带 boost 的源码包那就得自己从 Boost 官网下载boost_1_59_0.tar.gz并且解压到固定目录还要保证路径里没有权限问题。既然官方已经给了打包好的版本就别自己给自己加戏了。2.3 创建运行用户与数据目录编译安装不会像 rpm 包那样自动创建 mysql 用户所以需要手动搞定。useradd -r -s /sbin/nologin mysql mkdir -p /data/mysql/logs chown -R mysql:mysql /data/mysql这里我把数据目录放在/data/mysql日志也统一放进/data/mysql/logs。生产环境最好把数据目录单独挂载在一块独立磁盘上避免根分区满了导致数据库异常。如果你有独立数据盘先把盘挂载到/data再执行上面的操作。注意/usr/local/mysql这个安装目录不需要chown给 mysql 用户。很多教程喜欢把整个 mysql 目录全部赋权给 mysql其实从安全角度讲是不必要的甚至有点危险。mysqld 运行的时候只需要对数据目录有写权限安装目录保持 root 所有即可。3. 源码编译安装 MySQL 5.7 全流程3.1 cmake 配置参数解析每个参数都有讲究进入源码目录后执行下面这组 cmake 配置命令。以我实际使用为准参数都经过验证cd /usr/local/src/mysql-5.7.44 cmake3 . \ -DCMAKE_INSTALL_PREFIX/usr/local/mysql \ -DMYSQL_DATADIR/data/mysql \ -DSYSCONFDIR/etc \ -DMYSQL_TCP_PORT3306 \ -DMYSQL_UNIX_ADDR/data/mysql/mysql.sock \ -DDEFAULT_CHARSETutf8mb4 \ -DDEFAULT_COLLATIONutf8mb4_general_ci \ -DWITH_INNOBASE_STORAGE_ENGINE1 \ -DWITH_PARTITION_STORAGE_ENGINE1 \ -DWITH_ARCHIVE_STORAGE_ENGINE1 \ -DWITH_BLACKHOLE_STORAGE_ENGINE1 \ -DWITH_FEDERATED_STORAGE_ENGINE1 \ -DWITH_MYISAM_STORAGE_ENGINE1 \ -DWITH_SSLsystem \ -DWITH_ZLIBsystem \ -DWITH_BOOST./boost \ -DENABLED_LOCAL_INFILE1 \ -DMYSQL_USERmysql逐项说明一下我的选择逻辑方便你按需调整CMAKE_INSTALL_PREFIX安装路径。默认是/usr/local/mysql我保持默认因为这是 MySQL 社区最常用的目录。MYSQL_DATADIR数据目录提前创建的那个/data/mysql。SYSCONFDIR配置文件目录。设为/etc后mysqld 启动时会自动读取/etc/my.cnf。MYSQL_TCP_PORT、MYSQL_UNIX_ADDR端口和 socket 文件位置保持和后续配置文件一致。DEFAULT_CHARSET、DEFAULT_COLLATION默认字符集和排序规则。MySQL 5.7 默认是latin1如果不改建表时不指定字符集就会出现中文乱码的隐患。现在的主流选择是utf8mb4排序规则我用的是utf8mb4_general_ci兼顾性能和兼容性。如果你是精细化排序需求可以换utf8mb4_unicode_ci。WITH_INNOBASE_STORAGE_ENGINE、WITH_MYISAM_STORAGE_ENGINE等要编译的存储引擎。InnoDB 和 MyISAM 是必须的Partition 分区表在 5.7 里默认集成显式开启一下更稳。其余引擎按需开启不用的可以去掉。WITH_SSLsystem使用系统 OpenSSL 库而不是编译内置的 OpenSSL减少后续安全补丁的维护成本。WITH_ZLIBsystem使用系统 zlib 压缩库用于压缩备份等场景。WITH_BOOST./boost指向源码包内置的 Boost 目录。如果这个参数写错或没写配置阶段会卡在 Boost 检测上。ENABLED_LOCAL_INFILE1开启LOAD DATA LOCAL INFILE能力。这个功能默认是关闭的但很多数据导入脚本会用到提前打开后面会省事。MYSQL_USERmysql指定运行用户和前面创建的 mysql 用户对应。配置完成后如果看到-- Configuring done和-- Generating done说明这一步顺利通过。如果中途报红色错误优先排查上面提到的依赖库和 Boost 路径。3.2 make 编译与耗时说明内存不够别硬扛配置完成之后就是最耗时的编译阶段make -j$(nproc)这个-j$(nproc)会自动使用所有 CPU 核数。在核数多的服务器上确实快但有个前提内存要扛得住。每个编译进程大概会吃掉几百 MB 到 1GB 内存如果 16 核但只有 8G 内存开-j16大概率会 OOM。我自己的建议是内存低于 4G老老实实make -j2内存 4G 到 8Gmake -j4内存大于 16G再考虑跑满核心。ARM 平台的单核编译速度普遍不如 x86做好心理准备——一台 4 核 ARM64 机器编 5.7差不多要一两个小时。编译过程中如果被 OOM 杀掉除了降低并行数还可以临时加 swap 空间撑过去dd if/dev/zero of/swapfile bs1M count4096 chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo /swapfile swap swap defaults 0 0 /etc/fstab编译完之后安装make installmake install很快就是把编译出的二进制文件拷贝到/usr/local/mysql然后可以顺手验证一下目录结构ls -l /usr/local/mysql/bin/mysqld看到mysqld文件存在安装这步就完成了。3.3 make install 后的权限修正与路径优化安装完成后还存在两个细节第一再次确认数据目录权限。之前已经chown -R mysql:mysql /data/mysql这一步要再做一次防止编译过程生成的文件改动权限chown -R mysql:mysql /data/mysql第二把 mysql 的 bin 目录加入 PATH方便后面mysql、mysqld命令直接使用echo export PATH/usr/local/mysql/bin:$PATH /etc/profile.d/mysql.sh source /etc/profile.d/mysql.sh有人习惯建软链接ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql也可以但用 profile 文件更干净卸载的时候直接删文件就行。4. 初始化数据目录、配置文件和 systemd 管理4.1 手写一份够用的 my.cnf编译安装不会自动生成/etc/my.cnf需要自己写。我把配置按模块拆开方便你按需复制[client] port3306 socket/data/mysql/mysql.sock [mysql] promptmysql auto-rehash [mysqld] usermysql basedir/usr/local/mysql datadir/data/mysql socket/data/mysql/mysql.sock pid-file/data/mysql/mysqld.pid port3306 server-id1 character-set-serverutf8mb4 collation-serverutf8mb4_general_ci skip-name-resolve explicit_defaults_for_timestamptrue max_connections1000 max_connect_errors100000 back_log500 wait_timeout3600 interactive_timeout3600 tmp_table_size64M max_heap_table_size64M log-error/data/mysql/logs/error.log slow_query_log1 slow_query_log_file/data/mysql/logs/slow.log long_query_time2 log_bin/data/mysql/logs/mysql-bin binlog_formatrow expire_logs_days7 max_binlog_size256M innodb_buffer_pool_size2G innodb_log_file_size256M innodb_flush_log_at_trx_commit2 innodb_file_per_table1 innodb_buffer_pool_instances8 innodb_flush_methodO_DIRECT performance_schemaON说明几个关键点basedir和datadir必须和 cmake 参数一致不然启动会找不到路径。pid-file建议放在数据目录下避免/var/run的权限问题。skip-name-resolve跳过反向域名解析否则客户端连接时会因为 DNS 解析慢而卡顿。但这个选项开了之后grant授权时就不能用主机名只能写 IP 或%。innodb_buffer_pool_sizeInnoDB 缓冲池大小通常设为物理内存的 50% 到 70%按当前机器内存调整。示例里的 2G 只是保守值。innodb_flush_log_at_trx_commit2事务提交时日志不立即刷盘性能好一些。如果业务要求最高数据安全等级改成1。开启了log_bin就是开启了二进制日志为后续主从复制或者数据恢复做准备。如果确定不需要可以注释掉。4.2 初始化数据目录initialize 和 initialize-insecure 的区别配置写好后执行初始化操作。MySQL 5.7 已经完全用mysqld --initialize替代了旧的mysql_install_db脚本。/usr/local/mysql/bin/mysqld --defaults-file/etc/my.cnf --initialize-insecure --usermysql--initialize和--initialize-insecure的区别要讲清楚--initialize会生成一个临时随机 root 密码打印在/data/mysql/logs/error.log文件里。很多人初始化完找不到密码就是因为没看这个日志。--initialize-insecureroot 账号初始为空密码登录后马上设置密码即可。我在测试和学习环境里更推荐这种方式清爽很多。初始化完成后再生成 SSL 证书和 RSA 密钥/usr/local/mysql/bin/mysql_ssl_rsa_setup --basedir/usr/local/mysql --datadir/data/mysql这一步会生成ca.pem、server-cert.pem、client-cert.pem等文件MySQL 的 SSL 连接能力依赖它们。如果不执行之后启动虽然正常但客户端想要启用 SSL 加密连接时会遇到麻烦。初始化过程通常几秒钟就结束。如果报错99% 是数据目录权限不对或者 my.cnf 里配置项写错去看 error.log 比瞎猜有效得多。4.3 手写 systemd 服务单元文件rpm 包装完会自动注册 systemd 服务但编译安装不会。所以需要手动创建一个服务单元文件/etc/systemd/system/mysqld.service[Unit] DescriptionMySQL Community Server 5.7 Afternetwork.target Aftersyslog.target [Service] Typenotify Usermysql Groupmysql PIDFile/data/mysql/mysqld.pid ExecStart/usr/local/mysql/bin/mysqld --defaults-file/etc/my.cnf LimitNOFILE65535 LimitNPROC65535 TimeoutSec300 PrivateTmptrue Restarton-failure RestartSec5s [Install] WantedBymulti-user.target这里用的是Typenotifymysqld 启动成功后会向 systemd 发通知相比传统的Typeforking更加快速可靠。但有一个注意点部分旧内核环境可能对 notify 支持不佳如果启动时一直卡在 “Activating start” 超过 30 秒把 Type 改成simple或者换成ExecStart/usr/local/mysql/bin/mysqld_safe --defaults-file/etc/my.cnf搭配Typeforking都能绕过去。注册并启动服务systemctl daemon-reload systemctl enable mysqld systemctl start mysqld systemctl status mysqld启动后立刻看一眼日志确认没有异常tail -50 /data/mysql/logs/error.log看到类似ready for connections就说明数据库已经正常起来了。4.4 启动后的基本验证与安全设置服务启动后验证最基本的登录和版本信息mysql -uroot -p # 因为用了 --initialize-insecure密码直接回车登录成功后SELECT version(); ALTER USER rootlocalhost IDENTIFIED BY YourStrongPassword; FLUSH PRIVILEGES;设置完密码后再敲exit重新登录一次确认新密码生效。此外检查一下字符集是否按预期生效SHOW VARIABLES LIKE character_set_server; SHOW VARIABLES LIKE collation_server;我这里做验证时两个输出分别是utf8mb4和utf8mb4_general_ci说明 my.cnf 的配置已经正确读取。如果后面要远程连接还要处理防火墙和账号firewall-cmd --permanent --add-port3306/tcp firewall-cmd --reloadCREATE USER app% IDENTIFIED BY YourAppPassword; GRANT ALL PRIVILEGES ON *.* TO app%; FLUSH PRIVILEGES;5. 常见问题与排查实录5.1 快速问题速查表我把实际踩过的坑汇总成一张速查表遇到问题先对照排查报错信息或现象原因解决办法CMake 2.8.12 is lower than required version 3.0CentOS 7 自带 cmake 版本太老yum install cmake3用cmake3命令Could NOT find BoostBoost 路径未指定或版本不对用mysql-boost-5.7.44.tar.gz源码包-DWITH_BOOST./boosterror while loading shared libraries: libaio.so.1缺少异步 I/O 运行库yum install -y libaio libaio-develmysqld: Cant create/write to file /data/mysql/mysqld.pid数据目录权限不对chown -R mysql:mysql /data/mysqlFailed to initialize DD storage engine数据目录权限或 my.cnf 配置错误查看 error.log修正配置和权限systemctl start 后状态一直是 activatingTypenotify 在部分环境兼容性差改成Typesimple或换mysqld_safeAccess denied for user rootlocalhostroot 密码与预期不符初始化时用--initialize-insecure或从 error.log 找临时密码远程连接 Connection refused防火墙没放行或 bind_address 限制放行 3306 端口检查 my.cnf 是否有 bind_address中文存入后乱码默认字符集不是 utf8mb4my.cnf 设置character-set-serverutf8mb4重建相关表5.2 编译内存不足怎么救swap 扩容实操编译 MySQL 5.7 最让人崩溃的并不是报错而是编译到一半进程直接消失没有任何提示。如果是在终端上编译可能会看到一行Killed这就是内存被 OOM Killer 干掉了。解决办法有几个第一降低并行数。make -j2虽然慢但每一步都很稳。第二增加 swap。前面已经给出命令建议在编译期间临时挂一个 4G 的 swap 文件dd if/dev/zero of/swapfile bs1M count4096 chmod 600 /swapfile mkswap /swapfile swapon /swapfile但要注意swap 是在内存不够时的缓解方案如果内存只有 1G就算挂 4G swap编译速度也会慢到让人怀疑人生。有条件的话还是建议至少 2G 内存起步。第三清理无用的进程释放内存。我遇到过一次比较极端的情况服务器上还跑着其他 Java 服务编译时内存只剩下几百兆后来停掉一个临时服务编译就顺利完成了。5.3 几个容易忽略的后续细节装完数据库只是开始有几个细节我建议第一时间处理。第一个是把 mysql 和 mysqldump 命令加入 PATH有人会遇到mysql: command not found。前面写了/etc/profile.d/mysql.sh但注意新开的 shell 窗口才生效当前窗口需要手动source一下。第二个是卸载清理。如果你之前尝试过 rpm 安装但失败了会有残留的/etc/my.cnf、/var/lib/mysql目录。编译安装前把这些残留清理干净否则初始化时可能和旧配置冲突。rm -rf /var/lib/mysql rm -f /etc/my.cnf.rpmsave第三个是备份慢日志和 binlog 的清理策略。expire_logs_days7只对二进制日志生效不代表逻辑备份可以不做。如果这台机器要接手存量业务建议第一时间配好定时任务把常用库的基础备份跑起来不然哪天真出问题再补救就晚了。说点题外话如果你手头也是 ARM64 的 CentOS 7我最想说的就一句话别硬背 x86 那一套方式很多细节是真的不一样。cmake 版本要换、rpm 仓库大概率装不上、编译还特别吃内存——这些坑我都是实打实踩过一遍才摸清楚的。如果只是临时验证流程手头没有 ARM64 真机也可以考虑用 QEMU 模拟一个 aarch64 环境先把流程跑通。模拟器的性能比真机差不少编译时间可能会拉长很多但用来做流程验证和参数测试完全够用。另外多说一句如果业务对版本没有特别要求能上 MySQL 8.0 还是尽量上 8.0。但现在很多老项目就卡在 5.7 这一档动弹不得这篇文章也就是给这些系统续命用的。编译安装走一遍至少能让你明白这套环境是怎么搭起来的以后出了问题排查的方向也会比只会用 yum 的人清晰得多。