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
相关推荐
麦聪聊数据3 小时前
如何使用 QuickAPI 快速连接 MySQL 数据库并发布 RESTful API
数据库·sql·mysql·restful·数据服务
Angelyb4 小时前
微服务保护和分布式事务
java·微服务·架构
Run Freely9374 小时前
MySQL 数据库_01
数据库·mysql
liliangcsdn4 小时前
Mac本地docker安装Kibana+ElasticSearch
elasticsearch·macos·docker
小朋友,你是否有很多问号?4 小时前
mac本地安装mysql
数据库·mysql
斯普信专业组5 小时前
MySQL主从同步参数调优案例
mysql·主从
优秀的老黄6 小时前
Docker部署RabbitMQ
linux·运维·docker·中间件·容器·centos·rabbitmq
失散136 小时前
分布式专题——10.1 ShardingSphere介绍
java·分布式·架构·shardingsphere·分库分表
Lin_Aries_04216 小时前
容器使用卷
linux·运维·docker·云原生·容器·eureka