MySQL从x86迁移到ARM不是配置问题,而是二进制不兼容:x86编译的mysqld会报Exec format error;必须用aarch64原生包,并严格区分armv7l与aarch64架构,前者需改用MariaDB;Docker部署须显式指定--platform=linux/arm64或使用-arm64v8镜像。

mysql 从 x86 迁移到 ARM 不是配置问题,而是二进制兼容性问题——直接运行 x86 编译的 mysqld 会立刻报 Exec format error,根本起不来。必须用 aarch64 原生构建的 MySQL,且要分清目标设备真实架构是 aarch64 还是 armv7l,后者连官方 ARM64 包都加载不了。
确认真实 CPU 架构,别被“ARM”二字骗了
很多故障源于误判硬件类型:armv7l(树莓派 3B、旧 Orange Pi)和 aarch64(树莓派 4B/5、鲲鹏、飞腾、苹果 M 系列)不兼容同一套二进制包。
执行以下命令交叉验证:
-
uname -m—— 必须输出aarch64才能用 MySQL 官方 ARM64 包 -
file /bin/bash—— 输出中应含AArch64,确认系统本身是 ARM64 可执行格式 -
lscpu | grep "Architecture"—— 辅助看是否为aarch64
若结果是 armv7l,别折腾 MySQL ARM64 包,改用 sudo apt install default-mysql-server(实际安装 MariaDB),它对旧 ARM 兼容性更好,SQL 行为基本一致。
用对安装方式:官方源优先,Docker 必加 --platform
Debian/Ubuntu 上直接 apt install mysql-server 通常失败,因为默认源只提供 amd64 包,会拉不到依赖或装空包。
正确做法是:
- 添加 MySQL 官方 APT 源(如
https://repo.mysql.com/apt/debian/),其aarch64包从 8.0.27 起才正式支持 - Docker 部署时,
mysql:latest默认不含 ARM64 镜像,docker run会静默失败或卡在Waiting for server startup - 必须显式指定平台:
docker pull --platform linux/arm64 mysql:8.0.33,再运行;或直接用带后缀的镜像:mysql:8.0.33-arm64v8 - 自定义 Dockerfile 开头加:
FROM --platform=linux/arm64 ubuntu:22.04
systemd 启动失败?大概率是 libtinfo 版本链接错了
常见错误日志:mysqld: error while loading shared libraries: libtinfo.so.5: cannot open shared object file
这不是缺失库,而是 MySQL 二进制包硬编码链接了旧版 libtinfo.so.5,但 Ubuntu 22.04+/Debian 12 已升级到 libtinfo.so.6。
修复方法:
- 创建软链(临时绕过):
sudo ln -s /usr/lib/aarch64-linux-gnu/libtinfo.so.6 /usr/lib/aarch64-linux-gnu/libtinfo.so.5 - 更稳妥的做法是编译安装时禁用静态链接:
-DWITH_LIBEDIT=OFF,避免 libedit 绑定旧版 tinfo - 若用官方二进制包,检查其
ldd $(which mysqld) | grep tinfo,确认是否真依赖.so.5
源码编译需绕开 ARM 不兼容项
在 ARM 服务器上自己编译 MySQL(例如需启用国密 SM4 或调试符号),cmake 阶段容易踩坑:
默认检测 host 工具链可能误判架构,或启用 x86 专属优化导致崩溃。
- 强制指定目标架构:
-DCMAKE_SYSTEM_PROCESSOR=aarch64 - 禁用 BoringSSL(ARM 上有未适配分支):
-DWITH_SSL=system,不要用-DWITH_SSL=bundled - 跳过 libedit:
-DWITH_LIBEDIT=OFF(ARM 平台下其静态链接易出错) - 只编译客户端库时加:
-DWITHOUT_SERVER=ON,并确保工具链是aarch64-linux-gnu-gcc,不是arm-linux-gnueabihf- - gcc 版本必须 ≥ 10,低版本在
__int128和原子操作内建函数上有 ARM 兼容问题
mysqld --version 显示版本号还不够,得 file $(which mysqld) 看输出是否含 AArch64,否则后面所有调优、复制、备份都建立在错误前提上。


















