尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Docker Compose批量部署MySQL主从集群:1分钟搭建10套复制环境

发布时间:2026/9/26 22:58:07

资讯中心
01
ARTICLE

Docker Compose批量部署MySQL主从集群:1分钟搭建10套复制环境

Docker Compose批量部署MySQL主从集群:1分钟搭建10套复制环境
1. 先搞清楚我们要搭的东西到底是什么先说结论这个标题一点也不夸张但“1分钟”是有前提的镜像提前拉好、脚本写好了剩下的启动和验证就是几十秒的事。我用一套基于 Docker Compose 封装的批量部署脚本在一台 8 核 16G 的机器上同时拉起 10 套 MySQL 主从集群从执行命令到SHOW SLAVE STATUS全部显示Waiting for source to send event整个流程不超过 1 分钟。这套方案我不是第一次用了前前后后踩了不少坑今天把这套东西拆开讲清楚。1.1 主从复制到底在复制什么MySQL 主从复制严格说复制的是 binlog二进制日志里的逻辑事件流。主库把数据变更按顺序写进 binlog从库通过 IO 线程把主库 binlog 拉到本地 relay log中继日志再由 SQL 线程回放 relay log最终让从库的数据追上主库。整个链路看似简单但涉及三张关键的角色表主库的 dump 线程负责把 binlog 事件推送给从库的 IO 线程。从库的 IO 线程负责连接主库请求 binlog 并写入 relay log。从库的 SQL 线程负责读取 relay log 并逐个执行事件。记住这个模型后面所有排查都是围绕这三条线展开的。我搭 10 套集群时最依赖的一个状态字段就是Slave_IO_Running和Slave_SQL_Running这两个字段同时为Yes基本说明复制链路是通的。如果 IO 线程卡住大概率是网络、账号权限或者 server-id 冲突如果 SQL 线程卡住大概率是主从数据不一致或者 relay log 损坏。复制模式上8.0 和 5.7 我选的是 GTID 模式也就是全局事务标识符。GTID 是server_uuid:transaction_id的组合每个事务在主库上产生唯一编号从库可以通过 GTID 自动定位复制位点不需要再关心binlog file和binlog position这两个老参数。对于批量部署 10 套集群的场景GTID 最大的意义是让初始化更加自动化脚本里可以少处理很多“主库位点变化”的边界问题。如果你还在用老的MASTER_LOG_FILEMASTER_LOG_POS方式搭建少量实例没问题但批量搞的时候就容易翻车因为主库一旦有额外写入位点就会漂移。1.2 主从集群能解决什么解决不了什么用主从不是为了“看着专业”它的核心价值有三块读写分离、容灾冗余、分析隔离。读写分离的场景最直观主库承接写流量从库承接读流量应用层按需切换数据源能明显降低主库负载。容灾冗余是指主库出现硬件故障后可以手动或通过高可用组件把从库提升为新主库减少不可用时间。分析隔离则是在从库上跑公司里那些重量级查询、报表任务、备份操作避免它们挤占主库的 CPU 和 IO。但它不是万能的有几个误区必须说清楚。第一主从复制不是同步复制默认是异步的主库提交事务后不等从库确认就返回成功所以从库数据天然存在延迟。延迟高的时候你读从库会读到旧数据这个必须靠业务层容忍或者中间件做分片策略。第二主从不能解决数据一致性问题如果主从数据已经不一致复制链路直接报错停摆不是自动修复。第三GTID 虽然自动化程度高但反向切换从库提升为主库后再恢复原主库时要注意事务冲突不能简单重连了事。1.3 为什么我选 Docker Compose 而不是裸机安装很多人一看“10 套主从集群”第一反应是一台物理机装 20 个 MySQL 实例路径、端口、配置要改到怀疑人生。确实如果用传统方式在 Linux 上通过二进制包部署 10 套主从光是规划目录、编译参数、启动脚本就能折腾一天这个过程没必要重复验证。用 Docker Compose 的好处在于每个容器就是一个隔离的 MySQL 实例端口映射、数据目录、配置文件都可以通过编排文件声明环境一致性极高。不管底层是 CentOS、Ubuntu 还是 Rocky只要 Docker 环境正常容器里的行为是一致的。这对批量复现主从场景极其重要尤其适合我这种经常要测运维工具、中间件、面试题里各种“主从切换”逻辑的人。不过我如实说一句Compose 不是万金油。生产环境的主从集群往往要结合 Orchestrator、MHA、ProxySQL 等组件Docker Compose 更多是开发环境、测试环境、压测环境的利器。但如果你想把“主从原理”验证透、把日常巡检脚本跑通、把面试里那些主从故障场景复现出来这套方案是最快路径。2. 环境准备与资源评估别上来就盲目拉二十个容器2.1 资源规划和端口设计是第一步10 套主从集群意味着 20 个 MySQL 容器实例。分配资源之前先想清楚每套集群是“真跑业务”还是“模拟场景”。如果只是模拟主从复制、验证配置、测试读写分离每个容器内存限制在 256M~512M 即可CPU 限制在 0.5~1 核即可。如果是压测那就不能这么抠建议单实例至少 1G 内存和 1.5 核起步。我用的机器是 8 核 16G给 20 个容器每实例分配了 512M 内存限制CPU 不加硬限制磁盘用 SSD。启动后整体内存占用在 10G 左右留了余量给宿主机和 docker daemon。这里有个很关键的思路资源限制一定要在 Compose 里声明。不限制的话20 个 MySQL 会按照 innodb_buffer_pool_size 默认值疯狂抢内存我的默认配置是 128M没有显式调大但容器本身没有 cgroup 限制时宿主机很容易被吃满。端口规划上传统做法是给不同实例分配不同的宿主机端口。10 套主从我划分为集群编号主库宿主机端口从库宿主机端口容器内部端口固定为1133061330733062134061340733063135061350733064136061360733065137061370733066138061380733067139061390733068140061400733069141061410733061014206142073306端口选择从 13306 起步是为了避开常规的 3306、3307也不跟宿主机已有服务冲突。这里唯一要牢记的是容器内部和外部端口不能混淆。连接主库或从库时用的是宿主机 IP 加映射端口而 MySQL 配置文件里的 server 相关参数和数据目录都在容器内部视角。2.2 Docker 与 Compose 插件装错版本会吃大亏先说宿主机系统。我在 Rocky Linux 9 和 Ubuntu 22.04 上都验证过这套流程核心要求是 Docker Engine 版本不低于 20.10Compose 插件正常可用。安装 Docker 的步骤不再赘述重点提醒几个容易出问题的地方。第一docker compose命令和老的docker-compose是两套东西。新版 Docker Engine 推荐用docker compose带空格作为子命令它是一个 Go 编写的独立二进制插件。老项目里常见的docker-compose由 Python 写成新版本 Docker 环境下经常出现兼容性问题尤其是version字段废弃后老命令会给你报奇怪的格式错误。我要不是为了兼容旧脚本绝不用docker-compose。实际操作中我用的是docker compose version检查版本确保输出里有Docker Compose version v2.x。第二运行 Docker 服务的用户要加入 docker 用户组否则每次都要 sudo。批量操作 20 个容器时命令数量非常多如果每次都要 sudo 超时重新输入密码那 1 分钟搭建就是个笑话。建议直接sudo usermod -aG docker $USER newgrp docker第三磁盘空间问题。MySQL 官方镜像本身不算大但容器一旦初始化数据目录很容易膨胀。10 套集群即使每套只有几十 MB 的初始化数据加上 binlog、redo log、undo log总量也是可观的。我建议宿主机的/var/lib/docker分区至少预留 30G 可用空间否则 MySQL 8.0 启动后会因为磁盘空间不足报各种神鬼莫测的错比如InnoDB: Operating system error number 28。2.3 镜像选型锁定版本不要用 latest镜像标签是这次实操里最容易阴沟翻船的地方。很多人图省事直接用mysql:latest这是大忌。latest标签会跟随官方更新飘移今天拉下来是 8.0.36明天变 8.0.38行为可能发生变化尤其在认证插件、默认字符集、参数默认值上不同小版本的差异真的能坑到你怀疑人生。我选的是mysql:8.0.36官方镜像锁死在 Dockerfile 层面。为什么不选 5.7因为 MySQL 5.7 已经停止更新8.0 在性能、安全性、GTID 支持方面都更主流。8.0 的默认认证插件是caching_sha2_password这一点在配置从库连接主库时要特别注意后面我会详解。如果你有历史包袱必须用 5.7那也请锁死mysql:5.7.44不要用5.7标签。镜像最好提前手动拉好这一步对“1分钟”贡献最大docker pull mysql:8.0.36不要以为随便找台机器现拉也能 1 分钟搞定国内镜像源高峰期一个接近 100MB 的镜像拉取时间能让你直接破防。提前备好镜像后面的操作才真正是读秒级别的。3. 一分钟搭建的关键批量生成 Compose 配置3.1 设计思路写一份模板用一个变量驱动 10 套纯手工写 20 个 service 段是愚蠢且低效的。我的做法是准备一个小的 shell 脚本gen_cluster.sh通过一个循环变量生成完整的docker-compose.yml。脚本不复杂但对格式极其敏感尤其是 YAML 缩进少一个空格容器编排阶段就会报错。脚本核心逻辑是定义一个要生成的集群数量比如CLUSTER_NUM10。定义一个基础端口比如BASE_PORT13306。循环生成每个集群的主从两个 service 段。拼接生成docker-compose.yml文件。这里的核心点是每个主库的server_id必须全局唯一。MySQL 复制协议中从库连接主库时会以 server-id 标识自己如果两个从库用了相同的 server-id主库会踢掉旧连接导致其中一个从库频繁断连。我在批量生成时把 server_id 设计为“集群编号2-1”是主库“集群编号2”是从库这样 10 套集群的 server_id 分别为 1 到 20两两集群之间完全不冲突。3.2 批量生成 docker-compose.yml 的代码实现下面是实际跑通过的脚本我简化了部分注释保留了核心逻辑。脚本内容本身可以直接抄但请你先理解每一步再运行#!/bin/bash CLUSTER_NUM10 BASE_PORT13306 MYSQL_ROOT_PASSWORDRoot123456 REPL_USERrepl_user REPL_PASSWORDRepl123456 OUT_FILEdocker-compose.yml cat $OUT_FILE EOF services: EOF for ((i1; iCLUSTER_NUM; i)); do MASTER_PORT$((BASE_PORT (i-1)*2)) SLAVE_PORT$((MASTER_PORT 1)) MASTER_ID$((i*2 - 1)) SLAVE_ID$((i*2)) cat $OUT_FILE EOF mysql-master-${i}: image: mysql:8.0.36 container_name: mysql-master-${i} restart: unless-stopped ports: - ${MASTER_PORT}:3306 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} command: - --server-id${MASTER_ID} - --log-binmysql-bin - --gtid_modeON - --enforce_gtid_consistencyON - --binlog_formatROW - --default_authentication_pluginmysql_native_password volumes: - mysql-master-${i}-data:/var/lib/mysql networks: mysql-cluster-net: ipv4_address: 172.28.${i}.10 mysql-slave-${i}: image: mysql:8.0.36 container_name: mysql-slave-${i} restart: unless-stopped depends_on: - mysql-master-${i} ports: - ${SLAVE_PORT}:3306 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} command: - --server-id${SLAVE_ID} - --gtid_modeON - --enforce_gtid_consistencyON - --read_onlyON - --super_read_onlyON volumes: - mysql-slave-${i}-data:/var/lib/mysql networks: mysql-cluster-net: ipv4_address: 172.28.${i}.20 EOF done cat $OUT_FILE EOF volumes: EOF for ((i1; iCLUSTER_NUM; i)); do cat $OUT_FILE EOF mysql-master-${i}-data: name: mysql-master-${i}-data mysql-slave-${i}-data: name: mysql-slave-${i}-data EOF done cat $OUT_FILE EOF networks: mysql-cluster-net: driver: bridge ipam: config: - subnet: 172.28.0.0/16 EOF echo Generated $OUT_FILE with $CLUSTER_NUM clusters这里有一个必须注意的细节MySQL 8.0 官方镜像中默认认证插件是 caching_sha2_password我在主库命令中显式指定了--default_authentication_pluginmysql_native_password。原因是复制账号在老认证插件下更容易被兼容适配虽然 8.0 本身支持 caching_sha2_password但客户端驱动和中间件五花八门一不小心就报Authentication plugin caching_sha2_password cannot be loaded。如果目标是生产环境且客户端版本明确支持可以不用这个参数但批量测试场景我建议加上省掉一大片兼容性麻烦。网络方面我给每套集群分配了独立网段172.28.${i}.0/24主库固定172.28.${i}.10从库固定172.28.${i}.20。这样主从之间的通讯地址不需要依赖 DNS 解析也不容易因为容器重建导致 IP 变化。这种规划对于批量管理非常友好后期写巡检脚本时直接按 IP 遍历即可。3.3 启动容器的一个坑IPv4 子网不能铺太大执行docker compose up -d前我特意把 network 子网限制在172.28.0.0/16而不是默认的桥接网络。很多人直接省略 network 配置让 Compose 自己创建默认网络也能跑但默认网络不支持指定静态 IP而且不同项目之间的网络隔离不够彻底。当你有 10 套集群同时起时默认网络会把它们全部放在同一个网段将来做网络策略限制时你根本没法区分。子网不能铺太大还有另一个原因预留子网冲突。172.28.0.0/16这个网段如果和公司局域网冲突容器通信就会异常。我在一个客户的服务器上就遇到过他们的内网恰好占了 172.28.0.0/16Docker 自动分配的网段一启动就把公司网络搞懵了。所以部署前先查一下当前机器上已有的 docker 网络docker network ls如果有其他项目已经占了类似网段就换一个不冲突的比如172.29.0.0/16或 10.88.0.0/16。3.4 启动命令与快速验证镜像准备好、配置文件生成好后启动命令只有一行docker compose up -d在 10 套集群规模下第一次启动需要初始化数据目录通常会等一会儿。但如果你的数据卷是全新的、镜像已缓存、磁盘是 SSD实测从执行命令到 20 个容器全部显示Up大约 40 秒到 1 分钟。这也是标题“1分钟搭建10套MySQL主从集群”这句话的真正来源——它指的是容器全部正常启动而不是把复制链路也初始化完。容器启动后先用一个命令检查全局状态docker compose ps --format table {{.Name}}\t{{.Status}}\t{{.Ports}}这个输出会显示每个容器的状态。如果你看到某个容器反复 restart大概率是 MySQL 初始化失败。此时去看对应容器日志docker logs mysql-master-1 --tail 50最常见的失败原因有两个一是挂载的 volume 权限问题容器内 mysql 用户无法写入数据目录二是配置文件或其他参数冲突导致 MySQL 无法完成初始化。前者在官方镜像中相对少见后者通常和 my.cnf 里配了 Compose 命令行中重复的参数有关。还有一点要提醒不要看到 20 个容器都 Up 就以为万事大吉。MySQL 容器对外表现为 Up内部可能还在进行初始化。需要在容器内实际执行mysqladmin ping确认。批量检查时可以用一行循环for i in $(seq 1 10); do docker exec mysql-master-$i mysqladmin ping -h127.0.0.1 -uroot -pRoot123456 2/dev/null docker exec mysql-slave-$i mysqladmin ping -h127.0.0.1 -uroot -pRoot123456 2/dev/null done全部返回mysqld is alive后容器层才算就绪。4. 复制链路的初始化与验证十套集群一起搞定4.1 在主库创建复制账号并授权容器全部启动后剩下就是配置复制链路。自动化的思路是写一个初始化脚本依次对 10 套集群执行。但在此之前我先手动对第一套集群做一遍完整流程确保每一步命令正确然后再批量执行。这个习惯能帮你少踩很多雷尤其是 SQL 写错时你只需要改一次脚本而不是在 20 个容器里逐个补救。先在主库创建复制专用账号。这个账号在从库连接主库时使用必须具备REPLICATION SLAVE权限8.0 里对应REPLICATION SLAVE。在主库执行CREATE USER repl_user% IDENTIFIED WITH mysql_native_password BY Repl123456; GRANT REPLICATION SLAVE ON *.* TO repl_user%; FLUSH PRIVILEGES;账号权限最小化是铁律。不要图省事直接给repl_user授予 ALL PRIVILEGES 或者 SUPER 权限复制链路只需要 REPLICATION 相关权限多余的权限只会增加安全事故风险。顺便提一句如果你的业务要配置级联复制那才需要给中继主库额外权限而普通主从场景不必。接着确认主库当前的 GTID 状态。GTID 模式下不再需要获取 File 和 Position但需要确保gtid_mode已开启并且enforce_gtid_consistency生效。可以执行SHOW VARIABLES LIKE gtid_mode; SHOW MASTER STATUS\G;在 GTID 模式下SHOW MASTER STATUS返回的File和Position字段已经不再用于启动复制而是看Executed_Gtid_Set。这个值会记录已经执行过的 GTID 集合从库启动复制时只需要知道从哪个 GTID 开始即可。4.2 从库执行 CHANGE MASTER TO 并启动复制从库上执行的语句如下我以集群 1 的从库连接集群 1 的主库为例CHANGE MASTER TO MASTER_HOST172.28.1.10, MASTER_PORT3306, MASTER_USERrepl_user, MASTER_PASSWORDRepl123456, MASTER_AUTO_POSITION1; START SLAVE;注意MASTER_AUTO_POSITION1这一行是 GTID 模式的核心。它告诉从库不要再监听 File 和 Position改用 GTID 自动定位到主库的 binlog 位置。如果不加这个参数MySQL 默认会认为你要用老协议直接报错或者无法正确同步。从库的MASTER_HOST用的是容器内部网络地址不是宿主机的映射端口地址。这一点很重要它体现的是“容器间通信”与“宿主机访问”两个视角。如果你在宿主机上用mysql -h127.0.0.1 -P13307去连从库那意味着你在走宿主机端口映射但从库内部连接主库时它处于容器网络里必须用容器 IP 或容器服务名。第二套到第十套集群的复制链路原理完全一样只是 IP 变化。对于批量操作我写了一个init_replication.sh核心是在每套集群的主库创建账号然后到从库执行 CHANGE MASTER TO 和 START SLAVE。注意脚本里要捕获每个步骤的返回值任何一个从库启动失败都不能静默忽略。4.3 验证复制状态三个字段决定成败配置完复制后验证是必不可少的一步。在每套集群的从库上执行SHOW SLAVE STATUS\G;最需要关注的字段如下表字段正常值异常含义Slave_IO_RunningYesIO 线程未运行连接主库失败Slave_SQL_RunningYesSQL 线程未运行回放 relay log 出错Seconds_Behind_Master0 或接近 0数值持续增大代表从库延迟严重Last_IO_Error空有内容则代表网络或认证问题Last_SQL_Error空有内容则代表回放出错Retrieved_Gtid_Set非空从库尚未拉到任何 GTID 时为空第一次搭建时我遇到过Slave_IO_Running一直是Connecting的情况最开始以为是网络问题后来才发现是复制账号密码写错了Last_IO_Error里明确提示Access denied for user repl_user。所以只要看到 IO 线程不是 Yes第一件事就看Last_IO_Error不要瞎猜。验证全部通过后还可以做一次实际的写入测试。在集群 1 主库建一张表插入数据然后从库查询-- 主库执行 CREATE DATABASE test_db; USE test_db; CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20)); INSERT INTO t1 VALUES (1, hello); -- 从库查询 USE test_db; SELECT * FROM t1;如果从库能查到1|hello说明 binlog 事件通过 dump - IO - SQL 全链路回放成功这套主从就是活的。这一步最有说服力比任何状态字段都真实。4.4 批量验证脚本的思路手动查 10 套集群的状态太浪费时间我封装了一个验证脚本逻辑很简单对每个从库循环执行SHOW SLAVE STATUS用 grep 或 awk 抓关键字段把所有异常实例汇总输出。for i in $(seq 1 10); do docker exec mysql-slave-$i mysql -uroot -pRoot123456 -e SHOW SLAVE STATUS\G 2/dev/null | grep -E Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master | tr \n echo - cluster $i slave done没验证之前你可能不知道批量脚本最大的价值是什么。当你手动执行了二十遍 CHANGE MASTER TO 后你会发现任何可以“重复做”的操作都值得写成脚本。5. 常见问题与排查策略这四十个容器让我踩遍了坑说实话我第一次写这套脚本时并没有一次通过前后折腾到凌晨。如果你照着上文操作大概率会踩到如下几个问题我把它们按出现频率从高到低排个序。5.1 Container 反复重启数据卷权限出问题现象docker compose ps看到某些容器 STATUS 为Restarting日志里有Permission denied或Cant open the mysql.plugin table。原因数据卷目录上的权限不对。官方镜像在容器内是以mysql用户运行的如果宿主机挂载的目录是 root 所有容器内的 mysql 用户没有写权限初始化直接失败。解决办法挂载卷时可以显式指定:ZSELinux 环境或检查目录权限最稳妥的是不挂宿主机目录到/var/lib/mysql而是用 Docker named volume也就是上文脚本里做的volumes: mysql-master-${i}-data:/var/lib/mysql。Named volume 由 Docker 接管权限天然避开这个问题。5.2 从库 IO 线程连接不上主库总是在 Connecting这种问题我在新环境里遇到过好几次。排查顺序应当固定为检查从库与主库的容器网络连通性。进入从库容器ping 主库容器 IP。检查主库的复制账号是否存在、密码是否正确、host 是否允许远程。账号 host 必须覆盖从库来源 IP 对应的范围比如%。检查主库和从库的 server_id 是否重复。如果从库 1 的 server_id 和从库 2 相同主库会认为连接冲突。检查防火墙。这里说的是宿主机防火墙不是 Docker 内防火墙。虽然容器间通信一般不受宿主机防火墙 影响但如果某些环境启用了 docker 网桥规则就需要额外注意。把Last_IO_Error拿过来逐字读是最重要的MySQL 在这条错误信息里提供了非常明确的提示。5.3 SQL 线程报错主从数据不一致或 relay log 损坏现象Slave_SQL_RunningNoLast_SQL_Error里通常是 1062主键冲突或 1032记录不存在。原因从库上有人写过数据或者主库上某条 DDL/DML 在从库执行时因为表结构差异失败。处理方式如果数据不一致是测试环境可以直接重建复制链路。要最大程度保持从库与原主库一致需要在从库上STOP SLAVE; RESET SLAVE ALL;然后重新 CHANGE MASTER TO。如果错误已经发生且不影响大局也可以跳过该事务执行SET GLOBAL sql_slave_skip_counter 1;再START SLAVE;但这是应急手段生产中不建议滥用。5.4 认证插件导致复制失败这是 8.0 特有的坑。如果主库没设置default_authentication_pluginmysql_native_password同时从库的账号使用了caching_sha2_password连接时有一定概率需要 RSA 加密传输公钥环境复杂时就会出现类似Authentication plugin caching_sha2_password reported error: Authentication requires secure connection的报错。我在脚本里直接在主库命令中植入mysql_native_password就是为了规避这层麻烦。如果你的业务环境强制要求caching_sha2_password那从库做 CHANGE MASTER TO 时需要额外配置MASTER_SSL相关参数或者确保网络传输本身是加密的。这个复杂度远高于用 native password所以我建议测试环境或内部环境统一用 mysql_native_password。5.5 容器能启动但 mysql 命令报ERROR 2002 (HY000): Cant connect to local MySQL server through socket这个热搜词很多人搜到过。在 Docker 容器内执行mysql -uroot -p时默认会尝试连接/var/run/mysqld/mysqld.sock如果 socket 文件路径不对就会报这个错。解决办法是显式指定 TCP 方式连接mysql -h127.0.0.1 -P3306 -uroot -p在批量脚本里尤其要注意凡是给mysql客户端传-h参数就不要再依赖 socket 连接。因为容器内部不仅 MySQL socket 路径与宿主机隔离而且你可能还需要连接其他容器的 MySQL那本身就只能走 TCP。5.6 磁盘空间不足InnoDB 初始化失败这是批量启动 20 个容器后最常见的慢性病。刚开始一切正常跑几轮数据写入和删除测试后宿主机磁盘被 binlog 吃满。解决方案有两个层面一是配置 MySQL 的 binlog 过期时间在容器启动命令中加--binlog_expire_logs_seconds86400让超过一天的 binlog 自动清理二是定时巡检磁盘使用率尤其是 Docker 数据目录。如果已经出现InnoDB: Operating system error number 28立即清理悬空容器和未使用的镜像删除不必要的旧数据卷docker system df docker volume prune注意docker volume prune要小心它会删掉所有未使用的 volume如果里面有旧数据想保留先做好确认。6. 一点实操后的心得体会这套基于 Docker Compose 批量部署 10 套 MySQL 主从的方案我前后在两个不同项目里验证过一个用于主从故障演练一个用于中间件的读写分离测试。我的体会是Docker Compose 的最大价值不是“生产环境高可用”而是让你用最低的成本把复杂的复制拓扑从想法变成现实反复验证原理、排查问题、锻炼操作手感。如果后续你还想继续扩展可以在同一套网络架构里加入 MHA 或 Orchestrator 容器做主库自动故障切换的演练也可以加一个 ProxySQL 容器把 10 套集群的从库都挂到同一个读写分离入口测试只读负载均衡还可以在集群里故意制造延迟观察Seconds_Behind_Master的波动加深对半同步复制、异步复制差异的理解。最后分享一个小技巧批量场景下所有“一次性”的初始化操作都值得写进脚本里但所有“探索性”的排查操作都建议先在单套集群上手工跑通。别急于追求自动化先把第一套集群的原理搞透再去批量化。我见过太多人直接拿别人脚本一把梭最后 20 个容器全都起来了却根本不知道主从复制是怎么工作的出了问题连日志都不会看。这套东西上手快但真正值钱的是你对那三张线程表和几个状态字段的理解深度。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。