资讯详情

ARM架构MySQL 5.7.44 Docker镜像:编译、部署与避坑指南

📅 2026/10/11 12:36:46 | 华诺云谱 👁 阅读
ARM架构MySQL 5.7.44 Docker镜像:编译、部署与避坑指南
简介面向需要在ARM服务器、开发板及嵌入式设备上运行MySQL的开发者与运维人员提供一份基于Ubuntu 22.04的MySQL 5.7.44 Docker镜像编译包专为树莓派、NVIDIA Jetson等ARM平台设计。资源整体约520MB共5个文件包含Dockerfile、my.cnf配置、初始化与启动脚本以及ARM64镜像压缩包分别用于镜像构建、参数设定、容器初始化和数据库启停结构简洁便于按需改造。已有434人学习。借助该资源使用者可跳过在ARM环境手动编译MySQL及其依赖的繁琐步骤直接构建或导入镜像即可运行容器化数据库并利用Docker的轻量特性在集群中灵活迁移扩展。镜像基于Ubuntu 22.04具备良好的兼容性与稳定性适合物联网应用、轻量级数据库服务及特定硬件平台验证同时便于统一开发、测试和生产环境降低环境差异带来的排错成本。使用时需注意仅在ARM架构环境运行并保持镜像与系统补丁更新以防范安全风险。1. 在 ARM 设备上跑 mysql 5.7.44为什么编译好的 docker 镜像包更省事mysql 5.7.44 的 ARM 版 docker 镜像包在飞腾、鲲鹏、树莓派这类 aarch64 设备上属于“早该有人做好的东西”。我接过好几个内网项目环境里既没有外网权限服务器又是 ARM 架构想跑 MySQL 5.7.44 时官方镜像仓库不一定有对应的 ARM 小版本拉回来的镜像还可能因为 glibc、libaio 这些运行依赖对不上直接在启动时崩掉。自己从源码编译 mysql 5.7.44 又绕不开 boost、cmake、bison 三个组件的版本匹配整套折腾下来大半天就没了。这个包做的就是把源码编译、依赖校准、初始化脚本这些前置工作全部做完交付一个 docker load 就能导入的镜像 tar 文件架构是纯 arm64行为按 5.7.44 校准过。适合两类人ARM 服务器上要尽快把 MySQL 5.7 跑起来的运维以及在 x86 开发机上想复现 ARM 镜像构建流程的研发。2. 镜像包到手后的第一步导入、核对架构与容器启动拿到这个包之后它就是一份镜像归档 tar 文件。和从 registry 拉镜像不同docker load 是纯本地操作不需要网络这一点在内网环境里非常关键。很多离线服务器连 docker hub 根本不通有这份 tar 就能绕开所有网络问题。2.1 用 docker load 导入镜像并确认版本先做导入和确认这两步走完你就知道手上的包到底是不是目标物。docker load -i mysql-5.7.44-arm64.tar docker images | grep mysqldocker load会把 tar 里所有镜像层写入本地 docker 存储完成时会输出Loaded image: mysql:5.7.44-arm64这样的提示。第二行命令是为了确认镜像已经被 docker 识别并且 tag 正确。如果你机器上之前已经存在同名镜像docker load会用 tar 里的内容覆盖同名 tag这一步多留意一下就好。接着用 inspect 确认架构这一步别省尤其是你在 x86 机器上加载它、准备后续 push 到别的服务器时docker image inspect mysql:5.7.44-arm64 --format {{.Architecture}} {{.Os}}正常情况下会输出arm64 linux。如果输出的是amd64说明这个包被重新打过 tag内容已经被替换过了不要去跑生产。2.2 用默认配置把容器跑起来第一次跑我不建议直接挂载自定义 my.cnf先用镜像内置配置把链路走通有问题也方便排查。docker run -d --name mysql57-arm \ -p 3306:3306 \ -v /data/mysql/data:/var/lib/mysql \ mysql:5.7.44-arm64这里-p 3306:3306把容器内 MySQL 端口暴露到宿主机-v /data/mysql/data:/var/lib/mysql把数据目录落到宿主机磁盘上。首次启动时镜像里的 entrypoint 脚本会自动执行mysqld --initialize-insecure初始化数据目录root 用户初始状态是无密码的。启动后看几行日志docker logs mysql57-arm --tail 30看到mysqld: ready for connections就说明初始化成功。然后进入容器确认版本docker exec -it mysql57-arm mysql -uroot -e SELECT VERSION();返回5.7.44并且没有报错说明这个镜像包在你这台机器上已经能用了。注意这一步查到的无密码 root 只是初始化脚本给的临时状态生产环境接下来第一件事就是设密码、建普通账号、关掉 root 远程登录。2.3 数据目录的属主问题要提前处理上一节的docker run里宿主机的/data/mysql/data会被 docker 自动创建但属主是 root。镜像里的 mysqld 进程是以 mysql 用户跑的mysql 用户在容器内的 uid 是 999遇到宿主机目录属主不对时写入会直接报 Permissions denied。常见做法是在宿主机上先把目录属主改掉mkdir -p /data/mysql/data chown -R 999:999 /data/mysql/data999 是官方 MySQL 镜像固定给 mysql 用户的 uid和容器内useradd -r -g mysql mysql分配出来的 uid 是一致的。如果不做这一步mysqld 初始化数据目录时会有概率写不进去表现就是日志里出现failed to create directory /var/lib/mysql/mysql。我第 4 章会专门把这类坑拆开讲。到这里镜像包的基本使用已经闭环了。如果你只是为了跑起来第 2 章就够了。但如果你想确认这个包是不是值得信任、出了奇怪问题怎么排查或者想基于它定制自己的版本下面第 3 章讲的是这个包到底怎么编译出来的。3. 镜像怎么编译出来的基础镜像、cmake 参数与多阶段 Dockerfile这一章完整还原 ARM 版 MySQL 5.7.44 镜像的构建过程。你不一定需要自己跑一遍但了解参数和结构之后遇到镜像行为异常时你知道该往哪里查。整个构建思路是在 x86 机器上模拟出 arm64 环境做“伪本地编译”然后把编译产物拷贝进一个干净的运行镜像。3.1 没有 ARM 真机时用 qemu 在 x86 上准备 arm64 构建环境如果你手里恰好有 ARM 服务器这一节可以跳过去。但没有 ARM 真机的场景很常见开发机是 x86目标机是鲲鹏或者飞腾。要在 x86 上构建 arm64 镜像最省心的方案不是交叉编译而是注册 binfmt 之后跑 arm64 容器。docker run --rm --privileged multiarch/qemu-user-static --reset -p yes docker run --rm --platform linux/arm64 arm64v8/ubuntu:20.04 uname -m第一行把 qemu-user-static 注册进内核的 binfmt 机制让 x86 内核能识别并执行 aarch64 的 ELF 文件。第二行是验证如果输出aarch64说明 arm64 容器已经可以在 x86 机器上正常启动了。这里要说一下为什么不用传统的 aarch64-linux-gnu-gcc 交叉编译。MySQL 的 cmake 配置过程会运行大量探测程序这些程序被编译出来是 aarch64 的交叉编译环境下它们会被直接执行可宿主是 x86探测结果拿到的是 x86 的 CPU 特性和库路径。结果就是配置期不报错编译到一半或者 target 机上运行时报错非常难查。qemu 方案让这些探测程序在模拟层里以 aarch64 身份运行整个编译过程和真机趋近一致。代价是编译速度慢我在 8 核 x86 上用 qemu 跑完整个 MySQL 源码大约花了 50 分钟真机上大概一半时间。3.2 构建容器里的依赖清单进入构建容器装依赖docker run --rm -it --platform linux/arm64 \ -v $(pwd):/mysql-src \ arm64v8/ubuntu:20.04 bash apt-get update apt-get install -y cmake gcc g make bison \ libncurses5-dev pkg-config libssl-dev \ libaio-dev zlib1g-dev wget各依赖的作用分别是gcc/g提供 C/C 编译器bison用于生成 SQL 语法解析器缺失时 cmake 会直接终止libncurses5-dev提供终端库cmake 检测不到 curses 也会中止libssl-dev是 SSL/TLS 支持的头文件和库libaio-dev是 Linux 异步 IO 接口编译期和运行期都需要。注意libaio-dev只是编译期依赖运行时镜像里还需要libaio1这个坑在第 4 章会专门讲。3.3 cmake 配置与编译参数解读MySQL 5.7 的构建系统和 8.0 有差别不少 8.0 的参数在 5.7.44 上是不认识的。下面这组是我验证过的完整配置cd /mysql-src/mysql-5.7.44 mkdir -p build cd build cmake .. \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIX/usr/local/mysql \ -DMYSQL_DATADIR/var/lib/mysql \ -DSYSCONFDIR/etc/mysql \ -DDOWNLOAD_BOOST1 \ -DWITH_BOOST/mysql-src/boost \ -DWITH_SSLsystem \ -DWITH_UNIT_TESTSOFF \ -DWITH_INNODB_MEMCACHEDOFF \ -DWITHOUT_FEDERATED1 \ -DENABLED_LOCAL_INFILE1 \ -DWITH_EXTRA_CHARSETSall make -j$(nproc) make install参数核心逻辑CMAKE_BUILD_TYPERelease让编译器启用 O3 优化这是生产环境必须的Debug 版性能差很多。CMAKE_INSTALL_PREFIX/usr/local/mysql是安装目录后面运行镜像里拷贝的就是这个目录。MYSQL_DATADIR和SYSCONFDIR分别声明数据目录和配置文件目录MySQL 编译期会把这些路径写进二进制后期改动要重新编译。DOWNLOAD_BOOST1让 cmake 自动下载与 5.7.44 匹配的 boost 版本省去手动对版本。离线环境要先下载 boost 源码放到指定目录再把DOWNLOAD_BOOST改成 0。WITH_SSLsystem使用系统 OpenSSL。这里有个容易混淆的点8.0 里是WITH_SSL5.7 也是但 5.7 还认EXTERNAL_SYSTEM_SSL旧写法。用WITH_SSLsystem即可。WITH_UNIT_TESTSOFF关掉单元测试编译省时间。WITH_INNODB_MEMCACHEDOFF、WITHOUT_FEDERATED1是裁剪非必要引擎5.7 的 engine 编译选项在这版已经不像老版本那么折腾了保守起见我只关了明显用不上的。编译完成后验证产物架构file /usr/local/mysql/bin/mysqld输出应该包含ARM aarch64。这一步能确认产物是目标架构而不是构建环境自身的 x86 二进制。3.4 多阶段 Dockerfile 组装运行镜像编译产物不能直接当一个镜像用运行时镜像需要的是最小化的运行环境。我用多阶段构建第一阶段编译第二阶段只拷贝产物FROM arm64v8/ubuntu:20.04 AS builder RUN apt-get update apt-get install -y --no-install-recommends \ wget cmake gcc g make bison libncurses5-dev pkg-config \ libssl-dev libaio-dev zlib1g-dev \ rm -rf /var/lib/apt/lists/* WORKDIR /mysql-src COPY mysql-5.7.44.tar.gz . RUN tar -xzf mysql-5.7.44.tar.gz mkdir -p mysql-5.7.44/build WORKDIR /mysql-src/mysql-5.7.44/build RUN cmake .. \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIX/usr/local/mysql \ -DMYSQL_DATADIR/var/lib/mysql \ -DSYSCONFDIR/etc/mysql \ -DDOWNLOAD_BOOST1 \ -DWITH_BOOST/mysql-src/boost \ -DWITH_SSLsystem \ -DWITH_UNIT_TESTSOFF \ -DWITH_INNODB_MEMCACHEDOFF \ -DWITHOUT_FEDERATED1 \ -DENABLED_LOCAL_INFILE1 \ -DWITH_EXTRA_CHARSETSall \ make -j$(nproc) make install FROM arm64v8/ubuntu:20.04 RUN groupadd -r mysql useradd -r -g mysql mysql \ mkdir -p /var/lib/mysql /var/run/mysqld /etc/mysql \ chown -R mysql:mysql /var/lib/mysql /var/run/mysqld RUN apt-get update apt-get install -y --no-install-recommends \ libaio1 libnuma1 libncurses5 \ rm -rf /var/lib/apt/lists/* COPY --frombuilder /usr/local/mysql /usr/local/mysql ENV PATH/usr/local/mysql/bin:/usr/local/mysql/sbin:$PATH COPY docker-entrypoint.sh /usr/local/bin/ RUN chmod x /usr/local/bin/docker-entrypoint.sh EXPOSE 3306 ENTRYPOINT [docker-entrypoint.sh] CMD [mysqld]第二阶段里的libaio1 libnuma1是 mysqld 运行时的动态库依赖少了任何一个都会在启动时报 cannot open shared object file。libncurses5是 mysql client 工具的终端依赖不加的话mysql -uroot进去会提示终端库缺失。对应的 entrypoint 脚本#!/bin/bash set -e if [ ! -d /var/lib/mysql/mysql ]; then echo Initializing data directory... mysqld --initialize-insecure --usermysql --datadir/var/lib/mysql fi exec $这个脚本的逻辑很直接数据目录里没有 mysql 系统库就执行初始化--initialize-insecure表示 root 初始无密码方便首次进入容器之后你要设密码是业务层面的事。exec $把容器主命令交还给 mysqld保证 mysqld 是 PID 1信号能正确传递。构建命令在 Dockerfile 同级目录执行docker build -t mysql:5.7.44-arm64 . docker save mysql:5.7.44-arm64 -o mysql-5.7.44-arm64.tardocker save出来的 tar 就是你要分发的镜像包。4. 避坑与常见问题编译和首启最容易翻车的五个点这一章的坑一部分是我在编译阶段踩的一部分是拿这个镜像部署到不同客户机时反复遇到的。每一条都是现象、原因、解决三段式你在定位问题时可以对照着看。4.1 编译刚起步就翻车Curses library not found现象cmake 配置阶段直接终止终端输出类似Could NOT find Curses (missing: CURSES_LIBRARY)。原因构建容器里只装了 gcc、make、cmake没装 ncurses 开发库。MySQL 客户端工具和部分配置脚本依赖 curses缺失时 cmake 不给任何回旋余地。解决Ubuntu 20.04 里安装libncurses5-dev装完重新跑 cmake。注意 Debian 11 和 Ubuntu 22.04 的libncurses-dev包名、版本路径都和 20.04 不同如果换基础镜像这句要跟着换。4.2 交叉编译产物在目标机上跑不起来gcc 探测脚本的坑现象在 x86 上用交叉编译器编译出的 mysqld拷贝到 ARM 服务器上执行时进程直接崩溃或者报 illegal instruction没有任何日志。原因前面 3.1 说过MySQL 的 cmake 会运行大量探测程序来检测 CPU 特性、指令集、库路径。交叉编译环境下这些 aarch64 探测程序被拿到 x86 宿主上执行拿到的是 x86 的特性值。编译出来的代码里可能混入了与目标机不匹配的指令。解决放弃传统交叉编译用 qemu-user-static 方案。执行完docker run --rm --privileged multiarch/qemu-user-static --reset -p yes之后arm64 容器里的编译就是一套“伪本地编译”探测程序通过模拟层运行时行为与真机一致。4.3 mysqld 起不来libaio.so.1 找不到现象容器启动后秒退docker logs看到error while loading shared libraries: libaio.so.1: cannot open shared object file。原因libaio 是编译依赖也是运行依赖。构建容器里装了libaio-dev所以编译过了但运行镜像只拷贝了/usr/local/mysql目录动态库是系统层的拷贝不进去。解决运行阶段的基础镜像里单独装libaio1和libnuma1。这也是为什么我在 3.4 的 Dockerfile 第二阶段单独写了那行apt-get install libaio1 libnuma1这一行当时是血泪经验换来的。4.4 挂载自定义 my.cnf 后报 unknown variable现象docker run 时挂了宿主机准备好的 my.cnf容器启动失败日志里一连串unknown variable mysqlx1、unknown variable binlog_expire_logs_seconds。原因很多现成的 my.cnf 模板是从 MySQL 8.0 或者 Percona 那边拷来的参数名在 5.7.44 上根本不存在。5.7 的参数解析器遇到未知变量会直接拒绝启动不会跳过。解决确认手头参数确实是 5.7 支持的。我自己习惯的做法是不确定的参数先加loose-前缀例如loose-binlog_expire_logs_seconds86400。loose-前缀是 MySQL 专门为兼容多版本配置设计的遇到不认识的参数会忽略而不是报错。但这只是过渡手段生产环境建议还是把参数表对着 5.7 官方文档核一遍。4.5 初始化时报 Permission denied数据目录属主现象宿主机挂载了数据目录容器首次初始化时日志报failed to create directory /var/lib/mysql/mysql或者直接Permission denied。原因mysqld 以 mysql 用户运行镜像内 mysql 用户的 uid 是 999宿主机挂载目录属主是 root跨容器写数据时 uid 不匹配就被拒绝。这跟 2.3 节说的是同一件事在不需要挂载自定义配置的简单场景里很多人会漏掉。解决宿主机执行chown -R 999:999 /data/mysql/data。如果你用的是别的 uid 构建的镜像先docker exec -it container id mysql查 uid再按实际值改。5. 验证镜像包能不能用版本、位数与性能三个命令镜像加载、容器启动这些基本动作做完之后我习惯再用三个维度确认这个包真的是“可信任的 ARM 版 5.7.44”而不是启动成功就完事了。先确认架构和产物文件docker image inspect mysql:5.7.44-arm64 --format {{.Architecture}} {{.Os}} docker cp mysql57-arm:/usr/local/mysql/bin/mysqld /tmp/mysqld file /tmp/mysqld第一条输出arm64 linux。第二条把 mysqld 从容器里拷出来第三条在主机的file命令下确认它是ELF 64-bit LSB executable, ARM aarch64。如果生产环境是鲲鹏 920 或者飞腾 FT-2000 这一代处理器跑一下这段能省后面很多怀疑。然后是版本正确性的硬核验证docker exec -it mysql57-arm mysql -uroot -e SELECT VERSION(), version_comment;输出应该是5.7.44加(MySQL Community Server (GPL))。到这里版本、架构都确认了。最后做一个性能摸底。MySQL 自带mysqlslap压测工具不需要额外装 sysbenchdocker exec -it mysql57-arm mysqlslap -uroot \ --concurrency20 --iterations3 \ --number-int-cols5 --number-char-cols5 \ --auto-generate-sql --engineinnodb这个工具会自动生成压测 SQL 并返回平均耗时。耗时稳定说明编译优化生效了可以放心切流量。如果耗时波动异常先查innodb_buffer_pool_size和innodb_log_file_size这俩参数对 ARM 平台的性能影响最大。顺手给出一个适合 ARM 服务器起步的 my.cnf 参考[mysqld] user mysql datadir /var/lib/mysql socket /var/run/mysqld/mysqld.sock pid-file /var/run/mysqld/mysqld.pid character-set-server utf8mb4 collation-server utf8mb4_general_ci default-storage-engine InnoDB innodb_buffer_pool_size 512M innodb_log_file_size 256M skip-name-resolve max_connections 500utf8mb4相比 5.7 默认的utf8能完整存下四字节表情符号现在新库直接就上 utf8mb4。bufffer_pool_size按物理内存的四分之一起步内存少就降到 256M。这套验证流程走完之后我对这个镜像包的信任度才算拉满。从那以后我每次拿到 ARM 架构的 MySQL 镜像包都会强制走一遍docker image inspect加file确认架构再启动这个习惯帮我拦下了不止一次用错架构包的事故。镜像和配置都确认无误之后再把它纳入自己的镜像仓库做分发后续交付就踏实了。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑