meta-description: 使用Docker Compose部署MySQL主从复制完整教程,详解读写分离配置和故障转移。

keywords: Docker Compose,MySQL主从,读写分离,数据库集群,主从复制

# 使用Docker Compose部署MySQL主从复制

本文详细介绍使用Docker Compose部署MySQL主从复制架构,实现读写分离和高可用。

## 主从复制原理

| 角色 | 作用 | 说明 |

|------|------|------|

| Master | 主库 | 处理写操作,记录binlog |

| Slave | 从库 | 拉取binlog,重放SQL |

| 延迟 | 复制延迟 | 通常<1秒 |

## 目录结构


mysql-replication/
├── docker-compose.yml
├── master/
│   ├── my.cnf
│   └── init.sql
├── slave/
│   ├── my.cnf
│   └── init.sql
└── .env

## docker-compose.yml


version: '3.8'

services:
  mysql-master:
    image: mysql:8.0
    container_name: mysql-master
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: master_root_pass
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: wp_pass
    volumes:
      - ./master/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./master/init.sql:/docker-entrypoint-initdb.d/init.sql
      - master-data:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - mysql-replication

  mysql-slave:
    image: mysql:8.0
    container_name: mysql-slave
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: slave_root_pass
    volumes:
      - ./slave/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./slave/init.sql:/docker-entrypoint-initdb.d/init.sql
      - slave-data:/var/lib/mysql
    ports:
      - "3307:3306"
    networks:
      - mysql-replication
    depends_on:
      - mysql-master

volumes:
  master-data:
  slave-data:

networks:
  mysql-replication:
    driver: bridge

## Master配置

### master/my.cnf


[mysqld]
# 服务器ID(集群中唯一)
server-id = 1

# 开启binlog
log_bin = /var/log/mysql/mysql-bin.log

# binlog格式(ROW推荐)
binlog_format = ROW

# 同步刷盘
sync_binlog = 1

# 需要复制的数据库
binlog_do_db = wordpress

# 忽略的数据库
binlog_ignore_db = mysql
binlog_ignore_db = information_schema
binlog_ignore_db = performance_schema

# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

### master/init.sql


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

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

-- 刷新权限
FLUSH PRIVILEGES;

-- 创建用于读操作的用户
CREATE USER 'wp_read'@'%' IDENTIFIED BY 'read_password';
GRANT SELECT ON wordpress.* TO 'wp_read'@'%';
FLUSH PRIVILEGES;

## Slave配置

### slave/my.cnf


[mysqld]
# 服务器ID(集群中唯一)
server-id = 2

# 中继日志
relay_log = /var/log/mysql/relay-bin

# 只读模式
read_only = 1

# 超级用户也只读(可选)
super_read_only = 1

# 需要复制的数据库
replicate_do_db = wordpress

# 忽略的表
replicate_ignore_table = wordpress.wp_options

# 并行复制
slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK

character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

### slave/init.sql


-- 配置主库信息(Docker网络内用服务名)
CHANGE MASTER TO
  MASTER_HOST='mysql-master',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl_password',
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=156;

-- 启动复制
START SLAVE;

## 启动集群


# 启动Master
docker-compose up -d mysql-master

# 等待Master完全启动
docker-compose logs -f mysql-master
# 看到 "ready for connections" 后继续

# 启动Slave
docker-compose up -d mysql-slave

# 查看状态
docker-compose ps

## 验证主从复制

### 在Master上操作


# 进入Master容器
docker exec -it mysql-master mysql -uroot -pmaster_root_pass

# 查看Master状态
SHOW MASTER STATUS\G
/*
File: mysql-bin.000001
Position: 156
Binlog_Do_DB: wordpress
*/

# 创建测试数据
USE wordpress;
CREATE TABLE test_repl (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50));
INSERT INTO test_repl (name) VALUES ('replication_test');

### 在Slave上验证


# 进入Slave容器
docker exec -it mysql-slave mysql -uroot -pslave_root_pass

# 查看Slave状态
SHOW SLAVE STATUS\G

/*
关键字段:
Slave_IO_Running: Yes    ← 必须为Yes
Slave_SQL_Running: Yes   ← 必须为Yes
Seconds_Behind_Master: 0  ← 延迟秒数
Last_Error:              ← 应为空
*/

# 验证数据同步
USE wordpress;
SELECT * FROM test_repl;
-- 应该能看到在Master插入的数据

## WordPress配置读写分离

### wp-config.php配置


// 主库(写)
define('DB_HOST', 'mysql-master:3306');

// 使用插件实现读写分离,或手动配置:
// 推荐插件:HyperDB 或 LudicrousDB

### 使用HyperDB插件


// hyperdb-config.php

// 写服务器(主库)
$wpdb->add_database(array(
    'host'     => 'mysql-master:3306',
    'user'     => 'wp_user',
    'password' => 'wp_pass',
    'name'     => 'wordpress',
    'write'    => 1,
    'read'     => 1,  // 主库也参与读(可选)
));

// 读服务器(从库)
$wpdb->add_database(array(
    'host'     => 'mysql-slave:3306',
    'user'     => 'wp_read',
    'password' => 'read_password',
    'name'     => 'wordpress',
    'write'    => 0,  // 不用于写
    'read'     => 1,
));

## 故障转移

### 手动提升Slave为Master


# 1. 在Slave上停止复制
docker exec -it mysql-slave mysql -uroot -pslave_root_pass \
  -e "STOP SLAVE;"

# 2. 将Slave设为可写
docker exec -it mysql-slave mysql -uroot -pslave_root_pass \
  -e "SET GLOBAL read_only = OFF;"

# 3. 修改应用配置指向新Master
# 修改 wp-config.php 的 DB_HOST

### 使用Orchestrator(自动化)


# docker-compose.yml 添加orchestrator
  orchestrator:
    image: openarkdb/orchestrator:latest
    container_name: orchestrator
    ports:
      - "3000:3000"
    command: >
      --config=/etc/orchestrator.conf.json
    volumes:
      - ./orchestrator.conf.json:/etc/orchestrator.conf.json
    networks:
      - mysql-replication

## 监控复制状态

### 监控脚本


#!/bin/bash
# check-replication.sh

CONTAINER="mysql-slave"
THRESHOLD=60  # 延迟阈值(秒)

delay=$(docker exec $CONTAINER mysql -uroot -pslave_root_pass \
  -e "SHOW SLAVE STATUS\G" | grep "Seconds_Behind_Master" | awk '{print $2}')

if [ "$delay" == "NULL" ] || [ "$delay" -gt "$THRESHOLD" ]; then
    echo "告警:复制延迟 ${delay} 秒!"
    # 发送告警(邮件/微信/钉钉)
fi

### 添加到Cron


# 每5分钟检查一次
*/5 * * * * /scripts/check-replication.sh

## 备份策略


# 在Slave上备份(不影Master性能)
docker exec mysql-slave mysqldump \
  -uroot -pslave_root_pass \
  --single-transaction \
  --routines \
  --triggers \
  --all-databases > backup_$(date +%Y%m%d).sql

# 压缩备份
gzip backup_*.sql

## 常见问题

| 问题 | 原因 | 解决方案 |

|------|------|----------|

| Slave_IO_Running=No | 网络问题/密码错误 | 检查MASTER_HOST/PASSWORD |

| Slave_SQL_Running=No | 数据冲突 | SET GLOBAL sql_slave_skip_counter=1 |

| 延迟持续增大 | Slave性能差 | 增加slave_parallel_workers |

| 主从数据不一致 | 误操作 | 重新全量同步 |

## 性能优化


# Master优化(my.cnf)
innodb_flush_log_at_trx_commit = 2  # 提高写性能
sync_binlog = 0                        # 由操作系统刷盘

# Slave优化(my.cnf)
innodb_flush_log_at_trx_commit = 2
sync_binlog = 0
slave_parallel_workers = 8  # 并行复制线程数

使用Docker Compose部署MySQL主从复制,可以快速搭建高可用数据库集群,提升WordPress的读取性能。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。