结论:MySQL 8.0 官方镜像不读 MYSQL_SERVER_ID 环境变量设置运行时配置,仅用于初始化;server-id 和 log-bin 必须通过 command 显式传参(如 "--server-id=1" "--log-bin")或挂载 /etc/mysql/conf.d/ 下权限为644的 my.cnf 才生效,否则 SHOW VARIABLES 显示 server_id=0、log_bin=OFF,主从复制必然失败。

直接说结论:不能只靠 environment 启动就完事,90% 的同步失败源于 server-id 和 log-bin 没生效——MySQL 8.0 官方镜像根本不读 MYSQL_SERVER_ID 环境变量来设置运行时配置。
为什么 command 必须显式传参,而不是用环境变量
MySQL 8.0 容器启动后查 SHOW VARIABLES LIKE 'server_id',十有八九返回 0;log-bin 默认完全关闭。这是因为官方镜像只把 MYSQL_SERVER_ID 等环境变量用于初始化阶段(如首次建库),不写入运行时 mysqld 配置。
- master 必须写:
command: ["--server-id=1", "--log-bin", "--binlog-format=ROW"] - slave 必须写:
command: ["--server-id=2", "--relay-log", "--relay-log-info-repository=TABLE"] - 挂载
my.cnf也行,但必须确保路径是/etc/mysql/conf.d/xxx.cnf且权限为644,否则 Docker 静默忽略 - 绝对不要在
environment里写MYSQL_SERVER_ID,纯属误导
主从连不上?大概率是网络和 bind-address 搞错了
默认 MySQL 容器只监听 127.0.0.1,从库用服务名(如 mysql-master)根本连不上,报错 Can't connect to MySQL server on 'mysql-master' (115) 就是这个原因。
- 主从必须共用自定义网络:
docker network create mysql-net,然后在docker-compose.yml中所有服务都加入该网络 - master 和 slave 的配置里**不能出现
bind-address**,让它监听0.0.0.0:3306 - 从库连接主库时,
SOURCE_HOST填服务名(如mysql-master),不是localhost或宿主机 IP
从库 IO_Running: No?认证插件不匹配
MySQL 8.0 默认用 caching_sha2_password,但很多从库镜像或老客户端不支持,日志里会明确报错:Plugin caching_sha2_password could not be loaded。
- 主库创建复制用户时,必须显式指定插件:
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl123'; - 千万别省略
IDENTIFIED WITH,写成IDENTIFIED BY会让 MySQL 8.0 默认选caching_sha2_password - 如果要用 GTID 模式,主库还需加
--enforce-gtid-consistency=ON --gtid-mode=ON,slave 对应加--gtid-mode=ON
启动复制前必须手动获取并设置 SOURCE_LOG_FILE 和 SOURCE_LOG_POS
光执行 CHANGE REPLICATION SOURCE TO 不够,SOURCE_LOG_FILE 和 SOURCE_LOG_POS 必须来自主库当前的 SHOW MASTER STATUS 输出,不能硬编码或猜。
- 先进 master 容器:
docker exec -it mysql-master mysql -uroot -proot -e "SHOW MASTER STATUS\G" - 记下
File(如mysql-bin.000003)和Position(如154) - 再进 slave 执行:
CHANGE REPLICATION SOURCE TO SOURCE_HOST='mysql-master', SOURCE_USER='repl', SOURCE_PASSWORD='repl123', SOURCE_LOG_FILE='mysql-bin.000003', SOURCE_LOG_POS=154; - 最后
START REPLICA;,再SHOW REPLICA STATUS\G看IO_Running和SQL_Running是否都为Yes
最易被忽略的是:每次重启 master 容器后,SHOW MASTER STATUS 的 Position 可能重置,从库必须重新同步;另外,command 里的参数顺序无关紧要,但任何拼写错误(比如 --log-bin 写成 --log_bin)都会导致 mysqld 启动失败且无明显提示。


















