Docker Compose 启动 MySQL 主从复制需明确角色分离:主库启用 log-bin 与 server-id=1,从库设不同 server-id=2 且 read_only=ON;须手动配置 CHANGE REPLICATION SOURCE TO,导入数据时注意 GTID 一致性,并启用 relay_log_recovery 确保重启后自动恢复复制。

用 Docker Compose 启动主从复制集群,不是单节点伪集群
单个 mysql:8.0 容器跑起来容易,但真要模拟生产级读写分离,必须明确区分主库(master)和从库(slave)角色。Docker 默认不自动配置复制关系,靠容器名通信、CHANGE REPLICATION SOURCE TO 手动指定源,才是可控路径。
关键点:
- 主库需开启
log-bin和唯一server-id(如1) - 从库
server-id必须不同(如2),且不能启用log-bin(除非做级联复制) - 主库导出数据时加
--master-data=2,才能在 dump 文件里嵌入CHANGE REPLICATION SOURCE TO语句 - 从库启动后执行
START REPLICA;(MySQL 8.0.22+ 已弃用SLAVE说法)
version: '3.8'
services:
mysql-master:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
command: >
--server-id=1
--log-bin=mysql-bin
--binlog-format=ROW
--skip-host-cache
--skip-name-resolve
ports:
- "3307:3306"
volumes:
- ./master.cnf:/etc/mysql/conf.d/master.cnf
mysql-slave:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
command: >
--server-id=2
--read_only=ON
--skip-host-cache
--skip-name-resolve
ports:
- "3308:3306" volumes:
- ./slave.cnf:/etc/mysql/conf.d/slave.cnf depends_on:
- mysql-master
主从数据一致性校验不能只靠
SHOW REPLICA STATUSSeconds_Behind_Master显示为0不代表数据一致——它只反映 relay log 回放延迟,不检测逻辑冲突或误删。尤其在手动干预 binlog、跳过错误(SET GLOBAL SQL_SLAVE_SKIP_COUNTER)后,极易静默失配。推荐做法:
- 用
pt-table-checksum(Percona Toolkit)定期校验表级 checksum,它通过主库生成校验值、从库执行对应查询比对 - 避免在从库写入:确认
read_only=ON且super_read_only=ON(MySQL 5.7+)已生效,否则INSERT/UPDATE会绕过复制直接落盘 - 检查
Replica_IO_Running和Replica_SQL_Running必须同时为Yes;任一为No都需查Last_IO_Error或Last_SQL_Error
扩展读节点时,不要复用同一份初始化 SQL
多个从库如果都用同一个
mysqldump文件导入,会导致所有从库的GTID_EXECUTED集合完全相同——后续主库发生故障切换后,新主库无法正确判断哪些事务已被哪些从库执行,GTID 复制会卡死。正确流程:
- 每个从库必须基于主库当前
SHOW MASTER STATUS的Executed_Gtid_Set做初始同步 - 用
mysqldump --set-gtid-purged=OFF导出(避免覆盖原有 GTID 集合) - 导入后,在从库执行
SET GLOBAL gtid_purged = 'xxx-xxx-xxx:1-100';(值来自主库gtid_executed) - 再执行
CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 1;
容器重启后复制中断?检查
replica_load和relay_log_recoveryDocker 重启容器时,MySQL 默认不会自动恢复复制线程。即使配置了
restart: always,也仅重启 mysqld 进程,不触发START REPLICA。解决方法:
- 在从库配置文件中显式启用
relay_log_recovery=ON(MySQL 5.6.2+),确保崩溃后能自动重建 relay log - 主库需设置
sync_binlog=1和innodb_flush_log_at_trx_commit=1,防止断电丢 binlog - 更稳妥的做法是写一个轻量级健康检查脚本,在容器启动后调用
mysql -h mysql-master -e "START REPLICA;",并捕获返回码
MySQL 容器集群最难缠的不是启动,而是状态漂移——网络抖动、时钟不同步、磁盘 I/O 延迟都会让复制线程悄无声息地停在某个事务上。别信日志里那句 “Replica running”,得定时查
SELECT * FROM performance_schema.replication_connection_status;。 - 用










