
1. 项目概述MySQL主从复制是企业级数据库架构中的基础配置方案而Docker容器化部署正逐渐成为现代运维的标准实践。将两者结合既能发挥容器化的快速部署优势又能实现传统数据库的高可用特性。我在最近的生产环境迁移项目中完整实践了基于Docker的MySQL 8主从复制方案过程中踩遍了几乎所有可能的坑——从网络配置冲突到GTID同步异常从权限设置错误到字符集不匹配。本文将呈现经过实战检验的完整配置流程包含那些官方文档不会告诉你的细节陷阱。2. 环境准备与拓扑设计2.1 容器网络规划主从复制对网络延迟敏感推荐使用自定义bridge网络而非默认的docker0网络。以下创建专用网络的命令包含MTU优化参数docker network create \ --driver bridge \ --subnet172.28.0.0/16 \ --gateway172.28.5.1 \ --opt com.docker.network.bridge.mtu1500 \ mysql-replication-net注意MTU值需要与宿主机的物理网卡保持一致通过ifconfig查看容器间巨型帧传输失败是常见同步中断原因。2.2 存储卷配置数据持久化必须使用volume而非bind mount避免权限问题docker volume create mysql-master-data docker volume create mysql-slave-data验证volume路径是否符合MySQL的datadir要求docker run --rm -v mysql-master-data:/var/lib/mysql alpine \ ls -ld /var/lib/mysql3. 主库配置实战3.1 主库容器启动使用官方mysql:8.0镜像启动主库关键参数包括server-id和log-bindocker run -d --name mysql-master \ --network mysql-replication-net \ --ip 172.28.5.10 \ -v mysql-master-data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORDMaster123 \ -e MYSQL_ROOT_HOST% \ mysql:8.0 \ --server-id1 \ --log-binmysql-bin \ --binlog-formatROW \ --binlog-row-imageFULL \ --sync_binlog1 \ --gtid-modeON \ --enforce-gtid-consistencyON3.2 主库关键配置解析binlog-row-imageFULL确保所有列数据都写入binlog避免从库更新时因缺少字段报错sync_binlog1每次事务提交都同步binlog到磁盘牺牲部分性能保证数据安全GTID模式全局事务标识符能简化故障转移和位置追踪3.3 创建复制账户进入主库容器执行CREATE USER repl172.28.5.% IDENTIFIED WITH mysql_native_password BY Repl123; GRANT REPLICATION SLAVE ON *.* TO repl172.28.5.%; ALTER USER repl172.28.5.% IDENTIFIED WITH mysql_native_password BY Repl123;血泪教训MySQL 8默认使用caching_sha2_password插件必须显式指定mysql_native_password否则从库连接会报Authentication plugin error。4. 从库配置与同步启动4.1 从库容器启动docker run -d --name mysql-slave \ --network mysql-replication-net \ --ip 172.28.5.11 \ -v mysql-slave-data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORDSlave123 \ mysql:8.0 \ --server-id2 \ --log-binmysql-bin \ --binlog-formatROW \ --gtid-modeON \ --enforce-gtid-consistencyON \ --skip-slave-start4.2 配置主从连接获取主库GTID位置SHOW MASTER STATUS\G -- 记录Executed_Gtid_Set值如3a59f153-4f4e-11ec-9a1e-0242ac110002:1-10在从库执行CHANGE MASTER命令CHANGE MASTER TO MASTER_HOST172.28.5.10, MASTER_USERrepl, MASTER_PASSWORDRepl123, MASTER_AUTO_POSITION1; START SLAVE;4.3 验证复制状态关键指标检查SHOW SLAVE STATUS\G -- Slave_IO_Running: Yes -- Slave_SQL_Running: Yes -- Seconds_Behind_Master: 0 -- Retrieved_Gtid_Set与Executed_Gtid_Set应与主库匹配5. 深度踩坑实录5.1 时区不一致导致timestamp字段异常现象主库插入的timestamp字段在从库显示不同值 解决方案# 启动容器时统一时区 -e TZAsia/Shanghai --default-time-zone8:005.2 大事务导致复制中断错误日志Worker 1 failed executing transaction... 处理方法-- 主库配置 SET GLOBAL binlog_group_commit_sync_delay 100; SET GLOBAL binlog_group_commit_sync_no_delay_count 10; -- 从库恢复 STOP SLAVE; SET GLOBAL sql_slave_skip_counter1; START SLAVE;5.3 容器重启后复制失效根本原因从库的master.info未持久化 解决方案# 创建专用配置卷 docker volume create mysql-slave-conf # 启动时挂载配置文件 -v mysql-slave-conf:/etc/mysql/conf.d \ --relay-logslave-relay-bin \ --relay-log-indexslave-relay-bin.index6. 完整验证方案6.1 基础数据同步测试-- 主库操作 CREATE DATABASE replica_test; USE replica_test; CREATE TABLE users(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50)); INSERT INTO users(name) VALUES(测试用户); -- 从库验证 SELECT * FROM replica_test.users;6.2 故障转移演练模拟主库宕机docker stop mysql-master -- 从库提升为主库 STOP SLAVE; RESET SLAVE ALL; SET GLOBAL read_onlyOFF;6.3 延迟压力测试使用sysbench制造负载sysbench oltp_read_write \ --db-drivermysql \ --mysql-host172.28.5.10 \ --mysql-userroot \ --mysql-passwordMaster123 \ --mysql-dbreplica_test \ --tables5 \ --table-size100000 \ --time300 \ --threads16 \ --report-interval10 \ run监控从库延迟-- 在从库执行 SHOW SLAVE STATUS\G -- 观察Seconds_Behind_Master波动7. 性能优化建议7.1 容器资源限制# 主库容器启动时添加 --memory4g --memory-swap4g \ --cpus2 \ --blkio-weight5007.2 MySQL参数调优主库my.cnf追加innodb_flush_log_at_trx_commit1 innodb_buffer_pool_size2G binlog_group_commit_sync_delay100 binlog_group_commit_sync_no_delay_count10从库my.cnf追加read_onlyON slave_parallel_workers4 slave_parallel_typeLOGICAL_CLOCK7.3 监控方案推荐使用Prometheusmysqld_exporterGrafana组合关键监控指标复制延迟(seconds_behind_master)IO/SQL线程状态(slave_io_running, slave_sql_running)网络往返时间(rtt)