news 2026/10/13 1:37:34

ARM平台手工部署MySQL 5.7:预编译包安装与避坑全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ARM平台手工部署MySQL 5.7:预编译包安装与避坑全指南

简介:这是面向 64 位 ARM 架构(AArch64)的 MySQL 5.7.32 二进制安装包,专为 glibc 2.28 的 Linux 环境准备,适合在树莓派、ARM 服务器等平台上快速部署数据库。压缩包总大小约 510 兆,内含一万四千八百余份文件,除了 mysqld、mysql_install_db、mysql_secure_installation 等核心程序外,还大量包含测试用例、结果文件、配置模板、头文件、动态库和证书,类型覆盖 test、result、cnf、inc、so、pem 等,并收录了 binlog 示例数据,为安装、初始化、功能验证与排错提供了完整的素材。目前已有 1418 人学习下载。使用这份包可免去源码编译的繁琐流程,解压后即可初始化并配置 MySQL,尤其适合 ARM 平台上的数据库运维人员或需要快速搭建测试环境的中高级学习者;借助自带测试集也能直观理解 5.7.32 在 InnoDB 并发、JSON 支持、查询优化等方面的改进。整体目录结构完整,按功能模块划分清晰,便于按需提取配置模板或头文件,也能作为后续环境基线升级的参考。

1. 为什么要在 ARM 平台手工装 MySQL 5.7:从一次生产环境迁移说起

前段时间接手一个迁移任务:业务系统要迁到 ARM 架构的服务器上,数据库要求 5.7 版本。原机跑的是 MySQL 5.6,数据量和查询模式都比较老派,直接升 8.0 风险不小。结果翻遍了发行版软件源,ARM 仓库要么只有 MySQL 8.0,要么还是 5.5,中间缺了一大截。后来同事从官方归档里找到这个针对 aarch64、glibc 2.28 的预编译包mysql-5.7.32-linux-glibc-2.28-aarch64.tar.gz,用起来才算走上正路。这篇文章就是记录我拆解这个包、落地部署的全过程。适合手里有 ARM 服务器、又必须用 MySQL 5.7 的开发者,也适合那些不想费劲编译源码的人——预编译包省去交叉编译的时间,但前提是搞懂它带来的几个硬约束:glibc 版本、路径规划、权限处理。这些坑不提前踩一遍,很容易在初始化那一步被卡死。

2. 安装前检查:glibc 版本、依赖库与解压路径

2.1 确认操作系统与 glibc 版本是否匹配

这个包的文件名里写死了glibc-2.28,意思是它链接到的是 glibc 2.28 的符号版本。也就是说系统里的 glibc 必须大于等于 2.28,否则动态链接器会直接报GLIBC_2.28 not found。我见过有人拿到包就往 ARM 服务器上扔,结果启动时一脸懵。

先看系统发行版和 glibc 版本:

cat /etc/os-release ldd --version | head -n1

常见发行版对应关系:

系统版本glibc 版本能否直接跑
Ubuntu 18.042.27不能,低于 2.28
Ubuntu 20.042.31可以
CentOS/Debian 自编译取决于实际需要ldd --version确认

如果 glibc 版本不够,两个选择:升级系统组件(有风险,不推荐在旧生产环境乱动),或者找对应更旧 glibc 的 MySQL 二进制包。我在模拟项目X里用的是 Ubuntu 20.04,所以直接通过。

2.2 解压到指定目录与软链接规划

预编译包解压后是一个完整目录,里面包含了 bin、lib、share 等子目录。我一般习惯把它放到/usr/local/mysql,并做软链接指向具体的版本目录,这样将来升级只需要换软链接。

tar -xzf mysql-5.7.32-linux-glibc-2.28-aarch64.tar.gz mv mysql-5.7.32-linux-glibc-2.28-aarch64 /usr/local/mysql-5.7.32 ln -s /usr/local/mysql-5.7.32 /usr/local/mysql

这里把版本目录保留原名,再用/usr/local/mysql这个不带版本号的路径作为实际使用路径。后续的basedir统一指向/usr/local/mysql,就不会在配置里到处写版本号。另外,tar 包内的目录名通常和文件名一致,解压时最好先ls确认一下再移动,避免多出一层嵌套目录。

2.3 创建 mysql 用户与目录权限

MySQL 的 mysqld 进程出于安全考虑,不建议用 root 直接跑。预编译包本身不带任何用户配置,需要手动建一个无权登录的系统用户。

groupadd mysql useradd -r -g mysql -s /sbin/nologin mysql mkdir -p /data/mysql chown -R mysql:mysql /data/mysql

注意,数据目录我单独放到了/data/mysql,没有放在安装目录下面。这样做的好处是:将来升级 MySQL 安装包时,数据目录可以原样保留,不会被误删。另外,/data/mysql的父路径/data也需要保证 mysql 用户可访问,否则初始化时权限检查照样会翻车。

3. 初始化数据目录与启动配置:my.cnf 与 systemd 管理

3.1 编写最小可用的 my.cnf

解压后的包不提供现成的 my.cnf,只有一份 my-default.cnf 模板。不要偷懒,直接写一个适合 ARM 环境的最小配置即可。注意 ARM 服务器的磁盘和内存配置差异很大,先保守设置,后面再调。

[mysqld] basedir=/usr/local/mysql datadir=/data/mysql socket=/tmp/mysql.sock pid-file=/data/mysql/mysqld.pid port=3306 user=mysql log-error=/var/log/mysql/error.log character-set-server=utf8mb4 collation-server=utf8mb4_general_ci skip-name-resolve max_connections=200 innodb_buffer_pool_size=1G

这里解释几个容易忽略的点:

  • socket和pid-file路径要保证 mysqld 进程能写入,尤其 pid-file 放在 datadir 里,别顺手放到只读目录。
  • log-error的父目录必须存在并属于 mysql 用户,否则初始化阶段写不了日志,报错信息还看不到。
  • skip-name-resolve在 ARM 生产环境建议加上,避免每次连接都做 DNS 反向解析,延迟会明显缩短。
  • character-set-server需要写成 utf8mb4,不是 utf8,5.7 默认的 utf8 其实编码不完整。

3.2 初始化数据目录

5.7 与 5.6 的最大区别之一,就是数据目录不能靠mysql_install_db一条命令完事,官方推荐用mysqld --initialize。在 ARM 平台上跑初始化时,务必显式指定--user=mysql,否则进程可能尝试以当前 shell 身份写入文件。

mkdir -p /var/log/mysql chown mysql:mysql /var/log/mysql /usr/local/mysql/bin/mysqld --initialize-insecure \ --user=mysql \ --basedir=/usr/local/mysql \ --datadir=/data/mysql

用--initialize-insecure而不是--initialize,原因是后者会生成一个随机 root 临时密码,存在 log-error 里,部署时还得去翻日志,非常不方便。--initialize-insecure会生成一个无密码的 root 账号,只允许本机 socket 登录,接下来可以马上修改密码。如果是从官方文档抄命令,注意--initialize-insecure前面不能加mysqld_safe,那是老版本的玩法。

3.3 配置 systemd 服务

初始化完成后,直接把 mysqld 加入 systemd 管理,比手工mysqld_safe &更可控。

cat > /etc/systemd/system/mysql.service <<EOF [Unit] Description=MySQL Server 5.7.32 After=network.target [Service] Type=forking PIDFile=/data/mysql/mysqld.pid ExecStart=/usr/local/mysql/bin/mysqld --daemonize --pid-file=/data/mysql/mysqld.pid Restart=on-failure LimitNOFILE=65535 [Install] WantedBy=multi-user.target EOF

这里有个细节:Type=forking配合--daemonize,让 mysqld 自行后台化,systemd 通过 PIDFile 跟踪主进程。如果省略--daemonize,systemd 会认为进程没有 fork 而报错。配置完成后:

systemctl daemon-reload systemctl start mysql systemctl enable mysql

检查状态和端口:

systemctl status mysql ss -lntp | grep 3306

到这一步,MySQL 已经跑起来了。接下来最重要的一步是改 root 密码,因为--initialize-insecure留下的 root 没有密码:

mysql -uroot ALTER USER 'root'@'localhost' IDENTIFIED BY '你的强密码'; FLUSH PRIVILEGES;

4. 避坑指南:ARM 环境下 MySQL 5.7 的 5 个典型故障

4.1 启动报错GLIBC_2.29 not found

现象:执行/usr/local/mysql/bin/mysqld时,系统提示/lib/aarch64-linux-gnu/libc.so.6: version GLIBC_2.29 not found。

原因:这个包链接的是 glibc 2.28,但当前系统 glibc 高于 2.28 才能覆盖符号版本。如果系统 glibc 是 2.27,哪怕只差一个小版本,也找不到对应符号。

解决:确认 glibc 版本(ldd --version),低于 2.28 就换 ubuntu 20.04 以上或重新找旧 glibc 的包。不要想着手动替换系统的 libc.so.6,那会直接让系统起不来。从那以后,我每次拿到二进制包第一件事就是检查系统版本,不再盲目解压。

4.2 初始化失败,日志里提示libaio.so.1: cannot open shared object file

现象:mysqld --initialize一闪而过,log-error 里出现 libaio 相关错误。

原因:MySQL 5.7 依赖 libaio 库做异步 IO,但基础镜像里很可能没有安装。

解决:手动安装依赖。在 Ubuntu/Debian 上:

apt-get install -y libaio1 libnuma-dev

在 CentOS/RHEL 上可能是libaio和libnuma。ARM 平台尤其容易漏掉这两个包,因为某些精简镜像只装基础运行库。检查命令:

ldd /usr/local/mysql/bin/mysqld | grep "not found"

4.3 数据目录权限正确,但 mysqld 仍然无法创建 pid 文件

现象:启动时日志说Can't start server: pid file could not be created,但ls -l /data/mysql明明有 mysql 属主。

原因:父目录/data权限不对,mysql 用户没有对/data的执行权限,无法深入到底层创建文件。

解决:给/data添加可执行权限,同时确认路径里没有经过类似/root这样无法访问的目录。修复:

chmod 755 /data chown -R mysql:mysql /data/mysql

这问题困惑了我整整半天,最后发现是上级目录缺失 x 权限。系统日志里往往只报最终目标路径无法写入,不会告诉你是哪一层拦截了。

4.4 root 无法登录:Access denied for user 'root'@'localhost'

现象:初始化用了--initialize,拿到日志里的临时密码后,执行mysql -uroot -p,输入密码却报 access denied。

原因:临时密码在 log-error 里,但终端复制时容易把空格或换行一起带入。还有一种情况是 shell 转义出了问题,密码里的特殊字符被解释掉了。

解决:先把密码写入文件,再用--init-file方式修改密码。比如:

echo "ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPass_2024';" > /tmp/init.sql /usr/local/mysql/bin/mysqld --init-file=/tmp/init.sql \ --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql

修改完成后删除临时脚本文件。注意主库已经在运行的话,要先停掉再带--init-file启动。

4.5systemctl start mysql提示超时,但手工启动正常

现象:用/usr/local/mysql/bin/mysqld --daemonize手工跑没问题,systemd 启动却报 start operation timed out。

原因:Type=forking配置下,systemd 会等待主进程 fork 完成。如果--daemonize和配置里的 PIDFile 路径不一致,systemd 等待超时。

解决:检查 service 文件里 PIDFile 与 my.cnf 中的pid-file是否一致。另外,在 ExecStart 里去掉--daemonize,改用ExecStart=/usr/local/mysql/bin/mysqld并设置Type=simple可以更省事,但如果 mysqld 挂了,systemd 不会自动尝试重启。这个根据你的运维习惯选,我在生产上仍然坚持用Type=forking,因为它与 mysqld_safe 的守护语义更接近。

5. 性能验证与基础调优:确认 MySQL 真的在 ARM 上跑起来

5.1 用 mysqlslap 做一次本地基准测试

验证部署是否成功,不能只靠systemctl status。我习惯用自带工具 mysqlslap 快速压一轮,语法简单且不需要额外安装压测软件。先准备测试库和账号:

GRANT ALL ON *.* TO 'bench'@'localhost' IDENTIFIED BY 'bench123'; FLUSH PRIVILEGES;

然后执行:

/usr/local/mysql/bin/mysqlslap \ --user=bench --password=bench123 \ --host=localhost --port=3306 \ --concurrency=10 --iterations=3 \ --number-of-queries=1000 \ --auto-generate-sql \ --create-schema=test

参数说明:--concurrency=10模拟 10 个并发连接,--iterations=3跑三轮取均值,--number-of-queries=1000控制总查询量。输出里会有一行Average number of seconds to run all queries,看到这个就说明 MySQL 服务正常,而且对当前硬件负载有了基线数据。如果这一轮报连接超时,优先检查防火墙和 my.cnf 里的绑定地址。

5.2 根据 ARM 芯片特点调整关键变量

ARM 服务器在内存带宽和缓存路径上跟 x86 有差异,MySQL 调参不能照搬 x86 那一套。我一般关注几个变量:

SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit'; SHOW VARIABLES LIKE 'max_connections';

innodb_buffer_pool_size建议设置为物理内存的 60%-70%,但不能超过可用内存,因为还有操作系统缓存和连接线程内存。innodb_flush_log_at_trx_commit默认值是 1,安全但是每次提交都刷盘,ARM 平台如果用的是普通 SATA SSD,可以改成 2 降延迟,代价是断电时最多丢一秒事务。max_connections别调太高,ARM 服务器的线程栈占用不小,每个连接默认分配 256KB 内存,200 个连接大约额外消耗 50MB,小内存机器容易直接 OOM。

用sysbench做更复杂的压测也可以,但在 ARM 上编译 sysbench 又是一堆依赖。mysqlslap 对初装验证已经够用,真正性能调优还是要放到业务特征明确之后再做。

6. 把日常备份做成一条命令的坑与技巧

部署完 MySQL 之后,最怕的就是某天误删数据。日常备份我习惯用 mysqldump 加定时任务。先写一个备份脚本:

#!/bin/bash # /usr/local/bin/mysql_backup.sh BACKUP_DIR=/data/backup/mysql DATE=$(date +%Y%m%d_%H%M%S) DB_USER=root DB_PASS='真正的密码' DB_NAME=prod_db mkdir -p ${BACKUP_DIR} /usr/local/mysql/bin/mysqldump \ --user=${DB_USER} --password=${DB_PASS} \ --single-transaction --routines --triggers \ {DB_NAME} | gzip > ${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz find ${BACKUP_DIR} -type f -name "*.sql.gz" -mtime +7 -delete

脚本里两个坑。第一个是--single-transaction,如果你用的是 MyISAM 表,这个参数不生效,备份期间 DDL 会导致数据不一致。MySQL 5.7 默认引擎是 InnoDB,所以只要建表时没指定 MyISAM,就没问题。第二个坑是密码写在命令行里,会被进程列表看到。生产环境建议改用--defaults-extra-file方式,把密码写进一个 600 权限的配置文件中。定时任务加上:

crontab -e 0 2 * * * /usr/local/bin/mysql_backup.sh

恢复时也简单:

gunzip < /data/backup/mysql/prod_db_20260901_020000.sql.gz | /usr/local/mysql/bin/mysql -uroot -p prod_db

用 mysqldump 做备份的缺点是,数据量大时恢复时间很长,而且无法做到精确到秒的位点恢复。但那是在没有额外运维系统的前提下,最省心的后悔药。自从有一次误删表,靠凌晨的备份恢复到两小时前的状态之后,我养成了一个习惯:每次给 MySQL 做配置变更前,必然先跑一次备份脚本,确认生成的 gz 文件大小不是 0。希望这个习惯也能帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 1:37:34

空想症与拖延绝症:神经科学视角下的行动启动障碍

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 1:37:34

C语言多线程HTTP服务器实战:基于evhttp的高并发架构设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 1:35:53

ESP32 AEC失效的四大根因与工程级调优指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 1:35:53

Python爬虫实战:用Requests和正则搞定教务系统课表提取

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 1:35:12

C#手写算法与数据结构:性能、内存与生产级落地指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 1:35:04

计算机组成原理运算器习题解析:补码、Booth算法与浮点数运算

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华