鲲鹏ARM服务器上用Docker镜像部署MySQL主从集群完整方案

发布时间:2026/10/7 16:55:48
鲲鹏ARM服务器上用Docker镜像部署MySQL主从集群完整方案 说实话第一次接到在鲲鹏ARM服务器上搭MySQL主从集群的任务时我第一反应是照着x86上的老流程走一遍下载官方二进制包、解压、初始化、改配置、启动。结果第一个包就给我上了一课——“Exec format error”文件格式错误处理器根本不认这套指令集。后来换成镜像方式重新梳理了整个部署流程才发现用容器在这类ARM平台跑MySQL不仅绕开了编译和包管理的坑主从配置反而能做得更标准、更省事。这篇我会把鲲鹏ARM服务上用MySQL镜像部署主从集群的完整方案、关键参数、踩坑记录都写下来给准备入场的同学做个可复现的参考。1. 方案选型为什么在鲲鹏上优先用镜像方式1.1 先认清ARM平台的现实约束鲲鹏920这颗处理器用的ARMv8架构对外呈现是aarch64指令集。这在日常看cpuinfo时很显眼但很多人下单部署任务时根本没意识到它和x86的差异有多大。MySQL的官方通用二进制包默认按x86_64编译拿到鲲鹏机器上直接跑就是“Exec format error”内核读不懂二进制文件头的ELF machine字段。换用RPM包也一样yum源里若没有aarch64的mysql包只能去别处找或者自己打包。源码编译是一条看似可行的路实际走一遍才知道水多深MySQL 8.0的编译依赖cmake、bison、openssl开发库、boost库等一堆东西ARM上还要注意编译器是否支持NEON指令集的优化。即便编译通过后续每次小版本升级都要重复折腾运维成本很高。我的实测感受是在鲲鹏机器上源码编译MySQL 8.0顺利的话也要大半天稍微遇到依赖问题一天就进去了。而镜像方式的逻辑完全不同。官方MySQL镜像本身是multi-arch的Docker在拉取时会自动匹配当前平台的arm64变体相当于把“找包、装依赖、初始化、起服务”这些事全部封装好了。部署一个MySQL实例本质上变成了一条docker run命令加一组挂载参数无论你在x86开发机上还是在鲲鹏服务器上操作行为完全一致。这一点对于大规模交付和团队协作非常友好大家面对的是一套标准化流程而不是各自手工编译出来的“某一版MySQL”。1.2 主从架构的价值与适用边界主从集群不是摆设解决的实际问题很具体读写分离把查询压力从主库分流出去数据冗余让主库挂了之后能从从库找回数据更重要的是从库可以作为备份和报表分析的专用节点避免业务查询和线上写入相互干扰。鲲鹏服务器常用于数据库国产化场景这类业务往往对稳定性要求极高单点MySQL的可用性根本说不过去主从是最基础也最稳妥的起步方案。很多人纠结要不要一上来就上MGRMySQL Group Replication或者半同步复制我的建议是先从异步主从做起。异步复制搭起来最简单对网络延迟不敏感业务改动最小等链路稳定、监控完善之后再根据RPO要求决定是否升级到半同步或者MGR。镜像方式部署的主从后续切换方案也灵活从库提升为主库只需停掉复制、清理只读参数一条命令就能切换不需要重装任何组件。就现阶段大多数国产化项目的评估要求来说一主一从的镜像方案已经能覆盖绝大多数交付场景。2. 环境准备与镜像选择要点2.1 确认硬件架构与基础环境部署之前先把底牌摸清楚省得后面出错都不知道错在哪。登录鲲鹏服务器后用如下命令确认架构uname -m lscpu cat /etc/os-release正常情况下uname -m会输出aarch64lscpu里Architecture一栏也是aarch64同时能看到鲲鹏920的型号信息。操作系统这步也要看仔细常见的中标麒麟、麒麟V10、openEuler、统信UOS都可能出现在鲲鹏机器上不同系统对Docker版本的要求和默认配置略有差异但大方向一致。Docker建议用20.10以上的版本不仅仅因为新的Docker对multi-arch镜像的支持更好更关键的是新版对overlay2存储驱动和iptables规则管理更成熟省得老版本在ARM上出现一些莫名其妙的兼容问题。检查命令docker --version docker info | grep -i architecture如果系统里还没有Docker用官方安装脚本装完记得把Docker服务设为开机自启systemctl enable docker --now这里有一个容易被忽略的点鲲鹏服务器的操作系统中可能默认开启了SELinux或防火墙策略裸奔的Docker环境虽然能跑但主从的3306端口互相访问可能会被拦下来。要么在安全策略里放行容器网段要么直接在部署前确认docker0网桥和容器网络的通信规则。我建议在搭建型任务阶段先把firewalld临时停掉等主从正常通了之后再恢复策略并精确放行这样能避免排查问题时把网络因素和配置因素搅在一起。2.2 镜像版本与国内源配置镜像选择直接决定后续踩坑多少。官方mysql镜像有5.7和8.0两条主线鲲鹏ARM上两个版本都有arm64变体但我强烈建议不要用latest标签原因是MySQL 8.0的小版本升级有时会改变默认参数行为latest指向的版本可能在某个时间点悄然变化导致你写好的配置文件行为不一致。部署时可复现的第一原则就是锁定具体版本。拉镜像前先确认当前平台能匹配到正确的镜像变体docker manifest inspect mysql:8.0.36 | grep -A2 architecture这条命令能看到镜像清单里同时存在amd64和arm64两个平台的条目Docker拉取时会根据本机架构自动选择arm64那一个。国内网络环境拉Docker Hub的镜像确实慢甚至经常超时我的做法是在/etc/docker/daemon.json里配置国内的镜像加速服务配置后重启Docker再拉取速度提升非常明显。注意这台机器上可能同时跑着其他容器修改daemon.json后docker服务重启会牵连所有容器所以调整镜像源的操作建议在业务低峰期做或者直接放在初始部署阶段一起完成。3. 主库与从库的容器化部署实操3.1 目录规划与配置文件设计容器启动只是一瞬间的事但数据目录规划得好不好决定了后面半年你会不会加班。我习惯先把宿主机目录建好再用volume挂载进容器这样MySQL的数据文件、配置、日志全部落在宿主机上容器删了重建也不丢数据。标准目录结构如下mkdir -p /data/mysql-master/conf mkdir -p /data/mysql-master/data mkdir -p /data/mysql-slave/conf mkdir -p /data/mysql-slave/data主库配置文件放在/data/mysql-master/conf/my.cnf[mysqld] server-id 1 log-bin mysql-bin binlog_format ROW gtid_mode ON enforce_gtid_consistency ON log_slave_updates ON skip_name_resolve ON max_connections 500 character_set_server utf8mb4 collation_server utf8mb4_general_ci bind-address 0.0.0.0 [client] default-character-set utf8mb4从库配置文件放在/data/mysql-slave/conf/my.cnf[mysqld] server-id 2 relay-log relay-log log-bin mysql-bin log_slave_updates ON binlog_format ROW gtid_mode ON enforce_gtid_consistency ON read_only ON skip_name_resolve ON max_connections 500 character_set_server utf8mb4 collation_server utf8mb4_general_ci bind-address 0.0.0.0 [client] default-character-set utf8mb4配置文件里几个参数的解释值得展开说一下。mysql官方容器默认会读取/etc/mysql/conf.d目录下的所有.cnf文件所以把自定义配置挂载到这个目录是官方推荐的做法。server-id主从必须不同这是复制拓扑里每个节点的身份证log-bin开启二进制日志主库没有它就无从谈复制。gtid_mode和enforce_gtid_consistency是8.0时代推荐的配置开启后从库定位复制进度不再依赖文件名和位置后续扩容、切换、故障恢复都简单很多。从库的read_only参数建议打开防止业务误写从库造成数据不一致log_slave_updates则在从库上再生成一份binlog便于从库继续向下级联或者从从库拉取备份而不影响主库。3.2 启动主库容器先给两个容器建一个独立的自定义网络名字就叫mysql-cluster。用自定义网络的好处是容器之间可以用容器名直接解析从库去连主库时根本不用关心主库的IP变没变docker network create mysql-cluster启动主库docker run -d \ --name mysql-master \ --network mysql-cluster \ -p 3306:3306 \ -e TZAsia/Shanghai \ -e MYSQL_ROOT_PASSWORDMasterRoot123 \ -v /data/mysql-master/conf/my.cnf:/etc/mysql/conf.d/my.cnf \ -v /data/mysql-master/data:/var/lib/mysql \ --restartalways \ mysql:8.0.36这个命令里最容易踩的坑是数据目录权限。官方MySQL镜像内的进程以mysql用户运行uid是999如果你主机的/data/mysql-master/data目录权限是root root容器启动时会因为无法写入而直接退出。第一次启动前先执行chown -R 999:999 /data/mysql-master/data chown -R 999:999 /data/mysql-slave/dataTZ环境变量设置时区为Asia/Shanghai避免容器内MySQL的时间比宿主机早8个小时排查问题时会扰乱你的判断。MYSQL_ROOT_PASSWORD只对首次初始化数据目录生效如果数据目录已经初始化过这个环境变量不会再改变root密码网上很多人改密码不生效就是这个原因。3.3 启动从库容器从库容器启动命令大同小异区别是端口映射不能跟主库冲突server-id不同docker run -d \ --name mysql-slave \ --network mysql-cluster \ -p 3307:3306 \ -e TZAsia/Shanghai \ -e MYSQL_ROOT_PASSWORDSlaveRoot123 \ -v /data/mysql-slave/conf/my.cnf:/etc/mysql/conf.d/my.cnf \ -v /data/mysql-slave/data:/var/lib/mysql \ --restartalways \ mysql:8.0.36启动后稍等几秒用docker ps确认两个容器都在Up状态再用docker logs mysql-master和docker logs mysql-slave看看有没有报错。这里提醒一下第一次初始化需要时间如果docker logs里没有错误但通过宿主机端口连不上MySQL可以等10秒左右再试不要急着判定启动失败。容器网络模式下主从复制走的是容器网络内部通信。从库容器里可以直接用mysql-master这个主机名去连主库这是因为自定义网络里Docker内置了DNS解析。很多教程让你填主库的exporter IP填了也能通但换机器重建容器后IP经常变写容器名才是镜像方式部署的正确姿势。4. 建立主从关系与状态验证4.1 在主库创建复制专用账号复制账号不建议直接用root权限给太大安全性差。登录主库创建一个专用账号并授予复制权限docker exec -it mysql-master mysql -uroot -pMasterRoot123CREATE USER repl% IDENTIFIED WITH mysql_native_password BY Repl12345; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO repl%; FLUSH PRIVILEGES;这里有个细节MySQL 8.0默认的认证插件是caching_sha2_password如果后续有老版本客户端或某些中间件需要连接复制账号可能出现认证不兼容。显式指定mysql_native_password是兼容性更好的选择主从复制链路也更稳。4.2 从库执行复制配置登录从库容器docker exec -it mysql-slave mysql -uroot -pSlaveRoot123执行切换主库并启动复制CHANGE MASTER TO MASTER_HOSTmysql-master, MASTER_PORT3306, MASTER_USERrepl, MASTER_PASSWORDRepl12345, MASTER_AUTO_POSITION1; START SLAVE;MASTER_AUTO_POSITION1是GTID模式下的推荐写法从库会自动从主库的GTID集合中计算出需要同步的事务不再需要手动指定binlog文件和position偏移量。这相当于从库拿到一个“总账本”知道自己缺哪些事务按需补齐。接着查看复制状态SHOW SLAVE STATUS\G重点关注三个指标Slave_IO_Running必须为Yes表示能正常从主库拉取binlogSlave_SQL_Running必须为Yes表示中继日志能正常回放Seconds_Behind_Master表示主从延迟的秒数刚配置完成后应该是0或很小的数字。4.3 数据一致性验证配置完成后最要紧的是做一次端到端的验证我习惯在主库建一个测试库和测试表写入几条数据再到从库上看是否同步来确认整条链路真的通了。主库执行CREATE DATABASE test_db CHARACTER SET utf8mb4; USE test_db; CREATE TABLE t_user ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); INSERT INTO t_user (name) VALUES (鲲鹏), (aarch64);从库执行USE test_db; SELECT * FROM t_user;如果从库能查到这两条记录说明主库的binlog产生、传输、中继日志回放整条链都是通的。我还会顺手验证一下主从库的全局变量一致性例如character_set_server、version避免字符集或版本不一致导致后续复制中断。5. 常见问题排查与运维心得5.1 高频踩坑现场与速查表搭建主从的过程里我踩过不少坑也帮人解决过不少类似问题最常见的几个场景整理成表方便你直接对照现象直接原因处理方式容器启动后立即退出docker logs显示权限错误数据目录属主不对chown -R 999:999 数据目录后重建容器docker run时报Exec format error镜像不是arm64变体用官方multi-arch镜像先manifest inspect确认拉取镜像超时或极慢国内访问Docker Hub受限配置国内镜像加速服务重启dockerSlave_IO_Running一直Connecting网络不通或认证失败检查容器网络、iptables、复制账号密码Slave_SQL_Running为NoGTID事务冲突或跳过事务查看Last_SQL_Error临时跳过或重建从库重启后复制中断server-id冲突或auto.cnf被拷贝确认两个容器server-id不同删除从库auto.cnf重建主库写入中文从库显示乱码字符集不一致统一utf8mb4建库时也显式指定字符集这些坑里最隐蔽的是server-uuid冲突。如果你从主库物理备份文件恢复从库数据备份中会包含auto.cnf文件里面保存着MySQL实例的uuid。直接导入后从库和主库的server-uuid相同复制会报错或异常。解法是启动从库前先清掉从库数据目录下的auto.cnf让MySQL第一次启动时重新生成新的uuid。SQL线程报错是另一个高频问题多见于手动在主库执行了ALTER TABLE等DDL而业务侧同时又在从库执行了只读查询导致从库回放时出现锁等待超时后报错。此时不要慌先看Last_SQL_Error拿到具体的错误信息如果是可以安全跳过的事务可以临时执行STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER 1; START SLAVE;如果错误信息涉及数据冲突这招不适用正确的做法是停掉复制、记录当前主库的GTID位置在从库上补齐差异数据后重新设置复制位点。这里要啰嗦一句SQL_SLAVE_SKIP_COUNTER只适合跳过无害事务面对真正损坏的数据跳过只会让主从差异越拉越大。5.2 日常运维备份与监控建议主从搭建完成并不代表一劳永逸日常维护才是最花精力的地方。备份策略上我建议以从库为备份节点在主库业务低峰期用mysqldump配合GTID完成逻辑备份docker exec mysql-slave mysqldump -uroot -pSlaveRoot123 \ --single-transaction --master-data2 --all-databases \ /data/backup/mysql-slave-$(date %F).sqlmysqldump加--master-data2会在备份文件头部记录备份时刻的binlog位置或GTID集合恢复后可以用它继续追加复制这个参数是保证备份可追溯的关键。同时建议定期清理陈旧备份我通常保留7天内的备份文件再配合binlog做增量恢复既能覆盖误删数据的场景也不会让磁盘被备份撑满。监控方面主从延迟和复制线程状态是两条生命线。可以写一个简单的shell脚本定时去从库执行SHOW SLAVE STATUS检查Slave_IO_Running和Slave_SQL_Running是否都为Yes以及Seconds_Behind_Master是否超过阈值异常时通过企业微信或邮件告警。脚本里注意用MYSQL_PWD环境变量或配置文件传密码不要裸写在命令行参数里避免被进程列表泄露。另一个值得养成的习惯是定期做从库数据校验。主从复制不会自动发现数据漂移例如有人在从库上手动插入了一条记录或者某个事务在主库上被跳过最终都会导致两边数据不一致。可以每月挑一个低峰期用pt-table-checksum对重点表做一次校验发现问题后用pt-table-sync修复。工具不复杂但在ARM容器环境里要注意安装兼容版本。最后聊一下演进方向。镜像方式部署的主从集群后续如果需要提升容灾能力可以把异步复制升级为半同步复制安装semisync插件并调整参数即可容器内只是my.cnf和插件的事不会引发架构改动。如果业务规模继续扩大还可以在现有集群基础上再挂一个只读从库或者改成MGR多主模式。因为从一开始就是用镜像加标准配置搭建的节点间的修改、替换、扩容都可以套用同一套流程这也是我坚持用镜像方式的最大原因。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询