版本 | 负责人 | 备注说明 |
---|---|---|
v1.0 | Kevin.xu | |
密级: 公开
文档说明
基于docker-compose快速搭建mysql 主从。实现mysql 主从复制
场景说明
mysql 数据量级增大后,需要对mysql 进行主从复制。降低单服务器IO负载。
环境准备
- Centos8
- Docker version 19.03.13, build 4484c46d9d
- 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.sh3 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.cnf0 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.sh0 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:
原因:
/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
重新进行构建
- 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
重新进行构建