如何搭建mysql容器集群环境_mysql环境扩展方案

8次阅读

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

如何搭建 mysql 容器集群环境_mysql 环境扩展方案

用 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 STATUS

Seconds_Behind_Master 显示为 0 不代表数据一致——它只反映 relay log 回放延迟,不检测逻辑冲突或误删。尤其在手动干预 binlog、跳过错误(SET GLOBAL SQL_SLAVE_SKIP_COUNTER)后,极易静默失配。

推荐做法:

  • pt-table-checksum(Percona Toolkit)定期校验表级 checksum,它通过主库生成校验值、从库执行对应查询比对
  • 避免在从库写入:确认 read_only=ONsuper_read_only=ON(MySQL 5.7+)已生效,否则 INSERT/UPDATE 会绕过复制直接落盘
  • 检查 Replica_IO_RunningReplica_SQL_Running 必须同时为 Yes;任一为 No 都需查 Last_IO_ErrorLast_SQL_Error

扩展读节点时,不要复用同一份初始化 SQL

多个从库如果都用同一个 mysqldump 文件导入,会导致所有从库的 GTID_EXECUTED 集合完全相同——后续主库发生故障切换后,新主库无法正确判断哪些事务已被哪些从库执行,GTID 复制会卡死。

正确流程:

  • 每个从库必须基于主库当前 SHOW MASTER STATUSExecuted_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_loadrelay_log_recovery

Docker 重启容器时,MySQL 默认不会自动恢复复制线程。即使配置了 restart: always,也仅重启 mysqld 进程,不触发 START REPLICA

解决方法

  • 在从库 配置文件 中显式启用 relay_log_recovery=ON(MySQL 5.6.2+),确保崩溃后能自动重建 relay log
  • 主库需设置 sync_binlog=1innodb_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;

text=ZqhQzanResources