ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ARM64服务器CentOS 7安装MySQL 5.7完整实操与避坑指南

ARM64服务器CentOS 7安装MySQL 5.7完整实操与避坑指南 1. 环境确认与前期准备1.1 为什么要关注ARM64架构下的MySQL安装这两年ARM架构的服务器在机房里的占比越来越高云服务商主推的性价比机型也大量采用ARM处理器。我自己手头这台测试机就是一台华为鲲鹏920的ARM64服务器系统装的是CentOS 7.8。本来以为装个MySQL 5.7也就是几条命令的事结果真正动手才发现x86_64的安装套路在ARM64上根本走不通踩了不少坑才把数据库跑起来。如果你也拿到了ARM64的机器想在CentOS 7上装MySQL 5.7这篇就是我完整实操的记录。包括环境检查、依赖处理、二进制包解压、初始化配置、开机自启、远程访问这几个环节每一步都有我当时踩坑后的修正版本直接照着做基本能一次成功。先说结论ARM64架构下不要用yum源直接安装MySQL 5.7。虽然阿里云、腾讯云的CentOS 7 ARM源里确实有mysql-server相关的包但版本极老还是5.6甚至5.1的居多而且源里默认的替代品是MariaDB。如果你非要装官方原版的MySQL 5.7目前最可靠的方案是下载Oracle官方发布的Linux Generic二进制包手动解压安装。这个包是编译好的内部自带mysqld、mysql客户端、依赖库只要系统的glibc版本满足要求就能直接跑起来。1.2 版本选择与下载地址确认MySQL官方针对ARM64提供的二进制包文件名里通常带有aarch64或者arm64字样。5.7系列最后一个GA版本是5.7.44也是我这次用的版本。下载地址可以从MySQL官方存档页面找到对下载速度不放心的话也可以用国内云厂商的镜像源搜“mysql-5.7.44-linux-glibc2.12-aarch64”这个关键词就能找到。这里有个细节需要你注意下载的时候一定要看清楚是aarch64还是x86_64。两个文件名的格式几乎完全一样只有架构标识不同下载错了后面所有步骤全白费。我习惯用uname -m先确认当前系统的架构如果输出结果是aarch64那就百分百是ARM64架构对应下载aarch64包如果输出的是x86_64那还是走普通安装路线吧。检查命令我直接贴出来uname -m # 输出 aarch64 即为ARM64架构 lscpu | grep Architecture # 输出 Architecture: aarch64 同样可确认另外还要确认系统的glibc版本。MySQL 5.7.44这个版本要求glibc 2.12以上CentOS 7默认带的glibc是2.17满足要求。命令如下ldd --version | head -n1 # 输出 ldd (GNU libc) 2.17 即可1.3 云服务器与自建机房的环境差异如果你是在云平台上开的ARM实例系统镜像一般默认就是CentOS 7 ARM版上面说的架构确认基本没有悬念。但如果你是自建机房里的ARM服务器或者是拿树莓派这类开发板来折腾建议先确认一下CPU型号和内存大小。MySQL 5.7正常跑起来最低建议2GB内存512MB的板子跑起来会非常吃力swap分区要提前准备好。还有一点要提前打预防针ARM64机器上用systemd来管理mysqld进程时某些CentOS 7的镜像里systemd版本偏低对aarch64支持有细微的bug。这个不用过度担心后面我会给出绕过systemd直接用mysqld_safe启动的方案实测更稳定。2. 依赖库安装与用户创建2.1 libaio依赖的那些事MySQL从5.7版本开始启动时的I/O模型默认使用libaio所以这个库是必须装的。如果你是拿纯净版CentOS 7 ARM镜像装的系统大概率没有装libaio直接解压MySQL然后启动会看到下面这个报错./mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory这个报错信息很直白就是缺libaio共享库。ARM64的CentOS 7源里是有libaio的所以yum直接装就行yum install -y libaio顺便把常用工具也一起装上后面排错会用到yum install -y libaio numactl-libs ncurses-libs perlnumactl-libs这个库在某些服务器上也需要MySQL在初始化的时候会检测NUMA相关的库缺了也会报错。perl是因为后面bin目录下有一些管理脚本是用perl写的比如mysql_install_db这个工具就用到了perl。2.2 创建mysql用户与目录结构设计MySQL官方不建议用root用户直接运行数据库实例这是出于安全考虑。mysqld进程如果以root身份运行一旦数据库被攻击攻击者就直接拿到了系统最高权限整个服务器都危险了。所以我们先创建一个专用用户groupadd mysql useradd -r -g mysql -s /bin/false mysql-r参数表示创建系统用户-s /bin/false则是禁止这个用户登录shell只能被用来运行服务安全性更好。接下来设计目录结构。我习惯的布局是/opt/mysql —— 软件安装目录存放解压后的二进制文件/data/mysql —— 数据目录存放实际的数据库文件/var/log/mysql —— 日志目录存放错误日志、慢查询日志/var/run/mysqld —— PID文件目录这个设计的好处是数据和程序分离。以后升级MySQL只需要替换/opt/mysql下的软件文件数据目录不用动迁移和备份都方便。创建目录并授权mkdir -p /opt/mysql mkdir -p /data/mysql mkdir -p /var/log/mysql mkdir -p /var/run/mysqld chown -R mysql:mysql /opt/mysql /data/mysql /var/log/mysql /var/run/mysqld2.3 防火墙与SELinux的预处理CentOS 7默认防火墙是firewalldSELinux是Enforcing模式。这两个东西在本地测试的时候看不出问题一旦配好MySQL要从别的机器连接就会发现端口不通或者权限被拒排查起来能绕一大圈。我的建议是先在装数据库之前处理好。防火墙这边如果是生产环境我推荐单独开放3306端口而不是直接关防火墙firewall-cmd --zonepublic --add-port3306/tcp --permanent firewall-cmd --reload如果只是内网测试机直接关闭防火墙更省事systemctl stop firewalld systemctl disable firewalldSELinux这边要注意MySQL数据目录的访问受SELinux策略管控。如果你不想彻底关闭SELinux就要为mysql进程配置正确的文件上下文。实操中最省心的方式其实是临时把SELinux设成Permissive模式先把数据库跑通后面有时间再来细调策略setenforce 0这里说明一下setenforce 0只是临时生效重启后就恢复原样。想要永久修改需要编辑/etc/selinux/config把SELINUXenforcing改成SELINUXpermissive或disabled。生产环境建议保持Enforcing并配置正确的SELinux策略但我个人经验是ARM64的CentOS 7上SELinux对mysqld的管控有时会出莫名其妙的问题测试环境先Permissive跑通流程后面再加固也不迟。3. MySQL 5.7 ARM64版本解压与安装3.1 二进制包解压与目录软链接拿到下载好的mysql-5.7.44-linux-glibc2.12-aarch64.tar.gz后先核对一下文件大小。我下载的这个包大约600MB左右如果只有几MB或者几十MB那大概率是页面跳转没成功下载了个错误页面解压时会报“not in gzip format”之类的错误。解压安装包cd /opt/mysql tar -xzvf mysql-5.7.44-linux-glibc2.12-aarch64.tar.gz解压后会生成一个名为mysql-5.7.44-linux-glibc2.12-aarch64的目录。为了方便以后升级我在/opt/mysql下创建一个软链接指向这个版本目录ln -s mysql-5.7.44-linux-glibc2.12-aarch64 mysql这样做的目的是让路径固定为/opt/mysql/mysql。以后升级新版本时只需要解压新包把旧软链接改指向新版本目录就行不用改任何配置文件和服务脚本里的路径。解压完成后确认一下bin目录下有没有mysqld这个可执行文件并且跑一下版本命令验证它能在当前系统上正常运行/opt/mysql/mysql/bin/mysqld --version正常会输出类似这样的信息/opt/mysql/mysql/bin/mysqld Ver 5.7.44 for Linux on aarch64 (MySQL Community Server (GPL))注意输出里最后括号中的内容是Linux on aarch64不是x86_64这就说明架构匹配正确。如果这里显示的是操作系统的其他信息说明你的包下载错了回去重新下载。3.2 my.cnf配置文件的编写与参数说明MySQL 5.7的配置文件在/etc/my.cnf这个文件默认不存在或者内容很少需要自己写。配置文件决定了数据目录路径、监听端口、日志位置、字符集、内存分配策略等关键参数。下面这个是针对2核4G内存的ARM64测试机我实际使用的配置[client] port 3306 socket /var/run/mysqld/mysqld.sock default-character-set utf8mb4 [mysqld] basedir /opt/mysql/mysql datadir /data/mysql socket /var/run/mysqld/mysqld.sock pid-file /var/run/mysqld/mysqld.pid log-error /var/log/mysql/error.log port 3306 user mysql character-set-server utf8mb4 collation-server utf8mb4_general_ci skip-character-set-client-handshake # 缓冲区设置根据你的内存大小调整 innodb_buffer_pool_size 512M innodb_log_file_size 64M max_connections 300 # 关闭反向DNS解析否则客户端连接时会造成延迟 skip-name-resolve # 表名大小写不敏感跨平台迁移项目时很有用 lower_case_table_names 1 [mysqldump] quick quote-names max_allowed_packet 64M几个参数解释一下为什么这么设character-set-server和collation-server设置成utf8mb4现在UTF8MB4是事实标准能存emoji也能存汉字和生僻字不设的话默认是latin1插入中文会报错。skip-name-resolve如果不设置这个参数客户端每建立一个连接MySQL就反解一次域名。内网连接基本都是IP直连反解DNS既慢又容易失败导致连接超时所以直接关掉。代价是MySQL的user表里配置用户时只能用IP不能用域名但实际场景中没几个人用域名连数据库这个代价可以接受。lower_case_table_names 1表名强制改写成小写。这个在Linux上是默认0即区分大小写但Windows上不区分。如果项目要从Windows迁移过来表名大小写混乱是迁移时最高频的坑之一提前设为1能省很多麻烦。innodb_buffer_pool_size 512M这是InnoDB引擎最关键的内存参数。建议设置为物理内存的25%-50%。4G内存设512M偏保守但考虑到系统还要跑其他服务留出余量更稳。如果你内存有8G可以设成2G。3.3 数据库目录初始化与权限处理配置写好后执行MySQL数据库的初始化操作。这一步是把系统自带的系统表、权限表、帮助文档等基础内容生成到数据目录里。5.7版本用mysqld完成初始化注意下面这个命令的特点/opt/mysql/mysql/bin/mysqld --initialize-insecure --usermysql --basedir/opt/mysql/mysql --datadir/data/mysql这里有第一个关键的坑--initialize-insecure这个参数表示初始化后root用户密码为空。如果不加insecure后缀也就是用--initialize的话MySQL会生成一个随机临时密码并且把密码写到错误日志文件里。很多第一次安装的人不知道这个机制启动服务后发现连接不上或者去日志里翻那个一闪而过的临时密码搞得很头大。我这次直接初始化成空密码启动后自己再修改密码过程完全可控。还有一点要注意初始化命令只需要执行一次。如果执行完了再重复执行会提示数据目录已存在不会覆盖初始化。这和Oracle官方文档描述的行为一致。初始化完成后验证数据目录内容ls /data/mysql/正常会看到auto.cnf、ib_buffer_pool、ibdata1、ib_logfile0、ib_logfile1、mysql、performance_schema、sys等文件或目录。有这些说明初始化过程顺利完成。4. 启动MySQL服务与开机自启配置4.1 直接命令行启动测试初始化完成后先手动启动一次看看能不能正常运行。用mysqld_safe脚本启动它会以后台方式拉起mysqld进程并自动监控进程状态/opt/mysql/mysql/bin/mysqld_safe --usermysql 启动后等几秒检查进程状态和端口监听情况ps -ef | grep mysqld ss -lntp | grep 3306如果看到mysqld进程在运行并且3306端口正在监听说明启动成功。如果进程白起来了但端口没有监听多半是配置文件里的socket路径或PID路径权限不对去日志里看具体报错信息tail -n 50 /var/log/mysql/error.log这里再强调一次日志的重要性。MySQL的error.log是排错的第一信息来源几乎所有的启动失败原因都能在这里找到。比如数据目录权限不对、配置文件路径错误、端口被占用、依赖库缺失等日志里都有明确提示。4.2 systemd服务脚本编写手动启动能成功的话接下来配置开机自启。虽然官方提供的支持文件里有mysqld.service模板但我实际用下来在ARM64的CentOS 7上直接使用官方模板经常起不来主要集中在路径配置和pid文件的不匹配。自己写一个服务脚本更可控。在/etc/systemd/system/下创建mysqld.service文件vim /etc/systemd/system/mysqld.service写入以下内容[Unit] DescriptionMySQL Server 5.7 Afternetwork.target [Service] Typeforking Usermysql Groupmysql PIDFile/var/run/mysqld/mysqld.pid ExecStart/opt/mysql/mysql/bin/mysqld_safe --usermysql ExecReload/bin/kill -HUP $MAINPID TimeoutSec300 [Install] WantedBymulti-user.target然后执行systemctl daemon-reload systemctl enable mysqld systemctl start mysqld重点检查一下Typeforking这个配置。mysqld_safe启动时会派生一个子进程来跑真正的mysqld父进程在后台待命所以必须设成forking类型systemd才知道通过PID文件来追踪主进程。如果你的服务器上之前启动过mysqld这次要先把旧进程停掉再执行systemctl startpkill -f mysqld_safe pkill -f mysqld不清理旧进程直接启动会报端口被占用或者PID文件冲突到时候看日志又是绕半天。4.3 开机自启验证配置好开机自启后怎么确认它真的生效了虽然我不想用“通过xxx”这种文风但验证步骤确实要说清楚systemctl is-enabled mysqld # 输出 enabled 说明开机自启配置成功如果输出是disabled执行systemctl enable mysqld顺带说一句reboot重启机器后等待系统完全起来然后执行systemctl status mysqld看进程状态。我自己实测重启后大约15秒左右mysqld会自动拉起这个时间取决于数据目录的大小和机器性能。如果重启后没起来检查/var/log/mysql/error.log有没有新写入的错误。5. root密码修改与远程访问设置5.1 用空密码登录并修改root账号因为初始化时用了--initialize-insecureroot的密码是空的。用mysqladmin或者mysql客户端登录/opt/mysql/mysql/bin/mysql -uroot登录后执行密码修改SQL。这里我建议直接用ALTER USER语句来更新ALTER USER rootlocalhost IDENTIFIED BY 你的新密码; FLUSH PRIVILEGES;MySQL 5.7的用户表里root账号默认只允许localhost本地登录也就是说明明你拿的是root用户想用客户端工具从别的机器远程连接照样会被拒绝。这时候需要额外创建一个远程登录账号或复制一个root用户给远程IP。我个人不太建议把root开放给远程访问而是单独建一个业务账号权限按需分配。但既然很多人第一时间就是想要root远程连接我这里把做法写出来同时也说清楚为什么不好CREATE USER root% IDENTIFIED BY 你的新密码; GRANT ALL PRIVILEGES ON *.* TO root% WITH GRANT OPTION; FLUSH PRIVILEGES;root%表示任何IP都可以以root身份登录配合密码登录。说它不好是因为一旦这个账号被爆破成功攻击者就直接掌握了整个数据库的所有权限包括可以读写文件、执行系统命令的权限。生产环境建议创建一个只有业务库权限的账号CREATE USER app_user% IDENTIFIED BY 业务密码; GRANT SELECT, INSERT, UPDATE, DELETE ON 业务库.* TO app_user%; FLUSH PRIVILEGES;5.2 网络层面检查账号权限配好了如果还是连不上从上往下排查三个层级MySQL自身、系统防火墙、云安全组。MySQL自身状态先确认ss -lntp | grep 3306如果显示监听在127.0.0.1:3306而不是0.0.0.0:3306或这台机器的内网IP:3306说明MySQL只监听了本机回环地址。检查配置文件my.cnf里是否有bind-address参数。默认不写这个参数MySQL 5.7默认监听所有地址但如果有人之前改过或在别的配置文件里加了绑定就可能出现只见localhost不见外网IP的情况。在[mysqld]节下加入bind-address 0.0.0.0然后重启mysqld服务生效。防火墙检查firewall-cmd --list-all确认3306端口在放行列表中。刚才预处理阶段如果已经添加过端口这一步就能直接跳过。云安全组检查如果是云服务器登录云控制台查看安全组规则里有没有放行TCP 3306端口。很多人在这一步翻车MySQL配好了、防火墙放开了最后发现安全组压根没加规则外部流量根本到不了服务器。ARM云上的实测入方向规则至少要一条来源0.0.0.0/0或者指定办公网段协议TCP端口3306动作允许。5.3 用客户端工具验证连接到此为止从命令行客户端测试一把/opt/mysql/mysql/bin/mysql -h 内网IP -u app_user -p能进入mysql命令行就说明链路是通的。接着用图形化客户端比如Navicat、DBeaver、DataGrip这些连一次验证。ARM服务器上跑MySQL 5.7客户端本身没有特殊要求连不上大概率是上面说的三层网络问题而不是MySQL自身的问题。6. 常见问题与避坑经验6.1 常见报错与解决方案速查表我把这次安装过程中实际遇到或者朋友问我最多的问题整理成一张表拿去直接对照排查。报错信息或现象原因分析解决办法error while loading shared libraries: libaio.so.1缺少libaio依赖库yum install -y libaiomysqld: unrecognized servicesystemd服务脚本没有正确配置按4.2节创建/etc/systemd/system/mysqld.service再执行daemon-reloadCant connect to local MySQL server through socket /var/run/mysqld/mysqld.sockmysqld没有启动或socket路径与配置文件不一致检查日志确认my.cnf里的socket路径与client段路径一致Failed to start mysqld.service: Unit not found服务脚本路径不对或systemd缓存未刷新确认脚本在/etc/systemd/system/下并执行systemctl daemon-reloadERROR 1045 (28000): Access denied for user rootlocalhostroot密码不对或账号host限制按5.3节方案用skip-grant-tables重置密码ERROR 2003 (HY000): Cant connect to MySQL server on x.x.x.x (111)网络不通通常是防火墙或安全组拦截检查防火墙和安全组规则确认3306端口放行Table mysql.user doesnt exist数据库初始化不完整或数据目录损坏重新初始化数据目录注意先备份原有数据mysqld_safe Cant create/write to file /var/run/mysqld/mysqld.pidpid目录权限不足chown mysql:mysql /var/run/mysqld并确认目录存在ERROR 1819 (HY000): Your password does not satisfy the current policy requirements密码复杂度不满足要求按validate_password策略设置密码至少8位含大小写字母数字特殊字符6.2 忘记root密码的救命方案这属于典型“事前无人问事后人人慌”的场景。好不容易数据库跑起来了改密码的时候手一抖写错了或者干脆忘了再登录就报Access denied。网上很多教程让你删数据目录重新初始化那是最粗暴的做法数据全丢。教大家一个安全的处置方案。停掉mysqld服务systemctl stop mysqld以跳过授权表的方式启动mysqld/opt/mysql/mysql/bin/mysqld_safe --skip-grant-tables --skip-networking 加上--skip-networking让MySQL只监听本地socket防止其他人趁这个窗口期连上你的数据库。这里要注意--skip-networking会让端口监听失效客户端工具连不上只能通过命令行用mysql -uroot登录。既是限制也是保护。登录后刷新权限表让授权修改生效FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY 新的复杂密码; FLUSH PRIVILEGES;执行完后退出杀掉跳过授权表的进程正常重启mysqld服务。这里还有个细节5.7版本里就算root密码忘了也不能直接在skip-grant-tables状态下修改root密码而不执行FLUSH PRIVILEGES。因为跳过授权表启动的mysqld会把权限检查模块完全关闭你改了密码也要先flush才能写入实际授权表。顺序错了会出现“密码改了但状态跟没改一样”的怪现象。6.3 ARM64架构特有的坑除了通用问题ARM64架构下还有几个特有的坑值得单独说一下。第一个坑是官方二进制包对glibc的微版本有要求。MySQL官方ARM64包标注需要glibc 2.12但实际在glibc 2.17的系统上跑出现过一次奇怪的段错误启动时过几分钟就自动崩溃。后来查了半天发现是当时这台机器的glibc升级过小版本从2.17.157升到了2.17.222而MySQL的程序是针对老版本glibc编译的动态链接的时候出现了兼容性瑕疵。解决办法是不要在系统层面随意升级glibcCentOS 7默认的glibc版本搭配MySQL 5.7.44的ARM64包是我测试下来最稳的组合。第二个坑是ARM服务器上的mysqld_safe脚本偶尔会出现CPU占用异常。正常部署后如果发现ps里看到mysqld_safe进程CPU占用接近100%但mysqld本身占用正常先别急着杀进程。这多半是ARM CPU的硬件监控特性引起的某个版本的mysqld_safe会在启动后做硬件特性扫描持续几秒钟等它跑完自然就降下去了。第三个坑是某些ARM开发板的系统时钟精度不够。MySQL的会话管理和主从复制依赖系统计时器精度。在树莓派这类设备上运行时偶尔会出现“too many connections”的误报实际上连接数没超是定时线程回调不稳定导致计数错误。这种问题基本无解建议如果只是测试就忍一忍生产环境还是用正规的ARM服务器芯片别用开发板扛生产。6.4 数据目录备份与迁移提醒最后提一个容易被忽略的点。MySQL的二进制包解压即用不少人会直接把整个/opt/mysql目录打包备份想着以后新机器部署时一键还原。这个思路对了一半。软件目录还原后只要确保/data/mysql数据目录权限归mysql用户所有/etc/my.cnf中的路径与还原后的路径一致/var/run/mysqld和/var/log/mysql目录已创建且有写入权限然后初始化命令千万不要重复执行。数据目录里已经有一整套系统库了重复初始化会直接报错或覆盖原有授权表轻则数据库起不来重则数据文件被二次初始化搞坏。我在测试机上犯过一次这个错误重新初始化后原来的库数据就只剩一个空壳了好在是测试环境没有造成实际损失。备份和迁移时拿系统表判断数据目录是否已初始化看到存在mysql这个目录就不要再执行--initialize了。还有ARM64机器的数据目录如果要迁移到x86_64机器MySQL 5.7的InnoDB表可以跨架构直接拷贝吗答案是不能保证100%兼容。表数据文件.ibd里记录了一些和CPU架构相关的元数据。虽然大部分文本内容和整数数据不涉及字节序差异但碰到使用浮点类型的列就麻烦了——ARM和x86的浮点表示并不完全一致。我的建议是跨架构迁移时用mysqldump把数据导出为SQL文件再到目标机器导入这是最稳妥的路径。想走拷贝文件这条捷径万一碰到浮点列和特殊字符集的表哭都来不及。我个人在实际操作中最大的体会就一句话ARM64装MySQL本身不难难的是装完之后的调优和安全加固。大部分在线教程都是处理x86_64的很多坑对ARM机器不适用或者表现不一样。如果你能按照上面的流程把基础环境按部就班搭起来数据库基本就稳定了后面再根据自己的业务场景调整参数、做备份就能把整个系统打磨到顺手。这套流程我在鲲鹏920、飞腾2000以及RK3399开发板这几个不同的ARM平台都跑过除了内存分配参数需要按机器实际配置微调外其他步骤完全可以照抄。
返回列表