通过docker安装mysql(5.7+8.0)并配置主从复制(GTID+增强半同步)

一、环境

操作系统:Debian10.11
主机IP地址:172.25.53.131
从机IP地址:172.25.53.132
mysql版本:5.7.36
mysql版本:8.0.26
mysql root密码:admin@root
mysql 数据库名:mydb
mysql 普通用户:mydb
mysql 普通用户密码:admin@user

二、安装docker

参考 Debian10安装docker
docker run -it --rm mysql:8.0.26-debian --verbose --help 查看配置参数

三、拉取镜像

# 拉取镜像
docker pull mysql:5.7.36
docker pull mysql:8.0.26
# 如果不能链接互联网使用以下方法导出导入镜像
# 1. 使用有互联网的系统 执行docker pull mysql:5.7.36拉取
# 2. 执行 docker save mysql:5.7.36 -o mysql_5.7.36.tar 导出镜像
# 3. 上传镜像至本机
# 4. 执行 docker load -i mysql_5.7.36.tar 导入镜像
# 5. 8.0版本同理 版本号改为8.0.26

四、容器编排和主从配置

4.1 基础配置

# 创建程序目录
mkdir -p /opt/mysql
# 进入目录
cd /opt/mysql
# 创建mysql配置文件目录
mkdir -p conf
# 创建mysql数据库文件目录
mkdir -p data
# 创建日志文件目录
mkdir -p logs
# 创建并编辑mysql配置文件
nano ./conf/my.cnf
  • my.cnf配置文件参考
# 服务端基本设置
[mysqld]

# ---------------主从配置---------------
# 服务端ID 用来区分主从服务器
server-id=1
# binlog日志只记录指定库的更新
#binlog-do-db=mydb
# binlog日志不记录指定库的更新
#binlog-ignore-db=testdb
# -----GTID----
# 开启gtid模式
#gtid-mode=on
# 强制gtid一致性
#enforce-gtid-consistency=on

# --------------Master---------------
# -----master增强半同步配置-----
# *****注意:
# *****8.0版本以下三个参数必须先关闭 
# *****在docker-compose up -d启动并初始化完成后 再开启然后重启容器生效
# 载入增强半同步master插件
#plugin-load=rpl_semi_sync_master=semisync_master.so
# 打开master半同步复制
#rpl_semi_sync_master_enabled = 1
# 超时时间 单位毫秒
#rpl_semi_sync_master_timeout = 10000

# --------------Slave---------------
# -----slave增强半同步配置-----
# *****注意:
# *****8.0版本以下两个参数必须先关闭 
# *****在docker-compose up -d启动并初始化完成后 再开启然后重启容器生效
# 载入增强半同步slave插件
#plugin-load=rpl_semi_sync_slave=semisync_slave.so
# 打开slave半同步复制
#rpl_semi_sync_slave_enabled=1
# ------slave其他配置------
# relay-log是从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件
#relay-log=mysql-relay-bin 
#relay-log-index=mysql-relay-bin.index
# 使用逻辑时钟并行复制
#slave-parallel-type=LOGICAL_CLOCK
# 复制进程为4个
#slave-parallel-workers=4
# 使用slave_master_info表存储Master位置信息
#master_info_repository=TABLE 
# 使用lave_relay_info表存储Relay位置信息
#relay_log_info_repository=TABLE
# 在数据库启动后立即启动自动relay log恢复
#relay_log_recovery=on

# 复制数据写入log-bin
#log-slave-updates=1
# 普通用户只读
#read_only=1


# -----------二进制日志配置-----------
# 启用二进制日志功能 并指定binlog的存储目录
log-bin=mysql-bin
# 二进制日志索引
log-bin-index=mysql-bin.index
# 从MySQL5.1.12开始 可以用以下三种模式来实现复制
# 基于SQL语句的复制(statement-based replication, SBR)
# 基于行的复制(row-based replication, RBR)
# 混合模式复制(mixed-based replication, MBR)。
# 相应地 binlog的格式也有三种 STATEMENT ROW MIXED 
# 强烈建议ROW  其他格式可能导致数据不一致
binlog_format=ROW
# 二进制日志最大长度 超过长度会写入新文件
max_binlog_size=1GB


# 错误日志
log_error = /var/log/mysql/mysql_error.log
# 时区
default-time-zone = '+08:00'
# 日志使用系统时间
log_timestamps=SYSTEM
# 跳过外部锁定;External-locking用于多进程条件下为MyISAM数据表进行锁定
skip-external-locking
# 索引块的缓冲区大小
# 对MyISAM表性能影响最大的一个参数
# 决定索引处理的速度 尤其是索引读的速度
# 默认值是16M
# 通过检查状态值Key_read_requests和Key_reads 可以知道key_buffer_size设置是否合理 
key_buffer_size = 128M
# 查询语句包的最大尺寸。
# 消息缓冲区被初始化为net_buffer_length字节 但是可在需要时增加到max_allowed_packet个字节
# 该值太小则会在处理大包时产生错误 如果使用大的BLOB列 必须增加该值
# 这个值来限制server接受的数据包大小
# 有时候大的插入和更新会受max_allowed_packet 参数限制 导致写入或者更新失败
max_allowed_packet = 128M
# 表描述符缓存大小 可减少文件打开/关闭次数
table_open_cache = 512
# MySQL执行排序使用的缓冲大小
# 如果想要增加ORDER BY的速度 首先看是否可以让MySQL使用索引而不是额外的排序阶段
# 如果不能 可以尝试增加sort_buffer_size变量的大小
sort_buffer_size = 8M
# 通信缓冲区在查询期间被重置到该大小 通常不要改变该参数值 
# 但是如果内存不足 可以将它设置为查询期望的大小。
# 客户发出的SQL语句期望的长度 如果语句超过这个长度 缓冲区自动地被扩大 直到max_allowed_packet个字节
net_buffer_length = 16K
# MySQL读入缓冲区大小 
# 对表进行顺序扫描的请求将分配一个读入缓冲区 MySQL会为它分配一段内存缓冲区
# 如果对表的顺序扫描请求非常频繁 并且你认为频繁扫描进行得太慢 可以通过增加该变量值以及内存缓冲区大小提高其性能
read_buffer_size = 8M
# join多表缓冲区大小
# 应用程序经常会出现一些多表Join的操作需求
# MySQL在完成某些Join需求的时候 为了减少参与Join的被驱动表的读取次数以提高性能 需要使用到JoinBuffer来协助完成Join操作
# 当JoinBuffer太小MySQL不会将该Buffer存入磁盘文件,
# 而是先将Join Buffer中的结果集与需要Join的表进行Join操作,
# 然后清空JoinBuffer中的数据 继续将剩余的结果集写入此Buffer中 如此往复
# 这势必会造成被驱动表需要被多次读取 成倍增加IO访问 降低效率
join_buffer_size = 16M
# MySQL的随机读缓冲区大小
# 当按任意顺序读取行时(例如 按照排序顺序) 将分配一个随机读缓存区
# 进行排序查询时 MySQL会首先扫描一遍该缓冲 以避免磁盘搜索
# 提高查询速度 如果需要排序大量数据 可适当调高该值 但MySQL会为每个客户连接发放该缓冲空间
# 所以应尽量适当设置该值 以避免内存开销过大
read_rnd_buffer_size = 16M
# 当对MyISAM表执行repair table或创建索引时 用以缓存排序索引
# 设置太小时可能会遇到myisam_sort_buffer_size is too small
myisam_sort_buffer_size = 32M
# thread_cahe_size线程池
# 线程缓存 用来缓存空闲的线程 以至于不被销毁 如果线程缓存在的空闲线程 需要重新建立新连接
# 则会优先调用线程池中的缓存 很快就能响应连接请求 每建立一个连接 都需要一个线程与之匹配
thread_cache_size = 8
# 内存临时表的最大值
# 每个线程都要分配 实际起限制作用的是tmp_table_size和max_heap_table_size的最小值
# 如果内存临时表超出了限制 MySQL就会自动地把它转化为基于磁盘的MyISAM表 存储在指定的tmpdir目录下 
tmp_table_size = 256M
# 控制监控实体的个数 内部即限制对应container的容量
performance_schema_max_table_instances = 500
# 时间戳默认null方式 
explicit_defaults_for_timestamp = true
# 连接数最大值 即该参数最大值不能超过16384 即使超过也以16384为准
# 增加max_connections参数的值 不会占用太多系统资源
# 该参数设置过小的最明显特征是出现Too many connections错误
max_connections = 500
# 负责阻止过多尝试失败的客户端以防止暴力破解密码的情况
# 当此值设置为100时 意味着如果某一客户端尝试连接此MySQL服务器 但是失败100次 则MySQL会无条件强制阻止此客户端连接
max_connect_errors = 100
# mysql打开最大文件数 
open_files_limit = 65535
# 默认使用mysql_native_password插件认证密码
default_authentication_plugin = mysql_native_password
# 在内置插件 存储引擎加载前加载第三方插件
early-plugin-load = ""


# 默认存储引擎
default_storage_engine = InnoDB
# 开启独立表空间
innodb_file_per_table = 1
# 数据库目录
innodb_data_home_dir = /var/lib/mysql
# 共享表空间文件
innodb_data_file_path = ibdata1:10M:autoextend
# 事务日志目录
innodb_log_group_home_dir = /var/lib/mysql
# 缓冲区大小
innodb_buffer_pool_size = 1024M
# 日志组中的每个日志文件的大小 单位MB
innodb_log_file_size = 128M
# 日志写入日志磁盘文件前的缓冲大小 
# 如果有大的事务处理 设置大的日志缓冲可以减少磁盘I/O
innodb_log_buffer_size = 64M
# 每次commit日志缓存中的数据刷到磁盘中 通常设置为1
innodb_flush_log_at_trx_commit = 1
# 在回滚之前 InnoDB事务将等待超时的时间 单位秒 
innodb_lock_wait_timeout = 50
[mysqldump]
# 强制mysqldump从服务器查询取得记录直接输出而不是取得所有记录后将它们缓存到内存中
quick
# 限制server接受的数据包大小
# mysql服务器端和客户端在一次传送数据包的过程当中数据包的大小 
max_allowed_packet = 256M
[mysql]
# 关闭自动补全
no-auto-rehash
#使用myisamchk实用程序来获得有关你的数据库桌表的信息 检查和修复他们或优化他们
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer_size = 2M
write_buffer_size = 2M
#mysqlhotcopy使用lock tables flush tables和cp或scp来快速备份数据库
# 它是备份数据库或单个表最快的途径 完全属于物理备份 但只能用于备份MyISAM存储引擎和运行在数据库目录所在的机器上
# 与mysqldump备份不同 mysqldump属于逻辑备份 备份时是执行的sql语句 使用mysqlhotcopy命令前需要要安装相应的软件依赖包
[mysqlhotcopy]
interactive-timeout

4.2 主从配置

公共:

  • 主机和从机设置为不同的ID server-id=xx
  • 配置要同步的数据库 binlog-do-db=mydb
  • 开启GTID模式 gtid-mode=on
  • 开启GTID强制一致性 enforce-gtid-consistency=on

Master端:

  • 加载增强半同步插件 plugin-load=rpl_semi_sync_master=semisync_master.so
  • 开启半同步复制 rpl_semi_sync_master_enabled = 1
  • 半同步复制超时时间10秒 rpl_semi_sync_master_timeout = 10000

Slave端:

  • 加载增强半同步插件 plugin-load=rpl_semi_sync_slave=semisync_slave.so
  • 开启半同步复制 rpl_semi_sync_slave_enabled=1
  • 开启relay日志 用来保存从主机复制来的日志 relay-log=mysql-relay-bin
  • 配置relay日志索引 relay-log-index=mysql-relay-bin.index
  • 配置并行复制 slave-parallel-type=LOGICAL_CLOCK
  • 配置并行复制进程数量为4 slave-parallel-workers=4
  • 使用slave_master_info表存储Master位置信息 master_info_repository=TABLE
  • 使用lave_relay_info表存储同步位置信息 relay_log_info_repository=TABLE
  • 在数据库启动后立即启动自动relay log恢复 relay_log_recovery=on
  • 复制的数据也写入log-bin日志 log-slave-updates=1
  • 普通用户只读 read_only=1

注意:以下5个参数在8.0版本下必须先关闭,等mysql初始化完成后才能开启

  • plugin-load=rpl_semi_sync_master=semisync_master.so
  • rpl_semi_sync_master_enabled = 1
  • rpl_semi_sync_master_timeout = 10000
  • plugin-load=rpl_semi_sync_slave=semisync_slave.so
  • rpl_semi_sync_slave_enabled=1

Master配置参考:

# ---------------主从配置---------------
# 服务端ID 用来区分主从服务器
server-id=10
# binlog日志只记录指定库的更新
binlog-do-db=mydb
# binlog日志不记录指定库的更新
#binlog-ignore-db=testdb
# -----GTID----
# 开启gtid模式
gtid-mode=on
# 强制gtid一致性
enforce-gtid-consistency=on

# --------------Master---------------
# -----master增强半同步配置-----
# *****注意:
# *****8.0版本以下三个参数必须先关闭 
# *****在docker-compose up -d启动并初始化完成后 再开启然后重启容器生效
# 载入增强半同步master插件
plugin-load=rpl_semi_sync_master=semisync_master.so
# 打开master半同步复制
rpl_semi_sync_master_enabled = 1
# 超时时间 单位毫秒
rpl_semi_sync_master_timeout = 10000

# --------------Slave---------------
# -----slave增强半同步配置-----
# *****注意:
# *****8.0版本以下两个参数必须先关闭 
# *****在docker-compose up -d启动并初始化完成后 再开启然后重启容器生效
# 载入增强半同步slave插件
#plugin-load=rpl_semi_sync_slave=semisync_slave.so
# 打开slave半同步复制
#rpl_semi_sync_slave_enabled=1
# ------slave其他配置------
# relay-log是从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件
#relay-log=mysql-relay-bin 
#relay-log-index=mysql-relay-bin.index
# 使用逻辑时钟并行复制
#slave-parallel-type=LOGICAL_CLOCK
# 复制进程为4个
#slave-parallel-workers=4
# 使用slave_master_info表存储Master位置信息
#master_info_repository=TABLE 
# 使用lave_relay_info表存储Relay位置信息
#relay_log_info_repository=TABLE
# 在数据库启动后立即启动自动relay log恢复
#relay_log_recovery=on
# 复制数据写入log-bin
#log-slave-updates=1
# 普通用户只读
#read_only=1


Slave配置参考:


# ---------------主从配置---------------
# 服务端ID 用来区分主从服务器
server-id=20
# binlog日志只记录指定库的更新
binlog-do-db=mydb
# binlog日志不记录指定库的更新
#binlog-ignore-db=testdb
# -----GTID----
# 开启gtid模式
gtid-mode=on
# 强制gtid一致性
enforce-gtid-consistency=on

# --------------Master---------------
# -----master增强半同步配置-----
# *****注意:
# *****8.0版本以下三个参数必须先关闭 
# *****在docker-compose up -d启动并初始化完成后 再开启然后重启容器生效
# 载入增强半同步master插件
#plugin-load=rpl_semi_sync_master=semisync_master.so
# 打开master半同步复制
#rpl_semi_sync_master_enabled = 1
# 超时时间 单位毫秒
#rpl_semi_sync_master_timeout = 10000

# --------------Slave---------------
# -----slave增强半同步配置-----
# *****注意:
# *****8.0版本以下两个参数必须先关闭 
# *****在docker-compose up -d启动并初始化完成后 再开启然后重启容器生效
# 载入增强半同步slave插件
plugin-load=rpl_semi_sync_slave=semisync_slave.so
# 打开slave半同步复制
rpl_semi_sync_slave_enabled=1
# ------slave其他配置------
# relay-log是从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件
relay-log=mysql-relay-bin 
relay-log-index=mysql-relay-bin.index
# 使用逻辑时钟并行复制
slave-parallel-type=LOGICAL_CLOCK
# 复制进程为4个
slave-parallel-workers=4
# 使用slave_master_info表存储Master位置信息
master_info_repository=TABLE 
# 使用lave_relay_info表存储Relay位置信息
relay_log_info_repository=TABLE
# 在数据库启动后立即启动自动relay log恢复
relay_log_recovery=on
# 复制数据写入log-bin
log-slave-updates=1
# 普通用户只读
read_only=1

4.3 配置docker-compose

# 进入目录
cd /opt/mysql
# 设置mysql目录权限
chown -R 999.999 logs
chown -R 999.999 data
# 创建并编辑docker-compose.yml配置文件
nano docker-compose.yml

主机docker-compose.yml配置参考:

version: '3'
services:
  mysql-master:
    # 镜像和版本
    # 8.0版本改为mysql:8.0.26
    image: mysql:5.7.36
    # 容器名称
    container_name: mysql-master
    # 数据卷映射
    volumes:
      # 数据库目录
      - ./data:/var/lib/mysql
      # 配置文件目录
      - ./conf:/etc/mysql/conf.d
      # 日志目录
      - ./logs:/var/log/mysql
      # 时区
      - /etc/localtime:/etc/localtime
    # 启动规则设置为随系统启动并且出错后自动重启
    restart: always
    # 获取root权限
    privileged: true
    # 环境变量配置
    environment:
      # root密码
      - MYSQL_ROOT_PASSWORD=admin@root
      # 新建数据库
      - MYSQL_DATABASE=mydb
      # 新建用户
      - MYSQL_USER=mydb
      # 新用户密码
      - MYSQL_PASSWORD=admin@user
      # 默认时区
      - TZ=Asia/Shanghai
      # 默认编码
      - LANG=en_US.UTF-8
    # 容器直接使用主机网络
    network_mode: "host"
    # 设置数据库默认编码为utf8mb4 排序规则为utf8mb4_general_ci
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci

从机docker-compose.yml配置参考:

version: '3'
services:
  mysql-slave:
    # 镜像和版本
    # 8.0版本改为mysql:8.0.26
    image: mysql:5.7.36
    # 容器名称
    container_name: mysql-slave
    # 数据卷映射
    volumes:
      # 数据库目录
      - ./data:/var/lib/mysql
      # 配置文件目录
      - ./conf:/etc/mysql/conf.d
      # 日志目录
      - ./logs:/var/log/mysql
      # 时区
      - /etc/localtime:/etc/localtime
    # 启动规则设置为随系统启动并且出错后自动重启
    restart: always
    # 获取root权限
    privileged: true
    # 环境变量配置
    environment:
      # root密码
      - MYSQL_ROOT_PASSWORD=admin@root
      # 新建数据库
      - MYSQL_DATABASE=mydb
      # 新建用户
      - MYSQL_USER=mydb
      # 新用户密码
      - MYSQL_PASSWORD=admin@user
      # 默认时区
      - TZ=Asia/Shanghai
      # 默认编码
      - LANG=en_US.UTF-8
    # 容器直接使用主机网络
    network_mode: "host"
    # 设置数据库默认编码为utf8mb4 排序规则为utf8mb4_general_ci
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci

4.4 主机授权配置

# 进入目录
cd /opt/mysql
# 创建并后台启动容器
docker-compose up -d
# 查看主机mysql日志 
docker-compose logs mysql-master

# 8.0版本注意这里看到日志里初始化完成了就执行
# docker-compose stop停止容器 修改conf/my.cnf打开增强半同步插件后
# 执行docker-compose启动容器再继续下面操作

# 进入容器
docker exec -u root -ti mysql-master /bin/bash
# 登录数据库
mysql -u root -p

# 5.7版本 
# 创建用户并授权从机复制
# cpuser:用户名
# password:密码
# 172.25.53.132:只能通过这个IP登录 如果需要任意IP改为 %
GRANT REPLICATION SLAVE ON *.* to 'cpuser'@'172.25.53.132' identified by 'password';

# 注意:8.0版本
# 使用以下命令创建用户
# 创建用户
#create user 'cpuser'@'172.25.53.132' identified with mysql_native_password by 'password';
# 授权主从复制
#grant replication slave on *.* to 'cpuser'@'172.25.53.132';

# 刷新权限
FLUSH PRIVILEGES;
# 查看Msater状态 有GTID字段
SHOW MASTER STATUS;

4.5 从机配置主备复制

# 进入目录
cd /opt/mysql
# 创建并后台启动容器
docker-compose up -d
# 查看从机mysql日志
docker-compose logs mysql-slave

# 8.0版本注意这里看到日志里初始化完成了就执行
# docker-compose stop停止容器 修改conf/my.cnf打开增强半同步插件后
# 执行docker-compose启动容器再继续下面操作

# 进入容器
docker exec -u root -ti mysql-slave /bin/bash
# 登录数据库
mysql -u root -p
# 链接主机
# master_host:主机IP
# master_port:主机端口
# master_user:主备用户
# master_password:主备密码
# master_auto_position:试用GTID自动位置
change master to
 master_host='172.25.53.131',
 master_port=3306,
 master_user='cpuser',
 master_password='password',
 master_auto_position=1;
# 启动从机
START SLAVE;
# 查看从机状态
SHOW SLAVE STATUS\G;

重点关注以下两个值

  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes
mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.25.53.131
                  Master_User: cpuser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 1048
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 1261
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

五、测试

5.1 登录主机创建表和数据

# 进入容器
docker exec -u root -ti mysql-master /bin/bash
# 登录数据库
mysql -u mydb -p
# 查看增强半同步插件信息
show variables like '%rpl_semi%';
# 进入库
use mydb;
# 创建表
CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(255), PRIMARY KEY ( id )) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
# 插入测试数据
INSERT INTO test (name) VALUES ("testname");

5.2 登录从机查看表和数据

# 进入容器
docker exec -u root -ti mysql-slave /bin/bash
# 登录数据库
mysql -u mydb -p
# 查看增强半同步插件信息
show variables like '%rpl_semi%';
# 查看增强半同步插件同步状态
show status like 'Rpl_semi_sync_slave_status';
# 进入库
use mydb;
# 查看表
show tables;
# 查看数据
select * from test;

你可能感兴趣的:(docker,Debian,mysql,docker,服务器,linux)