mysql 8.0 主从复制在 docker compose 中失败主因是 server-id 和 log-bin 未生效:官方镜像不读 mysql_server_id 环境变量做运行时配置,必须通过 command 显式传参(如 "--server-id=1" "--log-bin")或挂载权限为644的 /etc/mysql/conf.d/my.cnf。

MySQL 8.0 主从复制在 Docker Compose 中跑不起来,90% 是因为 server-id 和 log-bin 根本没生效——官方镜像压根不读 MYSQL_SERVER_ID 环境变量做运行时配置,只用它初始化数据库。
command 必须显式传参,不能靠 environment
MySQL 8.0 容器启动后执行 SHOW VARIABLES LIKE 'server_id',返回 0 就说明配置失败;log_bin 显示 OFF 则主从同步必然断。这是因为官方镜像的 entrypoint 脚本只把 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"] - 挂载
/etc/mysql/conf.d/my.cnf也行,但文件权限必须是644,路径必须是/etc/mysql/conf.d/下的.cnf文件,否则 Docker 静默忽略 - 绝对不要在
environment里写MYSQL_SERVER_ID,纯属误导
网络和 bind-address 错误导致从库连不上主库
报错 Can't connect to MySQL server on 'mysql-master' (115),基本就是网络或监听地址问题。默认 mysqld 只监听 127.0.0.1,容器内用服务名根本连不通。
- 先手动创建专用网络:
docker network create mysql-net -
docker-compose.yml 中所有服务都加入该网络:
networks: [- mysql-net] - master 和 slave 的配置里**不能出现
bind-address**,删掉或注释掉,让 mysqld 监听0.0.0.0:3306 - 从库连接主库时,
SOURCE_HOST填服务名(如mysql-master),不是localhost或宿主机 IP
IO_Running: No?大概率是认证插件不匹配
从库执行 SHOW REPLICA STATUS\G 后看到 IO_Running: No,日志里出现 Plugin caching_sha2_password could not be loaded,这就是 MySQL 8.0 默认插件惹的祸——很多旧版客户端、从库镜像或中间件不支持它。
- 主库创建复制用户时,必须显式指定插件:
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl123'; - 紧接着执行:
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; - 千万别省略
IDENTIFIED WITH,写成IDENTIFIED BY会让 MySQL 8.0 自动选caching_sha2_password - 如果要用 GTID 模式,master 还需加
--enforce-gtid-consistency=ON --gtid-mode=ON,slave 对应加--gtid-mode=ON
CHANGE REPLICATION SOURCE TO 之前必须手动查主库状态
光执行 CHANGE REPLICATION SOURCE TO 不够,SOURCE_LOG_FILE 和 SOURCE_LOG_POS 必须严格对应主库当前的 binlog 位置,硬编码或凭空猜测都会导致同步卡住或丢数据。
- 进 master 容器:
docker exec -it mysql-master mysql -uroot -proot123 - 执行:
SHOW MASTER STATUS;,记下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 容器后,binlog 文件和 position 都会变,从库必须重新查、重新配;另外,command 参数顺序无关紧要,但少任何一个关键项(比如漏了 --log-bin 或 --relay-log),复制就起不来。











