简介:这是面向 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.04 | 2.27 | 不能,低于 2.28 |
| Ubuntu 20.04 | 2.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。希望这个习惯也能帮到你。
本文还有配套的精品资源,点击获取