mysql一主双从环境搭建–docker-compose
一、工作目录结构
├── cluster01
│ ├── msql-master01
│ │ └── volumes
│ │ ├── conf
│ │ │ └── my.cnf
│ │ ├── data
│ │ ├── initdb
│ │ │ ├── init.sql
│ │ │
│ │ └── log
│ ├── msql-slave01
│ │ └── volumes
│ │ ├── conf
│ │ │ └── my.cnf
│ │ ├── data
│ │ ├── initdb
│ │ │ └── init.sh
│ │ └── log
│ └── msql-slave02
│ └── volumes
│ ├── conf
│ │ └── my.cnf
│ ├── data
│ ├── initdb
│ │ └── init.sh
│ └── log
├── cluster02
│ ├── msql-master02
│ │ └── volumes
│ │ ├── conf
│ │ │ └── my.cnf
│ │ ├── data
│ │ ├── initdb
│ │ │ └── init.sql
│ │ └── log
│ ├── msql-slave03
│ │ └── volumes
│ │ ├── conf
│ │ │ └── my.cnf
│ │ ├── data
│ │ ├── initdb
│ │ │ └── init.sh
│ │ └── log
│ └── msql-slave04
│ └── volumes
│ ├── conf
│ │ └── my.cnf
│ ├── data
│ ├── initdb
│ │ └── init.sh
│ └── log
├── docker-compose.yml
└── reset.sh
1.1 创建工作目录
创建shell文件,prepare.sh
#!/bin/bash
mkdir cluster01/msql-master01/volumes/conf -p
mkdir cluster01/msql-master01/volumes/data -p
mkdir cluster01/msql-master01/volumes/initdb -p
mkdir cluster01/msql-master01/volumes/log -p
mkdir cluster01/msql-slave01/volumes/conf -p
mkdir cluster01/msql-slave01/volumes/data -p
mkdir cluster01/msql-slave01/volumes/initdb -p
mkdir cluster01/msql-slave01/volumes/log -p
mkdir cluster01/msql-slave02/volumes/conf -p
mkdir cluster01/msql-slave02/volumes/data -p
mkdir cluster01/msql-slave02/volumes/initdb -p
mkdir cluster01/msql-slave02/volumes/log -p
mkdir cluster02/msql-master02/volumes/data -p
mkdir cluster02/msql-master02/volumes/initdb -p
mkdir cluster02/msql-master02/volumes/log -p
mkdir cluster02/msql-master02/volumes/conf -p
mkdir cluster02/msql-slave03/volumes/conf -p
mkdir cluster02/msql-slave03/volumes/data -p
mkdir cluster02/msql-slave03/volumes/initdb -p
mkdir cluster02/msql-slave03/volumes/log -p
mkdir cluster02/msql-slave04/volumes/conf -p
mkdir cluster02/msql-slave04/volumes/data -p
mkdir cluster02/msql-slave04/volumes/initdb -p
mkdir cluster02/msql-slave04/volumes/log -p
授予prepare.sh执行权限
chmod +x prepare.sh
执行prepare.sh
./prepare.sh
1.2 创建文件
1.2.1 msql-master01
创建init.sql文件
vim cluster01/msql-master01/volumes/initdb/init.sql
grant replication slave,replication client on *.* to 'slave'@'%' identified by "123456";
flush privileges;
select "##################################### master01 .sql 已执行 #####################";
创建my.cnf 配置文件
vim cluster01/msql-master01/volumes/conf/my.cnf
[mysqld]
#D,默认是1,一般取IP最后一段
server-id=1
# [必须]启用二进制日志
log-bin=mysql-bin
# 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)# 确保binlog日志写入后与硬盘同步
sync_binlog = 1
# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all
binlog-ignore-db=mysql
# 设置需要同步的数据库 binlog_do_db = 数据库名;
# 如果是多个同步库,就以此格式另写几行即可。
# 如果不指明对某个具体库同步,表示同步所有库。除了binlog-ignore-db设置的忽略的库
# binlog_do_db = test #需要同步test数据库。
1.2.2 msql-slave01
(1)创建init.sh文件
vim cluster01/msql-slave01/volumes/initdb/init.sh
#!/bin/bash
declare MASTER_HOST="${MASTER_HOST:-localhost}"
declare MASTER_PORT=${MASTER_PORT:-3306}
declare MASTER_USER=${MASTER_USER:-test}
declare MASTER_PASSWORD=${MASTER__PASSWORD:-111111}
echo $MASTER_HOST
#sleep 20s
# mysql -u root -p123456 -P 8406 -h 124.222.25.184 -e "select 1;"
# 自旋直到 master 启动
declare tryCount=0
for i in {1..10};
do
declare master_ready=` mysql -u "$MASTER_USER" -h "$MASTER_HOST" -p"$MASTER_PASSWORD" -P "$MASTER_PORT" -e "show master status;" `
#master_ready=($master_ready)
echo "########### result:"
echo $master_ready
if [ "$master_ready" != "" ]
then
echo "master01 已启动"
break
else
echo "尝试连接master0: .....$i"
sleep 5s
fi
done
declare RESULT=`mysql -u "$MASTER_USER" -h "$MASTER_HOST" -p"$MASTER_PASSWORD" -P "$MASTER_PORT" -e "show master status;" `
echo "获取master bin_log结果:$RESULT"
RESULT=($RESULT)
declare bin_log=${RESULT[5]}
declare pos=${RESULT[6]}
echo "master 信息:"
echo "bin_log_file:$bin_log, pos: $pos"
# change master to master_host='124.222.25.184',master_user='slave',master_password='123456',master_port=8406,master_log_file='mysql-bin.000003', master_log_pos=602,master_connect_retry=30;
declare changeCMD="change master to master_host='$MASTER_HOST',master_user='slave',master_password='123456',master_port=$MASTER_PORT,master_log_file='$bin_log', master_log_pos=$pos,master_connect_retry=30;"
echo $changeCMD
#declare changeCMD="select 1;"
echo `mysql -u root -p123456 -e "$changeCMD ;start slave;"`
echo "监听主节点=> $MASTER_HOST:$MASTER_PORT"
(2)创建my.cnf文件
vim cluster01/msql-slave01/volumes/conf/my.cnf
[mysqld]
#D,默认是1,一般取IP最后一段
server-id=2
# 如果想实现 主-从(主)-从 这样的链条式结构,需要设置:
# log-slave-updates 只有加上它,从前一台机器上同步过来的数据才能同步到下一台机器。
# 设置需要同步的数据库,主服务器上不限定数据库,在从服务器上限定replicate-do-db = 数据库名;
# 如果不指明同步哪些库,就去掉这行,表示所有库的同步(除了ignore忽略的库)。
# replicate-do-db = test;
# 不同步test数据库 可以写多个例如 binlog-ignore-db = mysql,information_schema
replicate-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-bin
log-bin-index=mysql-bin.index
## relay_log配置中继日志
#relay_log=edu-mysql-relay-bin
## 还可以设置一个log保存周期:
#expire_logs_days=14
# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all
1.2.3 msql-slave02
(1)创建init.sh文件
vim cluster01/msql-slave02/volumes/initdb/init.sh
#!/bin/bash
declare MASTER_HOST="${MASTER_HOST:-124.222.25.184}"
declare MASTER_PORT=${MASTER_PORT:-8406}
declare MASTER_USER=${MASTER_USER:-root}
declare MASTER_PASSWORD=${MASTER__PASSWORD:-123456}
# 自旋直到 master 启动
declare tryCount=0
for i in {1..10};
do
declare master_ready=` mysql -u "$MASTER_USER" -h "$MASTER_HOST" -p"$MASTER_PASSWORD" -P "$MASTER_PORT" -e "show master status;" `
echo "########### result:"
echo $master_ready
if [ "$master_ready" != "" ]
then
echo "master01 已启动"
break
else
echo "尝试连接master0: .....$i"
sleep 5s
fi
done
# mysql -u root -p123456 -P 8406 -h 124.222.25.184 -e "select 1;"
declare RESULT=`mysql -u "$MASTER_USER" -h "$MASTER_HOST" -p"$MASTER_PASSWORD" -P "$MASTER_PORT" -e "show master status;" `
RESULT=($RESULT)
declare bin_log=${RESULT[5]}
declare pos=${RESULT[6]}
echo "master 信息:"
echo "bin_log_file:$bin_log, pos: $pos"
declare changeCMD="change master to master_host='$MASTER_HOST',master_user='slave',master_password='123456',master_port=$MASTER_PORT,master_log_file='$bin_log', master_log_pos=$pos,master_connect_retry=30;"
#declare changeCMD="select 1;"
echo `mysql -u root -p123456 -e "$changeCMD ;start slave;"`
echo "监听主节点=> $MASTER_HOST:$MASTER_PORT"
(2)创建my.cnf文件
vim cluster01/msql-slave02/volumes/conf/my.cnf
[mysqld]
#D,默认是1,一般取IP最后一段
server-id=3
# 如果想实现 主-从(主)-从 这样的链条式结构,需要设置:
# log-slave-updates 只有加上它,从前一台机器上同步过来的数据才能同步到下一台机器。
# 设置需要同步的数据库,主服务器上不限定数据库,在从服务器上限定replicate-do-db = 数据库名;
# 如果不指明同步哪些库,就去掉这行,表示所有库的同步(除了ignore忽略的库)。
# replicate-do-db = test;
# 不同步test数据库 可以写多个例如 binlog-ignore-db = mysql,information_schema
replicate-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-bin
log-bin-index=mysql-bin.index
## relay_log配置中继日志
#relay_log=edu-mysql-relay-bin
## 还可以设置一个log保存周期:
#expire_logs_days=14
# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all
1.2.4 msql-master02
(1)创建init.sql
vim cluster02/msql-master02/volumes/initdb/init.sql
#!/bin/bash
grant replication slave,replication client on *.* to 'slave'@'%' identified by "123456";
flush privileges;
echo "################################## master02 .sh 执行 ###########################"
echo "################################## master02 .sh 执行 ###########################"
echo "################################## master02 .sh 执行 ###########################"
(2) 创建my.cnf
vim cluster02/msql-master02/volumes/conf/my.cnf
[mysqld]
#D,默认是1,一般取IP最后一段
server-id=1
# [必须]启用二进制日志
log-bin=mysql-bin
# 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)# 确保binlog日志写入后与硬盘同步
sync_binlog = 1
# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all
binlog-ignore-db=mysql
# 设置需要同步的数据库 binlog_do_db = 数据库名;
# 如果是多个同步库,就以此格式另写几行即可。
# 如果不指明对某个具体库同步,表示同步所有库。除了binlog-ignore-db设置的忽略的库
# binlog_do_db = test #需要同步test数据库。
1.2.5 msql-slave03
(1) 创建init.sh
vim cluster02/msql-slave03/volumes/initdb/init.sh
#!/bin/bash
declare MASTER_HOST="${MASTER_HOST:-124.222.25.184}"
declare MASTER_PORT=${MASTER_PORT:-8506}
declare MASTER_USER=${MASTER_USER:-root}
declare MASTER_PASSWORD=${MASTER__PASSWORD:-123456}
# 自旋直到 master 启动
declare tryCount=0
for i in {1..10};
do
declare master_ready=` mysql -u "$MASTER_USER" -h "$MASTER_HOST" -p"$MASTER_PASSWORD" -P "$MASTER_PORT" -e "show master status;" `
echo "########### result:"
echo $master_ready
if [ "$master_ready" != "" ]
then
echo "master01 已启动"
break
else
echo "尝试连接master0: .....$i"
sleep 5s
fi
done
# mysql -u root -p123456 -P 8406 -h 124.222.25.184 -e "select 1;"
declare RESULT=`mysql -u "$MASTER_USER" -h "$MASTER_HOST" -p"$MASTER_PASSWORD" -P "$MASTER_PORT" -e "show master status;" `
RESULT=($RESULT)
declare bin_log=${RESULT[5]}
declare pos=${RESULT[6]}
echo "master 信息:"
echo "bin_log_file:$bin_log, pos: $pos"
# change master to master_host='124.222.25.184',master_user='slave',master_password='123456',master_port=8406,master_log_file='mysql-bin.000003', master_log_pos=602,master_connect_retry=30;
declare changeCMD="change master to master_host='$MASTER_HOST',master_user='slave',master_password='123456',master_port=$MASTER_PORT,master_log_file='$bin_log', master_log_pos=$pos,master_connect_retry=30;"
#declare changeCMD="select 1;"
echo `mysql -u root -p123456 -e "$changeCMD ;start slave;"`
echo "监听主节点=> $MASTER_HOST:$MASTER_PORT"
(2) 创建my.cnf
vim cluster02/msql-slave03/volumes/conf/my.cnf
[mysqld]
#D,默认是1,一般取IP最后一段
server-id=4
# 如果想实现 主-从(主)-从 这样的链条式结构,需要设置:
# log-slave-updates 只有加上它,从前一台机器上同步过来的数据才能同步到下一台机器。
# 设置需要同步的数据库,主服务器上不限定数据库,在从服务器上限定replicate-do-db = 数据库名;
# 如果不指明同步哪些库,就去掉这行,表示所有库的同步(除了ignore忽略的库)。
# replicate-do-db = test;
# 不同步test数据库 可以写多个例如 binlog-ignore-db = mysql,information_schema
replicate-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-bin
log-bin-index=mysql-bin.index
## relay_log配置中继日志
#relay_log=edu-mysql-relay-bin
## 还可以设置一个log保存周期:
#expire_logs_days=14
# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all
1.2.6 msql-slave04
(1) 创建init.sh
vim cluster02/msql-slave04/volumes/initdb/init.sh
#!/bin/bash
declare MASTER_HOST="${MASTER_HOST:-124.222.25.184}"
declare MASTER_PORT=${MASTER_PORT:-8506}
declare MASTER_USER=${MASTER_USER:-root}
declare MASTER_PASSWORD=${MASTER__PASSWORD:-123456}
# 自旋直到 master 启动
declare tryCount=0
for i in {1..10};
do
declare master_ready=` mysql -u "$MASTER_USER" -h "$MASTER_HOST" -p"$MASTER_PASSWORD" -P "$MASTER_PORT" -e "show master status;" `
echo "########### result:"
echo $master_ready
if [ "$master_ready" != "" ]
then
echo "master01 已启动"
break
else
echo "尝试连接master0: .....$i"
sleep 5s
fi
done
# mysql -u root -p123456 -P 8406 -h 124.222.25.184 -e "select 1;"
declare RESULT=`mysql -u "$MASTER_USER" -h "$MASTER_HOST" -p"$MASTER_PASSWORD" -P "$MASTER_PORT" -e "show master status;" `
RESULT=($RESULT)
declare bin_log=${RESULT[5]}
declare pos=${RESULT[6]}
echo "master 信息:"
echo "bin_log_file:$bin_log, pos: $pos"
declare changeCMD="change master to master_host='$MASTER_HOST',master_user='slave',master_password='123456',master_port=$MASTER_PORT,master_log_file='$bin_log', master_log_pos=$pos,master_connect_retry=30;"
#declare changeCMD="select 1;"
echo `mysql -u root -p123456 -e "$changeCMD ;start slave;"`
echo "监听主节点=> $MASTER_HOST:$MASTER_PORT"
(2) 创建 my.cnf
vim cluster02/msql-slave04/volumes/conf/my.cnf
[mysqld]
#D,默认是1,一般取IP最后一段
server-id=5
# 如果想实现 主-从(主)-从 这样的链条式结构,需要设置:
# log-slave-updates 只有加上它,从前一台机器上同步过来的数据才能同步到下一台机器。
# 设置需要同步的数据库,主服务器上不限定数据库,在从服务器上限定replicate-do-db = 数据库名;
# 如果不指明同步哪些库,就去掉这行,表示所有库的同步(除了ignore忽略的库)。
# replicate-do-db = test;
# 不同步test数据库 可以写多个例如 binlog-ignore-db = mysql,information_schema
replicate-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-bin
log-bin-index=mysql-bin.index
## relay_log配置中继日志
#relay_log=edu-mysql-relay-bin
## 还可以设置一个log保存周期:
#expire_logs_days=14
# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all
1.3 docker-compose文件
创建docker-compose.yml
vim docker-compose.yml
version: '3.3'
services:
# 服务名, 主节点01
mysql-cluster-master01:
# 容器名
container_name: mysql-cluster-master01
# mysql 镜像
image: mysql:5.7
# stop之后重启容器
restart: always
# 暴露端口号: 宿主机端口:容器内端口号
ports:
- 8406:3306
privileged: true
# 按照路径挂载目录: 日志、配置文件、数据
volumes:
- $PWD/cluster01/msql-master01/volumes/log:/var/log/mysql
- $PWD/cluster01/msql-master01/volumes/conf/my.cnf:/etc/mysql/my.cnf
- $PWD/cluster01/msql-master01/volumes/data:/var/lib/mysql
- $PWD/cluster01/msql-master01/volumes/initdb:/docker-entrypoint-initdb.d
# 环境变量: mysql密码
environment:
MYSQL_ROOT_PASSWORD: "123456"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_general_ci',
'--max_connections=3000'
]
# 使用的网卡
networks:
- myweb
# 从节点
mysql-cluster-slave01:
container_name: mysql-cluster-slave01
image: mysql:5.7
restart: always
ports:
- 8407:3306
privileged: true
volumes:
- $PWD/cluster01/msql-slave01/volumes/log:/var/log/mysql
- $PWD/cluster01/msql-slave01/volumes/conf/my.cnf:/etc/mysql/my.cnf
- $PWD/cluster01/msql-slave01/volumes/data:/var/lib/mysql
- $PWD/cluster01/msql-slave01/volumes/initdb:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: "123456"
# 需要同步的 master 节点配置
MASTER_HOST: "124.222.25.184"
MASTER_PORT: 8406
MASTER_USER: "root"
MASTER__PASSWORD: "123456"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_general_ci',
'--max_connections=3000'
]
depends_on:
- mysql-cluster-master01
networks:
- myweb
# 从节点
mysql-cluster-slave02:
container_name: mysql-cluster-slave02
image: mysql:5.7
restart: always
ports:
- 8408:3306
privileged: true
volumes:
- $PWD/cluster01/msql-slave02/volumes/log:/var/log/mysql
- $PWD/cluster01/msql-slave02/volumes/conf/my.cnf:/etc/mysql/my.cnf
- $PWD/cluster01/msql-slave02/volumes/data:/var/lib/mysql
- $PWD/cluster01/msql-slave02/volumes/initdb:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: "123456"
# 需要同步的 master 节点配置
MASTER_HOST: "124.222.25.184"
MASTER_PORT: 8406
MASTER__PASSWORD: "123456"
MASTER_USER: "root"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_general_ci',
'--max_connections=3000'
]
depends_on:
- mysql-cluster-master01
networks:
- myweb
# 服务名, 主节点02
mysql-cluster-master02:
# 容器名
container_name: mysql-cluster-master02
# mysql 镜像
image: mysql:5.7
# stop之后重启容器
restart: always
# 暴露端口号: 宿主机端口:容器内端口号
ports:
- 8506:3306
privileged: true
# 按照路径挂载目录: 日志、配置文件、数据
volumes:
- $PWD/cluster02/msql-master02/volumes/log:/var/log/mysql
- $PWD/cluster02/msql-master02/volumes/conf/my.cnf:/etc/mysql/my.cnf
- $PWD/cluster02/msql-master02/volumes/data:/var/lib/mysql
- $PWD/cluster02/msql-master02/volumes/initdb:/docker-entrypoint-initdb.d
# 环境变量: mysql密码
environment:
MYSQL_ROOT_PASSWORD: "123456"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_general_ci',
'--max_connections=3000'
]
# 使用的网卡
networks:
- myweb
# 从节点
mysql-cluster-slave03:
container_name: mysql-cluster-slave03
image: mysql:5.7
restart: always
ports:
- 8507:3306
privileged: true
volumes:
- $PWD/cluster02/msql-slave03/volumes/log:/var/log/mysql
- $PWD/cluster02/msql-slave03/volumes/conf/my.cnf:/etc/mysql/my.cnf
- $PWD/cluster02/msql-slave03/volumes/data:/var/lib/mysql
- $PWD/cluster02/msql-slave03/volumes/initdb:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: "123456"
# 需要同步的 master 节点配置
MASTER_HOST: "124.222.25.184"
MASTER_PORT: 8506
MASTER__PASSWORD: "123456"
MASTER_USER: "root"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_general_ci',
'--max_connections=3000'
]
depends_on:
- mysql-cluster-master02
networks:
- myweb
# 从节点
mysql-cluster-slave04:
container_name: mysql-cluster-slave04
image: mysql:5.7
restart: always
ports:
- 8508:3306
privileged: true
volumes:
- $PWD/cluster02/msql-slave04/volumes/log:/var/log/mysql
- $PWD/cluster02/msql-slave04/volumes/conf/my.cnf:/etc/mysql/my.cnf
- $PWD/cluster02/msql-slave04/volumes/data:/var/lib/mysql
- $PWD/cluster02/msql-slave04/volumes/initdb:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: "123456"
# 需要同步的主节点信息
MASTER_HOST: "124.222.25.184"
MASTER_PORT: 8506
MASTER__PASSWORD: "123456"
MASTER_USER: "root"
command: [
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_general_ci',
'--max_connections=3000'
]
depends_on:
- mysql-cluster-master02
networks:
- myweb
# 配置网卡
networks:
# 使用网卡,桥接模式
myweb:
driver: bridge
1.4 辅助脚本
重置环境脚本 reset.sh。用于清除所有 /data ; /log; 中的所有数据。
vim reset.sh
#!/bin/bash
docker-compose stop
docker-compose rm -f
rm -rvf cluster01/msql-master01/volumes/data/*
rm -rvf cluster01/msql-master01/volumes/log/*
rm -rvf cluster01/msql-slave01/volumes/log/*
rm -rvf cluster01/msql-slave01/volumes/data/*
rm -rvf cluster01/msql-slave02/volumes/log/*
rm -rvf cluster01/msql-slave02/volumes/data/*
rm -rvf cluster02/msql-master02/volumes/data/*
rm -rvf cluster02/msql-master02/volumes/log/*
rm -rvf cluster02/msql-slave03/volumes/log/*
rm -rvf cluster02/msql-slave03/volumes/data/*
rm -rvf cluster02/msql-slave04/volumes/log/*
rm -rvf cluster02/msql-slave04/volumes/data/*
1.5 搞定
启动mysql集群:docker-compose up