Docker 部署生产环境可用的 MySQL 主从架构

简介

跨云服务器一主一从,可以自己按照逻辑配置多个从服务器

假设主服务器ip: 192.168.0.4 从服务器ip:192.168.0.5

系统 CentOS7.9 (停止维护了,建议大家用 Ubuntu 之类的,我这个没办法,前人在云服务器上搞的,但是有生产数据又不能乱动)

考虑到公司的实际情况,网络相对也安全,所以暂时不配置 SSL,如需 SSL 的同学请自行增加部分配置项即可!

前置配置

默认你不是小白,有些细节可能不会很详细。

  1. 我这里提前创建一个叫做common的docker网络供后续容器使用
bash 复制代码
docker network create common --driver bridge

主服务器配置

  1. 编写docker-compose.yml
yml 复制代码
services:
  mysql-master:
    image: mysql:8.0.39
    container_name: data-base-platform-mysql-master
    restart: always
    privileged: true
    # 提高文件句柄限制,适合高负载
    ulimits:
      memlock: -1
      nofile:
        soft: 1000000
        hard: 1000000

    environment:
      TZ: Asia/Shanghai
      LANG: C.UTF-8
      MYSQL_ROOT_PASSWORD: VThzb5x5POhuzR # 生产请改为强密码
      MYSQL_DATABASE: test                  # 业务库示例

    volumes:
      - ./data:/var/lib/mysql                    # 数据持久化
      - ./logs:/var/log/mysql                    # 错误日志/慢日志
      - ./conf/my.cnf:/etc/mysql/my.cnf:ro       # 主配置文件
      - ./init:/docker-entrypoint-initdb.d:ro    # 启动时自动创建复制账号
      - ./backup:/backup                         # 备份目录
    ports:
      - "23306:3306"
    networks:
      - common

    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "5"

networks:
  common:
    driver: bridge
    external: true
  1. 启动容器
bash 复制代码
# 进入docker-compose.yml文件所在目录,执行以下
docker compose up -d

# 查看日志是否正常
docker compose logs -f

# 旧版本的可能叫做 docker-compose
  1. 设置目录权限
    启动成功之后会创建对应的目录:
  • data MySQL 数据目录
  • logs 日志目录
  • conf MySQL 配置文件目录
  • backup 备份目录
  • init 容器启动后需要执行的sql脚本放在这个目录

在这些目录同级内更改目录权限,避免可能出现的一些问题

bash 复制代码
chown -R 999:999 data conf logs init backup
# 不过容器配置了 privileged: true 一般也不会有问题,按需更改权限
  1. 放入my.cnf
    my.cnf文件放入到 conf 目录下,my.cnf如下:
text 复制代码
[mysqld]
port                 = 3306             # 监听端口
# 基础身份
server-id            = 1001
# 二进制日志名,默认binlog
log-bin              = mysql-bin
binlog_format        = ROW
binlog_row_image     = FULL
# 日志轮转
binlog_expire_logs_seconds = 604800   # binlog 的保留时间 7天 = 7 * 24 * 3600
max_binlog_size      = 1G               # 单个binlog文件最大大小

# 启用GTID复制,更易管理故障转移
gtid_mode            = ON
enforce_gtid_consistency = ON           # 强制GTID一致性

log-error = /var/log/mysql/error.log    # 错误日志路径
sync_binlog          = 1                # 每事务同步binlog(高耐久性)
innodb_flush_log_at_trx_commit = 1      # 每事务刷新InnoDB日志(高耐久性)

# 安全
# require_secure_transport = ON
# ssl_ca   = /etc/mysql/ssl/ca.pem
# ssl_cert = /etc/mysql/ssl/server-cert.pem
# ssl_key  = /etc/mysql/ssl/server-key.pem

# 安全设置
skip-name-resolve                       # 跳过主机名解析,提高性能
default_authentication_plugin = mysql_native_password  # 默认认证插件

# 性能
innodb_buffer_pool_size = 8G            # InnoDB缓冲池大小
# innodb_buffer_pool_instances = 2
max_connections         = 1000

[client]  # 客户端配置节
default-character-set = utf8mb4  # 默认字符集,支持Emoji等
  1. 重启容器
bash 复制代码
# 停止
docker compose down

# 重新启动
docker compose up -d
# 查看日志是否成功启动
  1. 测试连接
    自行通过其它远程连接工具测试是否可以远程连接,如果不可以请检查防火墙以及安全组配置。也可以测试 localhost 连接看看MySQL 是否可用。不再详细赘述。
  2. 创建同步账号
bash 复制代码
# 进入 MySQL 容器,假设你的容器叫做 mysql8
docker exec -it mysql8 bash

# 登录 MySQL
mysql -uroot -p # 回车然后输入密码回车

# 执行以下创建同步账号
# 主库创建用户,用户名、密码、可访问ip(就是@后面的%里面的内容,可以自行更改)都可以自行配置
CREATE USER IF NOT EXISTS 'repl_user'@'%' IDENTIFIED BY 'aO20QLeXyQFBa';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;

# 查看状态
SHOW MASTER STATUS;

从服务器配置

  1. 编写docker-compose.yml
yml 复制代码
services:
  mysql-slave:
    image: mysql:8.0.39
    container_name: data-base-platform-mysql-slave1
    restart: always
    privileged: true
    # 提高文件句柄限制,适合高负载
    ulimits:
      memlock: -1
      nofile:
        soft: 1000000
        hard: 1000000

    environment:
      TZ: Asia/Shanghai
      LANG: C.UTF-8
      MYSQL_ROOT_PASSWORD: VThzIib5PhuzR
      MYSQL_DATABASE: test

    volumes:
      - ./data:/var/lib/mysql
      - ./logs:/var/log/mysql
      - ./conf/my.cnf:/etc/mysql/my.cnf:ro
      - ./init:/docker-entrypoint-initdb.d:ro    # 启动时自动创建复制账号
      - ./backup:/backup

    ports:
      - "23307:3306"
    networks:
      - common

    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "5"

networks:
  common:
    driver: bridge
    external: true
  1. 启动容器
  2. 设置目录权限
  3. 放入my.cnf
text 复制代码
[mysqld]
port                 = 3306  # 监听端口
server-id            = 2002  # 唯一服务器ID
gtid_mode            = ON  # 启用GTID
enforce_gtid_consistency = ON  # 强制GTID一致性
read_only            = 1  # 只读模式
super_read_only      = 1  # 超级只读
sync_binlog          = 1  # 每事务同步(高耐久性)
innodb_flush_log_at_trx_commit = 1  # 每事务刷新(高耐久性)

expire_logs_days     = 7  # binlog保留(即使不启用binlog,也可设)
max_binlog_size      = 1G  # 单个binlog大小

innodb_buffer_pool_size = 8G  # InnoDB缓冲池大小
max_connections         = 1000  # 最大连接数

# 安全设置
skip-name-resolve  # 跳过主机名解析,提高性能
default_authentication_plugin = mysql_native_password  # 默认认证插件

[client]
default-character-set = utf8mb4  # 默认字符集
  1. 重启容器
  2. 测试连接
  3. 配置主从同步
bash 复制代码
# 进入 MySQL 容器,假设你的容器叫做 mysql8
docker exec -it mysql8 bash

# 登录 MySQL
mysql -uroot -p # 回车然后输入密码回车
# 如果SLAVE 已运行,先停止
STOP SLAVE;

# 配置主从
CHANGE REPLICATION SOURCE TO
  SOURCE_HOST = '192.168.0.4',  -- 主库IP
  SOURCE_PORT = 23306,  -- 主容器内部端口
  SOURCE_USER = 'repl_user', -- 主库上设置的用户
  SOURCE_PASSWORD = 'aO20HQFBa', -- 主库上设置的用户密码
  SOURCE_AUTO_POSITION = 1;  -- 使用GTID自动定位
START SLAVE;

SHOW SLAVE STATUS;  -- 检查状态

注意事项

  1. 如果启动容器出现网络的警告 WARNING: IPv4 forwarding is disabled. Networking will not work.
    这样子的话即使容器成功启动,防火墙打开,Docker 容器也是无网络的,请检查:
bash 复制代码
# 执行编辑
sudo vim /etc/sysctl.conf

# 加入下面这行
net.ipv4.ip_forward = 1

# 重载
sudo sysctl -p
相关推荐
yzhSWJ14 分钟前
直接使用docker中的nginx
nginx·docker·eureka
Giser探索家5 小时前
无人机桥梁巡检:以“空天地”智慧之力守护交通生命线
大数据·人工智能·算法·安全·架构·无人机
angushine6 小时前
Docker方式安装Prometheus+Grafana+Node Exporter
docker·grafana·prometheus
小马哥编程6 小时前
【软考架构】案例分析:MongoDB 如何存储非结构化数据以及其矢量化存储的优点。
数据库·mongodb·架构
鲜枣课堂6 小时前
华为最新光通信架构AI-OTN,如何应对AI浪潮?
人工智能·华为·架构
默 语6 小时前
MySQL中的数据去重,该用DISTINCT还是GROUP BY?
java·数据库·mysql·distinct·group by·1024程序员节·数据去重
爱隐身的官人6 小时前
Windows配置解压版MySQL5(免安装)
windows·mysql
想ai抽9 小时前
pulsar与kafka的架构原理异同点
分布式·架构·kafka
麦麦大数据10 小时前
F036 vue+flask中医热性药知识图谱可视化系统vue+flask+echarts+mysql
vue.js·python·mysql·flask·可视化·中医中药
BullSmall10 小时前
一键部署MySQL
数据库·mysql