简介面向需要在ARM64aarch64Linux环境中部署MySQL的开发者与运维人员这是MySQL 5.7.32预编译二进制包依赖glibc 2.28适配树莓派4及各类ARM服务器免去源码编译的繁琐流程。包内共14882个文件以test测试用例、result结果集、opt优化模块、inc头文件及cnf配置为主另有so动态库、pem证书、mysql_install_db、mysql_secure_installation等初始化与安全脚本整体约510.16MB可直接解压后初始化使用或用于二次编译参考。已有1418人学习下载。大量测试与结果文件构成完整回归测试集可快速验证该版本在ARM平台的兼容性配置优化模块和InnoDB、JSON支持等特性便于根据低内存环境调整参数充分释放ARM设备性能。1. 拿到 mysql-5.7.32-linux-glibc-2.28-aarch64.tar.gz 之后真正的问题是“怎么落地”在一台 ARM64 服务器上装 MySQL很多人第一反应是“找个 aarch64 的 rpm/deb 自动装”。但纯内网或定制系统里yum 源不一定有 5.7就算有glibc 版本也可能对不上。mysql-5.7.32-linux-glibc-2.28-aarch64.tar.gz 是官方发布的 Linux 通用二进制包文件名把三个关键条件写在脸上版本 5.7.32、运行平台 aarch64、动态链接要求 glibc 2.28 或更高。它不需要本地编译解压、初始化数据目录、启动 mysqld 就能跑适合自己掌控目录结构和升级节奏的运维场景。适合谁适合手头是鲲鹏、飞腾或其他 ARM64 芯片又没时间跟编译依赖纠缠的工程师。这篇按实际落地顺序把从解压到调优、再到排错的完整路径走一遍每步都给可直接抄写的命令和参数。2. 解压与最小配置把 mysql-5.7.32-linux-glibc-2.28-aarch64.tar.gz 变成可用实例2.1 解压前先做三件事确认架构、glibc 版本、磁盘规划先别急着 tar。常见翻车是“看着是 aarch64 包但系统 glibc 太老”或者“解压出来空间不够”。这三件事顺手做掉后面少一半麻烦。# 1. 确认芯片架构结果必须是 aarch64 或 arm64 uname -m # 2. 确认 glibc 版本结果应不低于 2.28 ldd --version | head -n 1 # 3. 确认 /usr/local 和数据盘有空间 df -h /usr/local /datauname -m 输出如果是 x86_64这个包装不了现在掉头去下 x86 版本别浪费时间。ldd --version 输出像ldd (GNU libc) 2.28或更高就达标如果是 2.17CentOS 7 默认机型跑起来会直接报 GLIBC_2.28 not found这个坑后面专门说。df -h 既要看程序目录也要看将来数据盘。MySQL 5.7 初始化后光系统库和 redo log 就要 200MB 以上生产数据另算。磁盘规划我一般会把程序包放在 /usr/local/mysql数据目录单独挂到 /data/mysql。好处是升级时换程序目录不影响数据备份也可以单独做。# 创建 mysql 用户和组用于以最小权限运行服务 groupadd mysql useradd -r -g mysql -s /sbin/nologin mysql这里有两个容易被忽略的点。第一mysql 用户不需要登录 shellsbin/nologin 防止别人 su 进去第二如果之前装过 MySQL 残留了 mysql 用户useradd 会报 already exists直接跳过但要确认这个用户的属主和家目录配置是干净的避免数据目录权限张冠李戴。2.2 解压与初始化 data 目录mysqld --initialize 参数怎么给解压用到的 Linux 常用命令只有一条但参数有讲究# 解压到 /usr/local 目录-z 按 gzip 解压-x 解包-f 指定文件名 tar -xzf mysql-5.7.32-linux-glibc-2.28-aarch64.tar.gz -C /usr/local # 去掉版本号目录名路径稳定以后升级替换也方便 mv /usr/local/mysql-5.7.32-linux-glibc-2.28-aarch64 /usr/local/mysqlmv 是不是比软链好我习惯用 mv新版本 tarball 解压后直接替换 /usr/local/mysql路径稳定systemd 单位文件不用每周改。如果你要保留多版本做灰度用ln -s指向具体版本目录也一样区别不大。但不要直接把解压出来的目录名留着后面 my.cnf 里 basedir 带一长串版本号升级时容易漏改。然后写最简 my.cnf。MySQL 5.7 的 tarball 默认不读取 /usr/local/mysql/my.cnf而是按顺序找 /etc/my.cnf、/etc/mysql/my.cnf、$MYSQL_HOME/my.cnf所以把配置放在 /etc/my.cnf 最省事。[mysqld] user mysql basedir /usr/local/mysql datadir /data/mysql socket /tmp/mysql.sock pid-file /data/mysql/mysql.pid log-error /data/mysql/error.log port 3306 server-id 1 [client] socket /tmp/mysql.sock下面创建目录并初始化mkdir -p /data/mysql chown -R mysql:mysql /data/mysql /usr/local/mysql/bin/mysqld --defaults-file/etc/my.cnf --initialize-insecure --usermysql初始化这一步是新手最容易卡住的地方。--initialize-insecure表示生成一个不带密码的 rootlocalhost生成本地免密之后自己 ALTER USER 改密。如果去掉-insecure变成--initialize则会在 error.log 里生成一条随机临时密码日志路径由--log-error指定。前者适合刚上手的测试环境后者更接近生产但第一次登录要 grep 日志很多人找不到密码就重装没必要。逻辑和参数思路mysqld 读的是 --defaults-file 指定的配置但初始化时还会通过命令行参数叠加--usermysql 强制进程降权到 mysql 用户不能用 root 直接初始化否则后续正常启动时权限混乱。datadir 目录必须为空否则报错 “Datadir already exists”如果重新初始化清空 /data/mysql 再跑。还有一个细节基于 glibc 2.28 的包在 aarch64 上初始化时如果系统 namespace 或 seccomp 限制过严可能卡在创建系统表阶段等一会儿没反应先看 error.log 而不是直接 kill。初始化完成后检查一下系统表是否齐全ls -l /data/mysql | head正常情况下应该看到 mysql、performance_schema、sys 三个库对应的目录。如果只有 ibdata1 和 ib_logfile0说明初始化没完成回看 error.log。2.3 启动、连接与 systemd 管理解决 2002 错误的关键初始化完成后先手动启动确认日志没报错再用 systemd 托管# 前台启动错误直接打到当前终端 /usr/local/mysql/bin/mysqld --defaults-file/etc/my.cnf --usermysql --console # 确认进程起来了监听 3306 ss -lntp | grep 3306 # 另开一个终端走本地 socket 登录 /usr/local/mysql/bin/mysql -u root --socket/tmp/mysql.sock首次能登录说明从解压到初始化的链路是通的。之后把它做成服务用 systemd 管理。我用的 unit 是[Unit] DescriptionMySQL Server 5.7.32 Afternetwork-online.target [Service] Typesimple Usermysql Groupmysql ExecStart/usr/local/mysql/bin/mysqld --defaults-file/etc/my.cnf Restarton-failure LimitNOFILE65535 [Install] WantedBymulti-user.target把上面内容存成 /etc/systemd/system/mysqld.service然后执行systemctl daemon-reload systemctl enable mysqld systemctl start mysqld这里有个高频坑Type 的设置。如果你在 ExecStart 里写 mysqld_safe日志里经常看到 PID 找不见或进程反复退出因为 mysqld_safe 会 fork 子进程与 systemd 的 Typesimple 不匹配。直接把 ExecStart 指向 mysqld 二进制Typesimple 才合适。LimitNOFILE 最好显式给MySQL 默认要求 open_files_limit 至少 4161systemd 默认的 1024 会造成 table_open_cache 打不开。遇到ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock先别急着看配置。常见原因有三个实例根本没启动、socket 路径不一致、systemd 的 PrivateTmp 把 /tmp 隔离了。排查顺序是# 1. 有没有进程 ps -ef | grep mysqld # 2. 日志最后 20 行 tail -n 20 /data/mysql/error.log # 3. 配置里的 socket 是否和客户端一致 /usr/local/mysql/bin/mysql -u root -S /tmp/mysql.sock多数时候是第 2 步。error.log 里会有最直接的原因比如 “Cant start server: Bind on TCP/IP port: Permission denied” 说明端口被占用或 SELinux 拦截“Directory /tmp/mysql.sock for socket file doesnt exist” 说明 /tmp 路径异常。用 systemd 的 PrivateTmptrue 会把 mysqld 看到的 /tmp 和外部隔开客户端连不上所以要么关掉 PrivateTmp要么把 socket 放到 /var/run/mysqld 这种持久目录。3. 参数调优与 ARM64 特性my.cnf 里该改什么、不该改什么3.1 内存与并发innodb_buffer_pool_size、max_connections 的 arm64 适用值通用二进制包的问题在于它要照顾全系列 aarch64 CPU既不会像鲲鹏 920 那样用 tuned 调 NUMA也不像飞腾 S2500 那样针对 cache line 优化。因此“改参数”比“重新编译”更划算。你不需要折腾 GCC 和 glibc把内存和并发参数写给 MySQL 就够了。先看决定 MySQL 大半性能的两个参数[mysqld] # 物理内存的 60% 左右8G 内存给 5G16G 给 10G别超过 70% innodb_buffer_pool_size 5G # 缓冲池实例8G 以下建议 116G 以上保持 8 或 16 innodb_buffer_pool_instances 4 # 并发连接数5.7 默认 151读多写少可设 300-600 max_connections 500 # 关闭反向 DNS 解析内网连接不必每次都查名字 skip_name_resolve # MySQL 5.7 默认用 多个文件句柄 per table连接多时把上限抬高 table_open_cache 4096 innodb_file_per_table ON为什么不建议直接把 x86 老机器上的参数抄过来关键在 aarch64 的内存带宽和 NUMA 结构。MySQL 5.7 在 ARM 服务器上跑遇到大并发时最明显的现象是 CPU 使用率不高但响应延迟抖动这是内存分配器在 NUMA 节点间来回访问造成的。常见做法是把缓冲池调得稍微保守一点给操作系统留 30% 以上内存作为 page cache 和临时文件空间InnoDB Buffer Pool 填太满反而会让 redo log 刷盘调度和磁盘 IO 冲突。如果你确认芯片是单 NUMA 节点的小机器可以继续加但上线前最好做一次 sysbench 基础压测。关于 performance_schema5.7 默认开启它会吃掉一部分 CPU 和内存。生产排查慢查询时它有用但如果你只需要一个稳定承载业务的小库显式关闭能省不少资源。这不是 ARM 特有但在核心数少的 ARM 机器上收益更明显。performance_schema OFF但注意关闭 performance_schema 之后一些监控工具依赖 performance_schema 数据会失效比如部分版本的 Prometheus mysqld_exporter 默认查询 performance_schema 里的 wait events。如果监控脚本起不来先看 exporter 是否要求该开关打开。不要为了省内存而把监控链路弄瞎。连接数这块还有一个容易忽略的参数max_connections不是设了就能无脑堆。MySQL 每个连接占用一段线程栈5.7 默认 thread_stack 是 256KB500 个连接约占用 128MB加上 InnoDB 内部并发小内存机器在 ARM 上更容易先打满内存。所以 8G 内存的机器我建议 max_connections 设在 300 左右同时把innodb_thread_concurrency设置为 CPU 核数的 2 倍避免线程过多导致上下文切换开销。设置完可以用下面命令验证/usr/local/mysql/bin/mysql -u root -p -e SHOW VARIABLES LIKE max_connections; SHOW STATUS LIKE Threads_connected;3.2 二进制日志与事务binlog_format、sync_binlog 落地策略很多人把这个包装起来打开 binlog 就完事结果过一段发现磁盘满了才知道 binlog 没有设过期时间。5.7 的 binlog 参数群是落了坑再改就麻烦的一组最好初始化之后就固定。# 必须和实例唯一对应尤其以后要搭主从 server-id 1 # 日志路径要放到数据盘单独目录避免和 socket、error.log 挤在系统盘 log-bin /data/mysql/binlog/mysql-bin # 行级复制主从一致性好不在乎跨机房带宽可用 MIXED 换性能 binlog_format ROW # 每写一个事务就同步 binlog 一次最安全但写盘次数最多 sync_binlog 1 # 日志保留 7 天避免手动清理 expire_logs_days 7binlog_format 的取舍ROW 日志体积比 STATEMENT 大但恢复和数据一致性最好5.7 默认就是 ROW别在没读过文档的情况下改成 STATEMENT。sync_binlog1 配合innodb_flush_log_at_trx_commit1能保证异常断电最多丢一个事务但这会让每个事务都 fsync磁盘弱的机器上写入性能掉一半内网业务写多读少的话可以接受把 innodb_flush_log_at_trx_commit 改成 2减少 redo log 的同步频率但 binlog 建议仍然保持 1。把 binlog 放在单独目录还有一层原因/data/mysql/binlog 挂掉只影响日志不影响 datadir 中的库表文件。恢复时 binlog 可以做起点但库表文件完整性才是底线。若不单独建目录MySQL 也会默认写在 datadir 下出问题时无从分离。下面是常用检查命令# 确认 binlog 参数已生效 /usr/local/mysql/bin/mysql -u root -p -e SHOW VARIABLES LIKE log_bin; SHOW VARIABLES LIKE binlog_format; # 查看当前 binlog 文件 /usr/local/mysql/bin/mysql -u root -p -e SHOW MASTER STATUS;还有一个参数容易被忽略gtid_mode。5.7 支持 GTID 复制建议在初始化之后、搭建主从之前开启。如果已经跑了业务再开 GTID需要额外做配置变更麻烦但不难。单实例可以不开但如果是主从架构GTID 能极大简化 failover 和 binlog 位置查找。ARM 上与 x86 没有区别但国产化项目通常要双机热备预先开好能省很多心。gtid_mode ON enforce_gtid_consistency ON3.3 字符集与排序utf8mb4 和排序规则的选择在 ARM 国产化项目里碰到的第一个业务兼容性问题多半不是性能而是字符集。MySQL 5.7 默认是 latin1如果建库时不指定 utf8mb4后面写入 emoji 或者中文索引排序不对返工成本极高。所以 my.cnf 里一次性固定[mysqld] character_set_server utf8mb4 collation_server utf8mb4_general_ciutf8mb4 支持四字节字符utf8mb4_general_ci 排序比较快但不区分大小写、不处理 Unicode 特殊语言如果业务要求更严格的排序规则可以用 utf8mb4_unicode_ci。这里注意一个经典误区MySQL 的 utf8 其实是 utf8mb3最多存 3 字节建表时写 CHARACTER SET utf8 会造成 emoji 或生僻字写入报错。连接器也要确认环境变量# 确认服务端和客户端字符集一致 /usr/local/mysql/bin/mysql -u root -p -e SHOW VARIABLES LIKE %character%; SHOW VARIABLES LIKE %collation%;同时 JDBC 连接串里补上characterEncodingutf8mb4或utf8。这个参数在 ARM 上没有特殊性但国产系统的应用默认编码多为 gbk不统一的话数据进入 MySQL 后乱码。排错时先查character_set_results再查连接层编码。如果应用侧一时改不了可以在 my.cnf 里加character_set_client utf8mb4但不如应用侧直接规范。如果迁移老库原库是 latin1 或 utf8mb3新库直接改 utf8mb4 会发生字符集转换。常见做法是 dump 前先导出表结构用 sed 替换表定义中的 CHARSETutf8 为 CHARSETutf8mb4再导数据。不要边导边让 MySQL 隐式转换会产生乱码和数据截断。4. ARM64 平台安装 MySQL 避坑5 个最常见翻车点与排查4.1 现象error while loading shared libraries: libaio.so.1执行 bin/mysqld 或 mysql_install_db 时直接报error while loading shared libraries: libaio.so.1: cannot open shared object file原因这个 tarball 是动态链接编译依赖系统的 libaio 库。MySQL 5.7 在 Linux 上使用异步 IO需要 libaio.so.1。精简版系统、纯内网 docker 镜像或最小化安装的系统经常没有。解决用发行版包管理器装 libaio。CentOS/Rocky/麒麟 V10yum install -y libaioUbuntu/Debian/统信 UOSapt install -y libaio1如果机器完全内网没有源先在一台同版本系统上yum install --downloadonly --destdir/tmp/libaio libaio把 rpm 拷进内网后用rpm -ivh安装。这个坑不解决mysqld 都起不来更谈不上后续配置。4.2 现象ERROR 2002Cant connect ... through socket /tmp/mysql.sock初始化后mysql -u root 连接时报错。这里除了 2.3 说的“实例没启动”之外这个包在 systemd 下还多一个原因mysqld 启动被 PrivateTmp 隔离MySQL 写在 /tmp/mysql.sock 的 socket 文件外部客户端看到的 /tmp 是独立的连不上。原因分析systemd 的单元文件里如果开了PrivateTmptrue服务进程的 /tmp 是私有的socket 对外不可见。虽然 mysql 客户端也在同一台机器上但它不共享服务进程的 mount namespace所以访问不到那个 socket。解决在 unit 配置里删除 PrivateTmptrue 或显式设置为 false。也可以把 socket 放到持久化目录如 /var/run/mysqld并把该目录属主改成 mysql。两种方案选第二种更稳因为很多系统会定时清空 /tmp。mkdir -p /var/run/mysqld chown mysql:mysql /var/run/mysqld同时在 my.cnf 里把 socket 改成 /var/run/mysqld/mysql.sock客户端登录时也要用相同路径。4.3 现象/lib/aarch64-linux-gnu/libc.so.6: version GLIBC_2.28 not found解压后执行 bin/mysql 或 bin/mysqld报缺少 GLIBC_2.28甚至说 kernel too old。原因tarball 名里的 glibc-2.28 不是“自带的 glibc”而是“要求系统提供 2.28 以上的 glibc”。CentOS 7 aarch64 版本的 glibc 是 2.17装上必然报缺符号。这不是包坏了是系统太老。解决不要试图用一个 tar 包硬适配。要么升级系统到内置 glibc ≥2.28 的发行版比如 CentOS 8、麒麟 V10、统信 UOS要么换为针对老 glibc 编译的 MySQL 版本。如果你坚持升级 glibc一定要用发行版官方源或 OS 升级工具绝对不能手动替换 /usr/lib64/libc.so.6否则系统中所有命令都会崩连 ssh 都可能起不来。另外x86 平台上常见的 “fatal glibc error: cpu does not support x86-64-v2” 和这里不是一回事aarch64 包不会报 x86-64-v2它只看 glibc 版本。看到类似报错先确认自己是不是拿错包了。4.4 现象初始化时 SSL 证书生成失败或者 root 临时密码找不到执行mysqld --initialize时开启 SSL 但失败日志里出现 ssl error或者初始化完成后 error.log 里没有生成临时密码。原因5.7 默认会尝试用 mysql_ssl_rsa_setup 生成 SSL 证书如果系统 openssl 版本怪、openssl.cnf 指向不对或 datadir 没有写权限这一环会失败但初始化未必中断。临时密码找不到则多半是 log-error 参数没生效或日志写到了 /var/log/mysql 下。解决先手动补生成证书再初始化。进入 mysql 安装目录执行mkdir -p /data/mysql chown mysql:mysql /data/mysql /usr/local/mysql/bin/mysql_ssl_rsa_setup --datadir/data/mysql --usermysql执行成功后再跑mysqld --initialize。如果依然失败用--initialize-insecure跳过临时密码初始化后登录再手动设置密码。临时密码找不到时不要反复执行初始化直接把 --log-error 改为绝对路径比如 /data/mysql/error.log再去 tail 该文件。grep temporary password /data/mysql/error.log如果是空文件大概率是 mysqld 没跑起来回看 4.1 和系统依赖。4.5 现象麒麟 V10 / 鲲鹏环境 systemctl start mysqld 卡死或失败在银河麒麟 V10aarch64上配置好 systemd执行 systemctl start mysqld服务一直处于 Activating或者 10 秒后失败journalctl 看到 timeout。原因ARM64 机器上 MySQL 5.7 初始化时如果 datadir 在机械盘或网络盘刷页恢复会很慢systemd 等不到主进程 READY另外麒麟默认可能开了安全策略mysqld 访问 /data/mysql 会被限制。解决先确认单元文件里的 ExecStart 指向 mysqld 本身不要在 ExecStart 里用 mysqld_safe接着设置systemctl edit mysqld写入[Service] TimeoutStartSec300同时检查 SELinuxgetenforce如果输出 Enforcing先用 chcon 或 audit2allow 处理数据目录的上下文别上来setenforce 0。临时关闭只是为了定位问题生产环境安全策略不能裸奔。再看 /var/log/mysql 或数据盘日志确认 mysql 用户有写权限。卡住时最有用的命令是journalctl -u mysqld -n 50 --no-pager tail -f /data/mysql/error.log这两条日志能区分是权限、端口还是数据恢复问题。权限问题通常是 SELinux 的 denied端口问题会在 error.log 显示 Bind on TCP/IP port超时则通常伴随 “Initialization of buffer pool completed” 之后停顿说明磁盘 IO 太慢把 TimeoutStartSec 调大后观察再决定是否替换磁盘。5. 升级、迁移与日常维护验证这个 tar 包值不值得长期用5.1 验证可用性用 mysql_upgrade 完成一次人工版本保持这个 tar 包最大的价值在于可以离线、免编译地长期部署。要验证它值不值得用我的方法是做一次完整的升级演练而不是只在测试环境启动一下。比如手头这个 5.7.32 包之后要换同系列更高版本步骤是systemctl stop mysqld # 备份数据目录至少包含 ibdata1 和 mysql 库 cp -a /data/mysql /data/mysql.bak.$(date %F) # 替换程序目录保留原目录作为后悔药 mv /usr/local/mysql /usr/local/mysql.5.7.32 tar -xzf mysql-5.7.33-linux-glibc-2.28-aarch64.tar.gz -C /usr/local mv /usr/local/mysql-5.7.33-linux-glibc-2.28-aarch64 /usr/local/mysql # 启动并升级系统表 systemctl start mysqld /usr/local/mysql/bin/mysql_upgrade -u root -pmysql_upgrade 会比对 mysql 库系统表版本补丁不兼容的表结构会报 warning执行完能看到 OK 而不是错误。这比直接重启库更可靠。5.7.32 升 5.7.x 是版本内升级风险低跨大版本到 8.0 前先在测试机跑 MySQL Shell 的 util.checkForServerUpgrade 再做不要在生产直接换包。5.2 备份验证每天确认能恢复而不是能导出针对这个 tar 包最实用的验证手段不是看 binlog 有没有写而是真正做一次恢复。我习惯的备份组合是# 全量备份并记录 binlog 位置 /usr/local/mysql/bin/mysqldump -u root -p --single-transaction --flush-logs --master-data2 --all-databases all.sql大库可以用 xtrabackup小库用 mysqldump二选一不要混用。恢复验证更关键/usr/local/mysql/bin/mysql -u root -p all.sql /usr/local/mysql/bin/mysql -u root -p -e SELECT COUNT(*) FROM information_schema.tables;看表数量是否恢复一致。备份另一个要点是把 /etc/my.cnf 和这个 tarball 的版本号一起归档因为 my.cnf 里如果有未来版本才支持的参数重装时导入会报 unknown variable。到这里基本能判断这个 tar 包适不适合你的环境。我的习惯是在 ARM 纯内网里优先存一份官方 tarball 离线包配合系统自带 libaio能做到不依赖外网、不依赖发行版源的干净部署每次升级都走“替换目录 mysql_upgrade”而不是覆盖安装失败就切回备份目录等于给自己留了后悔药。遇到 glibc 版本不足的机器直接放弃这个包别硬改系统库遇到报错先看 error.log再动配置。希望这些步骤对你也有用。本文还有配套的精品资源点击获取