docker-compose 搭建mysql主从

docker-compose 搭建mysql主从
版本负责人备注说明
v1.0Kevin.xu

密级: 公开

文档说明

基于docker-compose快速搭建mysql 主从。实现mysql 主从复制

场景说明

mysql 数据量级增大后,需要对mysql 进行主从复制。降低单服务器IO负载。

环境准备

  1. Centos8
  2. Docker version 19.03.13, build 4484c46d9d
  3. docker-compose: 1.29.2

配置方法

目录结构

[root@ibeeServer shardingSphere]# tree
.
├── docker-compose.yml
├── mysql_master
│ ├── create_sync_user.sh
│ ├── Dockerfile
│ └── my.cnf
├── mysql_slaver
│ ├── Dockerfile
│ ├── my.cnf
│ └── slave.sh

3 directories, 7 files

配置说明

docker-compose.yml

version: '3'
services:
  mysql_master:
    environment:
      MYSQL_ROOT_PASSWORD: qwer1234 		#root 用户的密码
      MYSQL_DATABASE: test_db				#构建时创建数据库test_db
      MYSQL_USER: test						#构建时创用户test
      MYSQL_PASSWORD: 123456				#构建时创用户密码

      MASTER_SYNC_USER: "sync_admin" 		#设置create_sync_user.sh脚本中定义的用于同步的账号
      MASTER_SYNC_PASSWORD: "sync_admin" 	#设置create_sync_user.sh脚本中定义的用于同步的密码

      ADMIN_USER: "root" 					#设置create_sync_user.sh 执行时当前容器中拥有创建账号功能的数据库账号
      ADMIN_PASSWORD: "qwer1234"			#设置create_sync_user.sh 执行时当前容器中拥有创建账号功能的数据库账号密码

      TZ: Asia/Shanghai						#设置mysql时区
    build:
      context: ./mysql_master/				#构建目录 
    command: --default-authentication-plugin=mysql_native_password #mysql8 需要设置此项来支持用户名密码输入
    container_name: mysql_master 			#容器名称
    ports:
      - "4306:3306"							#容器向外对应的端口号,即连接主机的mysql 对应的端口号
    networks:
      - shardingSphere						#单机部署规划在同一网络中,可以通过容器名进行连接
    volumes:
      - "/data/dockerData/mysql_master/mysqlData:/var/lib/mysql"  #将mysql 的数据挂载到宿主机
    restart: always

  mysql_slaver:
    environment:
      MYSQL_ROOT_PASSWORD: qwer1234 		#root 用户的密码
      MYSQL_DATABASE: test_db				#构建时创建数据库test_db
      MYSQL_USER: test						#构建时创用户test
      MYSQL_PASSWORD: 123456				#构建时创用户密码

      SLAVE_SYNC_USER: "sync_admin" 		#用于同步的账号,由master构建时create_sync_user.sh创建
      SLAVE_SYNC_PASSWORD: "sync_admin"		#用于同步账号的密码,由master构建时create_sync_user.sh设置

      ADMIN_USER: "root"					#设置slaver.sh执行时当前容器中拥有创建账号功能的数据库账号
      ADMIN_PASSWORD: "qwer1234"			#设置slaver.sh执行时当前容器中拥有创建账号功能的数据库账号密码

#      MASTER_HOST: "mysql_master" 			#master地址,slaver.sh执行开启主从同步需要连接master的地址 (或者使用192.168.147.133)
      MASTER_HOST: "192.168.147.133" 		#master地址,slaver.sh执行开启主从同步需要连接master的地址 ( 或者使用mysql_master )
      MASTER_PORT: 4306						#master端口,slaver.sh执行开启主从同步需要连接master的端口,为上面 mysql_master 映射的端口
      TZ: "Asia/Shanghai" 					#设置mysql时区
    depends_on:								#设置mysql_slaver 依赖,需要等mysql_master 起来后才能运行从机
      - mysql_master
    build:
      context: ./mysql_slaver/				#构建目录 
    command: --default-authentication-plugin=mysql_native_password  #mysql8 需要设置此项来支持用户名密码输入
    container_name: mysql_slaver			#容器名称
    ports:									#容器向外对应的端口号,即连接主机的mysql 对应的端口号
      - "5306:3306"
    networks:
      - shardingSphere						#单机部署规划在同一网络中,可以通过容器名进行连接
    volumes:
      - "/data/dockerData/mysql_slaver/mysqlData:/var/lib/mysql" #将mysql 的数据挂载到宿主机
    restart: always
    
networks:
  shardingSphere:
    driver: bridge

Master 配置及说明

目录结构

[root@ibeeServer mysql_master]# tree
.
├── create_sync_user.sh
├── Dockerfile
└── my.cnf

0 directories, 3 files

Dockerfile 说明

FROM mysql:8   												#使用mysql8版本的镜像
COPY my.cnf /etc/mysql/conf.d								#拷贝my.cnf(mysql的配置文件到容器内)
COPY create_sync_user.sh /docker-entrypoint-initdb.d/		#拷贝create_sync_user.sh(mysql的配置文件到容器内) 并在容器构建后执行一次
CMD ["mysqld"]												#容器启动时执行的命令启动mysql服务

my.cnf 说明

[mysqld]
server-id = 100											#mysql服务节点的ID
port = 3306												#mysql 启动的端口号,容器内部
max_connections = 800									#最大连接数
max_connect_errors = 1000									
log_bin = bin.log
slow_query_log = 1
slow_query_log_file = slow.log
log_error=/var/lib/mysql/mysql.err

log-slave-updates=ON
enforce-gtid-consistency=ON
gtid_mode=ON

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

sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

create_sync_user.sh 说明

#!/bin/bash
#定义用于同步的用户名, 从ENV 中获取(在 docker-compose.yml  配置)
MASTER_SYNC_USER=${MASTER_SYNC_USER:-sync_admin}
#定义用于同步的用户密码 , 从ENV 中获取(在 docker-compose.yml  配置), 从ENV 中获取(在 docker-compose.yml  配置)
MASTER_SYNC_PASSWORD=${MASTER_SYNC_PASSWORD:-sync_admin}
#定义用于登录mysql的用户名, 从ENV 中获取(在 docker-compose.yml  配置)
ADMIN_USER=${ADMIN_USER:-root}
#定义用于登录mysql的用户密码, 从ENV 中获取(在 docker-compose.yml  配置)
ADMIN_PASSWORD=${ADMIN_PASSWORD:-qwer1234}
#定义运行登录的host地址, 从ENV 中获取(在 docker-compose.yml  配置)
ALLOW_HOST=${ALLOW_HOST:-%}
#定义创建账号的sql语句
CREATE_USER_SQL="CREATE USER '$MASTER_SYNC_USER'@'$ALLOW_HOST' IDENTIFIED BY '$MASTER_SYNC_PASSWORD';"
#定义赋予同步账号权限的sql,这里设置两个权限,REPLICATION SLAVE,属于从节点副本的权限,REPLICATION CLIENT是副本客户端的权限,可以执行show master status语句
GRANT_PRIVILEGES_SQL="GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO '$MASTER_SYNC_USER'@'$ALLOW_HOST';"
#定义刷新权限的sql
FLUSH_PRIVILEGES_SQL="FLUSH PRIVILEGES;"
#执行sql 
mysql -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$CREATE_USER_SQL $GRANT_PRIVILEGES_SQL $FLUSH_PRIVILEGES_SQL"

Slaver配置及说明

目录结构

[root@ibeeServer mysql_slaver]# tree
.
├── Dockerfile
├── my.cnf
└── slave.sh

0 directories, 3 files

Dockerfile 说明

FROM mysql:8   												#使用mysql8版本的镜像
COPY my.cnf /etc/mysql/conf.d								#拷贝my.cnf(mysql的配置文件到容器内)
COPY slave.sh /docker-entrypoint-initdb.d/					#拷贝slave.sh (mysql的配置文件到容器内) 并在容器构建后执行一次
CMD ["mysqld"]												#容器启动时执行的命令启动mysql服务

my.cnf 说明

与主节点最主要的区别为server-id不同

[mysqld]
server-id = 101											#mysql服务节点的ID
port = 3306												#mysql 启动的端口号,容器内部
max_connections = 800									#最大连接数
max_connect_errors = 1000									
log_bin = bin.log
slow_query_log = 1
slow_query_log_file = slow.log
log_error=/var/lib/mysql/mysql.err

log-slave-updates=ON
enforce-gtid-consistency=ON
gtid_mode=ON

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

sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

slave.sh 说明


#!/bin/bash
#定义连接master进行同步的账号, 从ENV 中获取(在 docker-compose.yml  配置)
SLAVE_SYNC_USER="${SLAVE_SYNC_USER:-sync_admin}"
#定义连接master进行同步的账号密码, 从ENV 中获取(在 docker-compose.yml  配置)
SLAVE_SYNC_PASSWORD="${SLAVE_SYNC_PASSWORD:-sync_admin}"
#定义slave数据库账号, 从ENV 中获取(在 docker-compose.yml  配置)
ADMIN_USER="${ADMIN_USER:-root}"
#定义slave数据库密码, 从ENV 中获取(在 docker-compose.yml  配置)
ADMIN_PASSWORD="${ADMIN_PASSWORD:-qwer1234}"
#定义连接master数据库host地址, 从ENV 中获取(在 docker-compose.yml  配置)
MASTER_HOST="${MASTER_HOST:-%}"

#定义连接master数据库host端口, 从ENV 中获取(在 docker-compose.yml  配置)
MASTER_PORT="${MASTER_PORT:-%}"
#等待10s,保证master数据库启动成功,不然会连接失败
sleep 10

#连接master数据库,查询二进制数据,并解析出logfile和pos,这里同步用户要开启 REPLICATION CLIENT权限,才能使用SHOW MASTER STATUS;
RESULT=`mysql -u"$SLAVE_SYNC_USER" -h$MASTER_HOST -P$MASTER_PORT  -p"$SLAVE_SYNC_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'`
#解析出logfile
LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'`
#解析出pos
LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'`
#设置连接master的同步相关信息
SYNC_SQL="change master to master_host='$MASTER_HOST', master_port=$MASTER_PORT, master_user='$SLAVE_SYNC_USER',master_password='$SLAVE_SYNC_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;"
#开启同步
START_SYNC_SQL="start slave;"
#查看同步状态
STATUS_SQL="show slave status\G;"
mysql -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$SYNC_SQL $START_SYNC_SQL $STATUS_SQL"

验证测试:

使用Navicat 进行连接主库与从库。

Master连接参数为:

host:xxx.xxx.x.x

port: 4306

user: root

passwd: qwer1234

Slaver连接参数为:

host:xxx.xxx.x.x

port: 5306

user: root

passwd: qwer1234

step1. 在主机test_db 中新建表

step2. 在从机test_db 中查看是否有新建的表

FAQ:

  1. Master 启动并未创建对应的create_sync_user.sh

  2. Slaver 启动并未执行slaver.sh

原因:

​ /docker-entrypoint-initdb.d/下的文件,只会在容器为空的时候构建时才会执行

解决:

rm -rvf /data/dockerData/mysql_master/mysqlData

rm -rvf /data/dockerData/mysql_slaver/mysqlData

docker rm -f mysql_master mysql_slaver

doker rmi -f shardingSphere_mysql_master shardingSphere_mysql_slaver

重新进行构建

  1. mysql_master mysql_slaver 容器无法启动

原因:在第一次构建时,这些目录下不能有文件

/data/dockerData/mysql_master/mysqlData

/data/dockerData/mysql_slaver/mysqlData

否则mysqld 会报错

解决:

rm -rvf /data/dockerData/mysql_master/mysqlData

rm -rvf /data/dockerData/mysql_slaver/mysqlData

重新进行构建

读写分离实现参考

shardingProxy 实现mysql读写分离

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值