ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ARM64 CentOS7部署MySQL5.7:aarch64 RPM包指南

ARM64 CentOS7部署MySQL5.7:aarch64 RPM包指南 如果你最近需要在 ARM64 架构的服务器上部署一套 CentOS7 MySQL5.7应该已经撞过不少墙了。我上周在一台 aarch64 的测试机上折腾了整整一天核心问题就一个Oracle 的官方 yum 源根本没有提供 aarch64 的 mysql5.7 仓库直接yum install mysql-server只会得到一句“没有可用包”。这篇文章记录的就是完整的排查和安装链路——从 CentOS7 aarch64 镜像准备到下载 ARM64 版 MySQL5.7 RPM 包再到本地安装、初始化、配置远程访问全程可复现。如果你和我一样是在 QEMU 模拟的 ARM64 环境里操作这篇文章同样适用。先说结论ARM64 上装 MySQL5.7 的正道不是走 yum 仓库而是从 MySQL 官方 archives 页面或国内镜像下载专门的 aarch64 RPM 包然后yum localinstall本地安装依赖用系统自带源解决。这条路解决了 90% 的坑剩下的坑基本集中在libaio.so.1、numa库和初始化密码上。下文会把每个步骤背后的原因也讲清楚不是单纯给你一串命令。1. 为什么 ARM64 上装 MySQL 5.7 这么费劲yum 源与架构的双重限制1.1 官方 yum 仓库的 aarch64 空白很多习惯 x86_64 环境的同学第一反应是去 MySQL 官方 yum 仓库配置 repo然后yum install mysql-server。这个思路在 ARM64 上直接失效MySQL 官方 yum repo 长期以来只提供 x86_64 的二进制包aarch64 目录在 5.7 时代基本是不存在的。即使你强行把 repo 地址指向 ARM64 目录也会得到一个 404 或者空的 repodata。这个问题的根源不在 CentOS而在 MySQL 官方对 ARM64 二进制的分发策略。MySQL 5.7 的 ARM64 支持其实在 Linux Generic 二进制包tar.gz里是有提供的但 yum 仓库没有同步跟进导致“官方有二进制却没有 yum 仓库入口”的尴尬局面。所以 ARM64 上安装 MySQL5.7最稳定可靠的拿包方式只有两个下 RPM 包本地装或者下 Generic tar.gz 手动解压部署。1.2 两条可行路线本地 RPM vs 源码编译对于生产环境和测试机我强烈建议走本地 RPM 路线不要轻易选择源码编译。MySQL 5.7 源码编译在 ARM64 下需要处理 Boost 库、GCC 版本、jemalloc 一堆依赖一个下午可能都编不出一个可用的二进制而 RPM 包是官方预编译好的安装速度快还自带 systemd 服务脚本省去很多手工活。本地 RPM 的另一大优势是依赖关系基本能用 CentOS7 自带 base 源解决。MySQL 5.7 的依赖主要是libaio、numactl、perl、ncurses-libs这些在 CentOS7 aarch64 的默认源里都有不需要额外折腾第三方源。1.3 版本选择为什么优先选 5.7.44 或 5.7.43MySQL 5.7 在 2023 年之后就不再更新了最后的几个版本分别是 5.7.43、5.7.44。选择版本时建议优先 5.7.44因为它修复了 5.7.43 之前的一些已知问题而且在 ARM64 上的 glibc 兼容性更好。如果你在公司内网环境下载 5.7.44 的 aarch64 RPM 包未来两年内不用担心安全漏洞补丁的问题。另外注意MySQL 官方针对 ARM64 的 RPM 包命名中会带 aarch64 字样比如mysql-community-server-5.7.44-1.el7.aarch64.rpm千万别下成 x86_64 版本。2. 环境准备CentOS 7 aarch64 镜像获取与初始化设置2.1 真机与 QEMU 模拟两种场景的镜像差异如果你手头是真 ARM64 服务器比如飞腾、鲲鹏这类当然也有其他品牌的 ARM 服务器直接用服务器厂商提供的 CentOS7 aarch64 ISO 或云镜像就行。如果是本地开发调试像我一样用 QEMU 模拟 ARM64 环境那镜像选择就有讲究了建议下载 CentOS-7-aarch64 的 qemu-img 格式 cloud 镜像启动参数里要指定-cpu cortex-a72或max否则后续安装软件时会出现指令集不支持的问题。QEMU 模拟环境下有个额外注意点MySQL 安装过程会比较慢因为二进制翻译开销很大mysqld --initialize可能要跑几分钟。这不是你操作出错是模拟器本身的性能瓶颈耐心等待即可。如果模拟环境内存小于 2G建议先加 swap否则数据库初始化很容易 OOM。2.2 yum 源替换与基础依赖安装拿到 CentOS7 aarch64 系统后第一步不是急着下载 MySQL而是先把 yum 源配好。CentOS 7 的官方源因为生命周期结束很多 mirror 已经停止同步建议把/etc/yum.repos.d/CentOS-Base.repo里的 baseurl 换成国内还在维护的镜像源比如阿里的 centos-vault 或清华源。这一步做完后面安装依赖才不至于报 404。基础依赖方面先装这几个包yum install -y wget vim lsof net-tools numactl-libs libaionumactl-libs和libaio是 MySQL 5.7 的关键依赖提前装好能避免安装 RPM 时的一串报错。具体为什么要装这两个后面第 4 节会详细说。2.3 确认架构与内核版本在下载 RPM 包之前一定要先确认当前系统架构防止下错包。执行uname -m如果输出是aarch64说明你是 ARM64 环境整个安装流程按本文走。如果输出是x86_64那你直接用官方 yum 仓库装更省事。再顺便看一眼内核版本uname -rMySQL 5.7 官方 RPM 要求 glibc 版本不低于 2.17CentOS7 的 glibc 一般是 2.17满足要求。如果你的系统是 CentOS7 很早的版本建议先yum update -y升级一下基础库。3. 下载 MySQL5.7 的 aarch64 安装包官方路径与国内镜像3.1 MySQL 官方 Product Archives 的目录结构MySQL 官方社区版下载入口在官方网站的 Product Archives 页面选择 Community Server然后选 5.7 版本、选 Linux - Generic 或者 Linux - Red Hat 系列。ARM64 的 RPM 包通常在 “Linux - Generic” 下会有 aarch64 版本或者在 “Red Hat Enterprise Linux 7 / Oracle Linux 7 (x86_64, 64-bit)” 旁边有一个独立选项 “Red Hat Enterprise Linux 7 / Oracle Linux 7 (ARM, 64-bit)”不同版本的页面布局略有差异。关键点MySQL 5.7 的 ARM64 RPM 包分为两类——RPM Bundle 和单个 RPM。Bunlde 里包含 server、client、common、libs 等多个文件适合离线环境一次性下载单个 RPM 则适合你只需要 server 和 client 的轻量场景。3.2 国内镜像加速下载官方站点的下载速度在部分网络环境下不太稳定这时候可以直接用国内开源镜像站的 MySQL 目录。比如清华大学的镜像站里有 mysql-5.7 的 aarch64 包目录路径类似/mysql/mysql-5.7/往里翻能看到mysql-community-server-5.7.44-1.el7.aarch64.rpm。阿里云镜像也有对应的 mirrors 路径下载速度通常能到几 MB/s。这里要提醒一下国内镜像站同步的 MySQL 版本可能不是最新的小版本但 5.7 系列只要不是太老实际使用差异不大。我这次用的是 5.7.44 版本亲测在 CentOS7 aarch64 上稳定运行。3.3 RPM 包清单解析哪些是必需的无论你是从官方还是镜像下载只要选择 RPM Bundle 或逐个下载核心需要这几个包mysql-community-server服务端主程序mysql-community-client客户端工具mysql-community-common公共文件mysql-community-libs客户端与服务端共享的库文件如果下载的是 Bundle里面还包含mysql-community-embedded-*、mysql-community-test-*这些非必要包不建议安装。只需要把上面四个传到服务器上即可。另外还有一个mysql-community-libs-compat它用于兼容旧的 MySQL 程序如果你系统里没有其他 mysql 客户端残留可以不用装。把它们放在同一个目录下比如/opt/mysql-rpm/。安装时执行cd /opt/mysql-rpm/ yum localinstall -y mysql-community-*.rpmyum localinstall会从 CentOS base 源自动解析并安装依赖比rpm -ivh一个一个装要省心得多。-y参数会自动确认依赖安装避免中途卡住。3.4 与 x86_64 包的关键差异ARM64 的 RPM 包和 x86_64 包在功能上完全一致但内部引用的依赖库不一样。x86_64 包依赖的numactl-libs和libaio在 ARM64 下也有对应的 aarch64 版本CentOS7 的 base 源里都有。如果你在 ARM64 机器上试图强行安装 x86_64 的 RPM 包会直接提示Wrong architecture这个错误其实是个好事能避免你用错包。另外MySQL 5.7 官方在 ARM64 二进制里默认没有启用 jemalloc 内存分配器这个是性能调优层面的问题后面第 6 节我会专门说明。4. 安装过程详解从 yum localinstall 到常见报错4.1 安装顺序与依赖自动解决执行yum localinstall后yum 会先检查当前目录下的所有 rpm 包之间的依赖关系再结合系统已装的包和 base 源里的包生成一个完整的安装计划。通常 MySQL 的四个核心包能自动处理内部依赖你只需要注意的是系统必须先有libaio和numactl-libs否则 yum 会在安装计划里自动从源里拉取也不会有太大问题。安装过程中的输出块很重要最后会有一行Installed: mysql-community-server...之类的提示。如果中间出现Error: Package: mysql-community-server-5.7.44-1.el7.aarch64 (commandline) requires: libaio.so.1()(64bit)说明你系统里缺libaio库。解决方式很简单yum install -y libaio然后再重新执行 localinstall 即可。这个错误是 ARM64 上最常见的x86_64 环境因为很多基础包自带 libaio 反而不容易遇到。4.2 常见报错numa、perl、ncurses 依赖除了 libaio第二常见的报错是Error: Package: mysql-community-server-5.7.44-1.el7.aarch64 requires: numactl-libs这个在 ARM64 服务器上很容易踩到因为部分精简版 CentOS 镜像没有预装 numactl-libs。执行yum install -y numactl-libs即可。还有一个可选依赖是perlMySQL 5.7 的mysql_install_db脚本在旧版本里依赖 perl但 5.7 里已经被mysqld --initialize替代如果你只是用 RPM 安装运行perl 缺失其实不影响。不过为了后续排查脚本方便建议顺手装yum install -y perl ncurses-libs4.3 ARM64 特有的兼容性陷阱QEMU 模拟环境下的 glibc 与 jemalloc如果你是在 QEMU 模拟的 ARM64 环境里安装安装速度会明显比真机慢甚至可能触发 glibc 相关的奇奇怪怪的问题。比如在某些 QEMU 版本下mysqld --initialize会报Invalid argument这实际上是模拟器对 ARM64 的 SVE 指令或部分系统调用支持不完善导致的不是 MySQL 本身的问题。解决办法有两条一是升级 QEMU 到较新版本二是启动参数加-cpu max让它支持更多的 ARM 扩展指令。jemalloc 的问题出现在 5.7.44 的 RPM 包上默认没有启用 jemalloc所以在高并发写入场景下内存分配表现不如 x86_64 平台。这个可以在 my.cnf 中配置malloc-liblibjemalloc.so.1来启用前提是系统已经通过yum install -y jemalloc装好了 aarch64 版本。这一步不是必需的低并发场景下跳过也没问题。4.4 安装完成后的验证安装完成后先确认 RPM 包都装上了rpm -qa | grep mysql预期输出类似mysql-community-common-5.7.44-1.el7.aarch64 mysql-community-libs-5.7.44-1.el7.aarch64 mysql-community-client-5.7.44-1.el7.aarch64 mysql-community-server-5.7.44-1.el7.aarch64再确认 mysqld 二进制是否存在which mysqld /usr/sbin/mysqld到这一步安装环节就算完成了。但是先别急着重启系统MySQL 5.7 的 RPM 包会在你第一次启动服务时自动初始化数据目录而这个初始化过程有很多默认参数坑下一节细讲。5. 初始化数据库与服务配置从 mysqld --initialize 到远程连接5.1 datadir 目录规划与权限MySQL 5.7 的 RPM 包默认数据目录是/var/lib/mysql这个目录在安装 RPM 时会自动创建并且把 owner 设为mysql:mysql。如果你要自定义数据目录比如放到单独的数据盘就必须在初始化之前先改/etc/my.cnf的datadir路径并且手动创建目录、把属主改为 mysql 用户mkdir -p /data/mysql chown -R mysql:mysql /data/mysql chmod 750 /data/mysql记住一个原则datadir 的属主和权限必须正确否则初始化时 mysqld 会直接报Cannot change ownership of the database directory。5.2 mysqld --initialize 的执行细节CentOS7 上安装 MySQL5.7 RPM 后数据目录不会自动初始化需要手动执行mysqld --initialize --usermysql注意这个命令是在 5.7 版本里替代旧mysql_install_db的初始化方式。执行时它会生成一个临时 root 密码放在初始化日志里。如果使用默认 datadir日志路径在/var/log/mysql.log或者/var/lib/mysql/目录下的.log文件中不同版本略有差异。找临时密码的标准姿势grep temporary password /var/log/mysqld.log如果日志里没找到可能因为你改过 datadir 或 log-error 路径那就在你配置的 log-error 路径里找。如果还是没有最稳妥的办法是清空 datadir重新执行一次初始化别嫌麻烦。5.3 找回临时密码的两种方法临时密码通常在初始化输出的最后一行形如[Note] A temporary password is generated for rootlocalhost: xxxxxxxx如果日志被覆盖或者路径不对还有一个保险方法在 my.cnf 中临时加一行skip-grant-tables然后启动 mysqld用空密码进入再重置 root 密码。这个方法在忘记密码时很好用但切记一次操作完成后立即移除该配置并重启服务否则任何人都能免密登录数据库。5.4 my.cnf 关键配置项字符集、大小写敏感、sql_mode修改/etc/my.cnf时我建议把下面这几项写进去可以少踩很多坑[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_general_ci lower_case_table_names1 sql_modeSTRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION port3306 bind-address0.0.0.0lower_case_table_names1表示表名不区分大小写。这个参数在 Windows 上默认是 1在 Linux 上默认是 0。如果你之前开发的业务是部署在 Windows 上的迁移到这台 ARM64 Linux 上时不设置这个参数线上经常会出现 “Table doesnt exist” 这种很诡异的报错。建议提前设成 1但要记住这个参数只在第一次初始化时生效中途改会出大问题。bind-address设为0.0.0.0是为了允许远程连接如果你只在本地访问保持默认的127.0.0.1会更安全。5.5 配置 systemd 服务与开机自启配置完 my.cnf 后启动 MySQL 并设置开机自启systemctl start mysqld systemctl enable mysqld systemctl status mysqld如果状态显示active (running)说明服务起来了。如果启动失败先看状态输出中的错误信息再结合/var/log/mysqld.log排查。启动失败的高频原因有两个一是 my.cnf 里配置了 systemd 无法识别的参数二是 datadir 权限不对或数据目录未初始化。注意一个细节在 CentOS7 aarch64 上systemctl status mysqld显示的主进程路径是/usr/sbin/mysqldPID 是动态变化的。如果看到进程反复重启大概率是初始化失败导致的空指针直接看日志才能定位。5.6 root 密码修改与远程访问授权用临时密码登录后第一件事是修改 root 密码ALTER USER rootlocalhost IDENTIFIED BY YourNewStrongPwd;MySQL 5.7 默认安装了密码校验插件validate_password强制要求密码至少 8 位且包含大小写字母、数字、特殊字符。如果不想用这么严格的策略可以临时降低校验级别set global validate_password_policyLOW; set global validate_password_length6;然后创建远程 root 账号或专用业务账号CREATE USER root% IDENTIFIED BY YourStrongPwd; GRANT ALL PRIVILEGES ON *.* TO root% WITH GRANT OPTION; FLUSH PRIVILEGES;这里要提醒root%可以访问所有库风险很大。生产环境建议创建业务专用账号只授权业务库CREATE USER appuser% IDENTIFIED BY AppUserPwd; GRANT ALL PRIVILEGES ON appdb.* TO appuser%; FLUSH PRIVILEGES;5.7 防火墙与 SELinux 放行远程连接不上时第一反应先检查端口和防火墙ss -tlnp | grep 3306 firewall-cmd --add-port3306/tcp --permanent firewall-cmd --reload如果你开启了 SELinux还需要让 mysqld 监听非默认端口或访问非默认 datadir 时放行setsebool -P mysqld_connect_any 1我这次在 QEMU 模拟环境里没开 SELinux但真机 ARM64 服务器上默认是开启的这一步很容易被漏掉。漏掉后的典型表现是服务正常、端口在监听但远程连接超时或直接被拒绝。6. 部署后的验证与调优建议6.1 验证连接与基础信息全部配置完成后做一轮验证确认安装是真的可用mysql -uroot -p -h127.0.0.1 -P3306登录后执行SELECT VERSION(); SHOW VARIABLES LIKE port; SHOW VARIABLES LIKE character_set_server; SHOW VARIABLES LIKE lower_case_table_names;版本号应为 5.7.44字符集应为 utf8mb4lower_case_table_names 应为 1。如果字符集不是 utf8mb4可以到 my.cnf 里检查配的是不是character-set-server而不是default-character-set后者是老版本写法5.7 里已经不再推荐。6.2 ARM64 下的性能调优提示一个跟 ARM64 直接相关的调优点是内存分配器。MySQL 默认使用 glibc 的 malloc在高并发插入和连接频繁建立的场景下锁竞争会明显影响性能。启用 jemalloc 的方法yum install -y jemalloc然后在 my.cnf 的[mysqld]区域加一行malloc-liblibjemalloc.so.1重启 mysqld 后通过LD_PRELOAD或/proc/pid/maps确认 jemalloc 是否已经加载。这里有个坑5.7.44 的 RPM 包里没有自带 jemalloc 库必须先用 yum 装好否则 mysqld 会报Cant find libjemalloc.so.1直接启动失败。InnoDB 缓冲池大小也建议按内存比例设置典型的 ARM64 服务器内存如果是 8G可以设置innodb_buffer_pool_size2G innodb_log_file_size256M这个值不是越大越好过大会导致 mysqld 启动时预分配内存过久在 QEMU 模拟环境里尤其明显。6.3 日志位置与常见故障排查路径MySQL 5.7 的错误日志默认在/var/log/mysqld.log如果你改过 my.cnf 的log-error则以自定义路径为准。日常运维中最有用的排查命令是tail -n 100 /var/log/mysqld.log journalctl -u mysqld -n 50我这次在 QEMU 模拟环境里遇到过一次“初始化完成后无法连接”的疑案端口正常、进程正常但客户端连接一直报Cant connect to MySQL server on 127.0.0.1。最后查日志发现是/var/lib/mysql/mysql.sock没有写入权限mysqld 起在 socket 监听失败的状态。解决办法是重建/var/lib/mysql目录权限并重新初始化。总结一下ARM64 上的 MySQL5.7 部署难点其实不在安装本身而在“找对 aarch64 的包”和“初始化阶段的各种细节”。只要你能下载到 5.7.44 的 aarch64 RPM 包按顺序装好依赖、配置好 my.cnf、执行 initialize后面就是常规操作了。最后再分享一个小技巧如果你在 QEMU 模拟环境里操作建议把初始化阶段的临时密码先截图保存否则后续重置密码全得靠 skip-grant-tables比较麻烦。
返回列表