第6课 docker swarm下mysql主从服务器的搭建

第6课 docker swarm下mysql主从服务器的搭建

🧙♂️ MySQL主从复制部署完整指南

📋 前置准备 

# 创建数据目录(在主节点和从节点都要执行)
sudo mkdir -p /mnt/sdc/mysql8/master/data /mnt/sdc/mysql8/master/conf
sudo mkdir -p /mnt/sdc/mysql8/slave/data /mnt/sdc/mysql8/slave/conf

# 设置目录权限
sudo chmod -R 755 /mnt/sdc/mysql8/

📝 第一步:创建主库配置文件

主库配置 /mnt/sdc/mysql8/master/conf/my.cnf

[mysqld]
server-id = 1
log-bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON

# 需要同步的数据库(可选)
# binlog-do-db = testdb

# 忽略同步的数据库
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys

[mysql]
default-character-set = utf8mb4

📝 第二步:创建从库配置文件

从库配置 /mnt/sdc/mysql8/slave/conf/my.cnf: 

[mysqld]
server-id = 2
relay-log = mysql-relay-bin
read_only = ON
super_read_only = ON
gtid_mode = ON
enforce_gtid_consistency = ON

[mysql]
default-character-set = utf8mb4

🐳 第三步:创建Docker Stack部署文件

mysql-stack.yml: 

# Docker Compose 文件版本 (兼容 Swarm 模式)
version: "3.8"

services:
  # 主数据库服务定义
  mysql-master:
    # 使用 MySQL 8.2 官方镜像 (实际使用时建议确认版本可用性)
    image: mysql:8.2

    # Swarm 部署配置
    deploy:
      replicas: 1 # 主库单实例运行
      placement:
        constraints: 
          - node.hostname==uubuntu  # 明确指定在manager节点运行
      restart_policy: # 重启策略配置
        condition: on-failure # 仅在失败时重启
        delay: 5s # 重启间隔5秒
        max_attempts: 1 # 最多尝试3次

    # 网络端口映射 (暴露主库3306端口到宿主机)
    ports:
      - "3306:3306"

    # 数据卷绑定挂载 (将宿主机目录映射到容器内)
    volumes:
      - type: bind # 日志目录绑定
        source: /mnt/sdc/mysql8/master/log
        target: /var/log/mysql
      - type: bind # 数据目录绑定
        source: /mnt/sdc/mysql8/master/data
        target: /var/lib/mysql
      - type: bind # 初始化脚本目录
        source: ./master-init
        target: /docker-entrypoint-initdb.d

    # 环境变量配置
    environment:
      MYSQL_ROOT_PASSWORD: "123456" # 设置root密码
      MYSQL_ROOT_HOST: "%" # 允许root远程访问 (MySQL 8.x 必需)

    # MySQL 服务器启动参数
    command:
      - --server-id=1     # 唯一服务器ID (主从必须不同)
      - --log-bin=mysql-bin # 启用二进制日志
      - --binlog-format=ROW # 使用行级日志格式
      - --log-slave-updates=ON  # 记录从库更新到二进制日志
      - --gtid-mode=ON  # 启用全局事务ID (GTID)
      - --enforce-gtid-consistency=ON # 强制GTID一致性
      - --binlog-transaction-dependency-tracking=WRITESET # MySQL 8 复制优化

    # 健康检查配置
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p123456"]
      interval: 5s # 每5秒检查一次
      timeout: 5s # 超时时间5秒
      retries: 10 # 连续失败10次判定为不健康

  # 从数据库服务定义
  mysql-slave:
    image: mysql:8.2
    deploy:
      replicas: 1 # 从库单实例运行
      placement:
        constraints: 
          - node.hostname==ubuntumini  # 明确指定在worker节点运行
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 1

    # 数据卷绑定 (与主库分离的目录)
    volumes:
      - type: bind
        source: /mnt/sdc/mysql8/slave/log
        target: /var/log/mysql
      - type: bind
        source: /mnt/sdc/mysql8/slave/data
        target: /var/lib/mysql
      - type: bind # 从库初始化脚本目录
        source: ./slave-init
        target: /docker-entrypoint-initdb.d

    # 环境变量 (密码需与主库一致)
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
      MYSQL_ROOT_HOST: "%"

    # 从库专用启动参数
    command:
      - --server-id=2   # 唯一服务器ID (从库必须不同于主库)
      - --log-bin=mysql-bin # 启用二进制日志
      - --binlog-format=ROW # 使用行级日志格式
      - --log-slave-updates=ON  # 记录从库更新到二进制日志
      - --gtid-mode=ON  # 启用全局事务ID (GTID)
      - --enforce-gtid-consistency=ON # 强制GTID一致性
      - --skip-slave-start  # 启动时不自动开始复制
      - --read-only=ON  # 设置从库为只读模式
      - --relay-log=mysql-relay-bin # 启用中继日志
      - --relay-log-index=mysql-relay-bin.index # 中继日志索引文件

    # 健康检查配置 (用于验证复制配置是否完成)
    healthcheck:
#      test: [
#        "CMD-SHELL",
#        "test -f /var/lib/mysql/slave.configured || (mysql -uroot -p123456 -e 'SHOW SLAVE STATUS\\G' | grep -q 'Waiting for master')"
#      ]
      test: ["CMD", "mysqladmin", "ping", "-uroot", "-p123456"]
      interval: 10s
      timeout: 5s
      retries: 12

    # Compose v3 不支持 depends_on 的健康依赖,已移除

# 共享网络配置 (使用预先创建的overlay网络)
networks:
  default:
    name: backend_network  # 新推荐写法(省略 external)
    external: true

🚀 第四步:部署MySQL集群

 
# 部署Stack
docker stack deploy -c mysql-stack.yml mysql

# 查看服务状态
docker service ls
docker service ps mysql_mysql-master
docker service ps mysql_mysql-slave

⚙️ 第五步:配置主库复制用户

# 进入主库容器
docker exec -it mysql-master mysql -uroot -p123456

在主库中执行:

-- 创建复制用户
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_password';

-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

-- 刷新权限
FLUSH PRIVILEGES;

-- 查看主库状态(记录File和Position)
SHOW MASTER STATUS\G

🔗 第六步:配置从库复制

# 进入从库容器
docker exec -it mysql-slave mysql -uroot -p123456

在从库中执行: 

-- 配置主从复制
CHANGE MASTER TO
    MASTER_HOST='mysql-master',
    MASTER_USER='repl',
    MASTER_PASSWORD='repl_password',
    MASTER_AUTO_POSITION = 1;

-- 启动复制
START SLAVE;

-- 查看复制状态
SHOW SLAVE STATUS\G

应看到:
        Slave_IO_Running: Yes
        Slave_SQL_Running: Yes
        Seconds_Behind_Master: 0

✅ 第七步:验证主从复制

测试数据同步 

# 在主库创建测试数据
docker exec -it mysql-master mysql -uroot -p123456 -e "
CREATE DATABASE IF NOT EXISTS testdb;
USE testdb;
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO users (name) VALUES ('Alice'), ('Bob'), ('Charlie');
"

# 在从库检查数据同步
docker exec -it mysql-slave mysql -uroot -p123456 -e "
USE testdb;
SELECT * FROM users;
SHOW SLAVE STATUS\G
"

🎯 第八步:监控和维护脚本

创建监控脚本 check_replication.sh

 
#!/bin/bash

echo "🔍 检查MySQL主从复制状态..."

# 检查主库状态
echo "=== 主库状态 ==="
docker exec mysql-master mysql -uroot -p123456 -e "SHOW MASTER STATUS\G"

echo -e "\n=== 从库状态 ==="
docker exec mysql-slave mysql -uroot -p123456 -e "SHOW SLAVE STATUS\G" | grep -E "Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master|Last_Error"

echo -e "\n=== 测试数据同步 ==="
docker exec mysql-master mysql -uroot -p123456 -e "
USE testdb;
INSERT INTO users (name) VALUES ('Test_' || DATE_FORMAT(NOW(), '%H%i%s'));
SELECT COUNT(*) as total_users FROM users;
"

sleep 2

docker exec mysql-slave mysql -uroot -p123456 -e "
USE testdb;
SELECT COUNT(*) as slave_users FROM users;
"

给脚本执行权限: 

chmod +x check_replication.sh
./check_replication.sh

🛠 第九步:一键修复脚本

创建修复脚本 fix_replication.sh

 
#!/bin/bash

echo "🔧 开始修复MySQL主从复制..."

# 停止从库复制
docker exec mysql-slave mysql -uroot -p123456 -e "STOP SLAVE; RESET SLAVE ALL;"

# 重新配置复制
docker exec mysql-slave mysql -uroot -p123456 -e "
CHANGE MASTER TO
    MASTER_HOST='mysql-master',
    MASTER_USER='repl',
    MASTER_PASSWORD='repl_password',
    MASTER_AUTO_POSITION = 1;
START SLAVE;
"

# 检查修复结果
echo "✅ 修复完成,检查状态:"
docker exec mysql-slave mysql -uroot -p123456 -e "SHOW SLAVE STATUS\G" | grep -E "Slave_IO_Running|Slave_SQL_Running|Last_Error"

📊 第十步:健康检查指标

正常的复制状态应该显示:

  • ✅ Slave_IO_Running: Yes

  • ✅ Slave_SQL_Running: Yes

  • ✅ Seconds_Behind_Master: 0

  • ✅ Last_Error: (空)

如果出现问题:

bash
 
# 查看详细错误信息
docker exec mysql-slave mysql -uroot -p123456 -e "SHOW SLAVE STATUS\G" | grep Last_Error

# 跳过特定错误(谨慎使用)
docker exec mysql-slave mysql -uroot -p123456 -e "STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE;"

🎩 魔法总结

部署成功的关键步骤:

  1. ✅ 正确配置主从my.cnf文件

  2. ✅ 创建复制用户并授权

  3. ✅ 使用GTID自动定位(MASTER_AUTO_POSITION=1

  4. ✅ 验证数据实时同步

(魔法杖挥出绿色成功光芒)✨ 恭喜!你现在已经掌握了MySQL主从复制的完整魔法!

记住定期检查: 

# 每天检查一次复制状态
0 2 * * * /path/to/check_replication.sh >> /var/log/mysql_replication.log

现在你的数据库拥有了高可用性和数据备份的超能力!🐋🚀

给TA打赏
共{{data.count}}人
人已打赏
Docker

第5课 本地镜像发布到私有库

2025-8-28 11:43:16

执行策划

优秀的主策划必须是一名优秀的执行策划

2025-8-11 18:03:08

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索