必须隔离配置与数据,否则MySQL实例误判为同一节点导致启动失败或复制中断;因server-id需全局唯一且log-bin文件名依赖主机名,复用my.cnf或volume会引发冲突。

能批量配置,但必须每个节点的 server-id、数据目录、配置文件、端口映射全部隔离,否则启动就冲突或复制中断。
为什么不能复用同一份 my.cnf 或 volume 路径
MySQL 启动时校验 server-id 全局唯一,且 log-bin 文件名默认基于主机名生成;若多个容器挂载相同 /etc/mysql/conf.d/my.cnf 或共享 /var/lib/mysql 目录,会出现:
-
mysqld拒绝启动,报错ERROR 2002 (HY000): Can't connect to local MySQL server - 主从连接后
SHOW SLAVE STATUS\G中Seconds_Behind_Master为NULL,IO_Running显示No - 从库反复重连失败,日志里持续出现
Lost connection to master
根本原因是:容器间未做配置/数据隔离,MySQL 实例误认为自己是同一节点。
docker-compose.yml 中必须显式区分的 4 个关键项
以下字段每增一个从节点,都需人工确认不重复:
-
container_name:如mysql-master、mysql-slave1、mysql-slave2 -
ports:主库映射3306:3306,从库至少错开,如3307:3306、3308:3306 -
volumes中的宿主机路径:每个节点必须独立目录,如./mysql-master/data、./mysql-slave1/data -
command或环境变量中传入的--server-id=100(推荐)或配置文件内server-id=100,值不可重复
别依赖镜像默认值——MySQL 8.0 默认 server-id=1,多个容器全用默认值,复制直接瘫痪。
my.cnf 配置差异:主 vs 从,不止 server-id
主库和从库的 my.cnf 不只是改 server-id,核心差异如下:
- 主库必须有:
log-bin=mysql-bin、binlog-format=ROW、sync-binlog=1(可选但推荐) - 从库必须有:
relay-log=relay-bin、read-only=1(防止误写)、log-slave-updates=1(级联复制才需要) - GTID 模式下,主从都必须开启:
gtid-mode=ON和enforce-gtid-consistency=true,否则CHANGE MASTER TO会报错ERROR 3079
不要把主库配置直接拷给从库再改 server-id——漏掉 read-only=1 可能导致从库被应用误更新,破坏一致性。
初始化脚本执行时机与权限问题
用 /docker-entrypoint-initdb.d/ 挂载 SQL 脚本创建复制用户时,注意:
- 脚本只在容器首次启动、且
/var/lib/mysql为空时执行;重启容器不会重跑 - 主库脚本里要
CREATE USER 'repl'@'%' IDENTIFIED BY 'xxx'并GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' - 从库脚本里不能执行
CHANGE MASTER TO——此时主库可能还没就绪;应等容器启动完成,手动进从库执行,或用healthcheck+depends_on控制顺序 - MySQL 8.0+ 默认认证插件是
caching_sha2_password,Navicat 等旧客户端连不上,得在脚本里加ALTER USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx'
最易忽略的是:从库执行 CHANGE MASTER TO 时,MASTER_HOST 必须填 Docker 网络内可达地址(如自定义网络中的容器名 mysql-master 或固定 IP),不能填 localhost 或宿主机 127.0.0.1。


















