mysql主从同步失败主因是server-id和log-bin未生效,docker中须用command显式传参而非环境变量,且必须共用自定义网络、禁用bind-address、使用mysql_native_password插件并严格按show master status结果配置source_log_file和source_log_pos。

不能只靠环境变量启动就完事,主从同步失败90%出在server-id和log-bin没生效上。
docker-compose.yml里必须用command传参,别信MYSQL_SERVER_ID
MySQL 8.0 官方镜像不读MYSQL_SERVER_ID环境变量来设置运行时配置——它只影响初始化阶段。容器启动后查SHOW VARIABLES LIKE 'server_id',十有八九还是0。
- 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 - 所有服务都加进这个网络:
networks: [- mysql-net] - master和slave的配置里**绝对不要出现
bind-address**,让它监听0.0.0.0:3306 - 从库连接主库时,host填
mysql-master(服务名),不是localhost或宿主机IP
复制用户必须指定mysql_native_password插件
MySQL 8.0 默认用caching_sha2_password,但老版本从库或某些镜像不支持,导致IO_Running: No,日志里明确报错Plugin caching_sha2_password could not be loaded。
- 主库登录后执行:
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl123'; - 再执行:
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; - 千万别用
IDENTIFIED BY省略插件声明,MySQL 8.0 会默认选caching_sha2_password
启动复制前必须手动获取并设置File和Position
光执行CHANGE REPLICATION SOURCE TO不够,MASTER_LOG_FILE和MASTER_LOG_POS必须来自主库当前的SHOW MASTER STATUS输出,不能硬编码或猜。
- 先在master容器里执行:
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
最容易被忽略的是:command参数顺序不影响,但--server-id必须在--log-bin之前;另外docker-compose up -d后别急着配复制,等两个容器docker ps显示healthy再操作,否则主库可能还没完成初始化。











