参考了很多博客,死磕了几天,最终跑起来了,不容易,晚上喝瓶82年可乐庆祝下。
1、整体文件结构,这里忽略log、conf、data映射目录
2、docker-compose.yml文件内容如下:
version: '3.3'
services:
mysql-master:
image: mysql
container_name: mysql-master
healthcheck:
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]
interval: 5s
timeout: 3s
retries: 3
environment:
MYSQL_ROOT_PASSWORD: "123456"
MASTER_SYNC_USER: "sync_admin" #设置脚本中定义的用于同步的账号
MASTER_SYNC_PASSWORD: "123456" #设置脚本中定义的用于同步的密码
ADMIN_USER: "root" #当前容器用于拥有创建账号功能的数据库账号
ADMIN_PASSWORD: "123456"
ALLOW_HOST: "10.10.%.%" #允许同步账号的host地址
TZ: "Asia/Shanghai" #解决时区问题
networks:
mysql:
ipv4_address: "10.10.10.10" #固定ip,因为从库在连接master的时候,需要设置host
volumes:
- /root/mysql/master:/docker-entrypoint-initdb.d #挂载master脚本
command:
- "--server-id=100"
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
- "--log-bin=mysql-bin"
- "--sync_binlog=1"
mysql-slave1:
image: mysql
container_name: mysql-slave1
depends_on:
mysql-master:
condition: service_healthy
environment:
MYSQL_ROOT_PASSWORD: "123456"
SLAVE_SYNC_USER: "sync_admin" #用于同步的账号,由master创建
SLAVE_SYNC_PASSWORD: "123456"
ADMIN_USER: "root"
ADMIN_PASSWORD: "123456"
MASTER_HOST: "10.10.10.10" #master地址,开启主从同步需要连接master
TZ: "Asia/Shanghai" #设置时区
networks:
- mysql
volumes:
- /root/mysql/slave1:/docker-entrypoint-initdb.d #挂载slave脚本
command:
- "--server-id=200"
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
mysql-slave2:
image: mysql
container_name: mysql-slave2
depends_on:
mysql-master:
condition: service_healthy
environment:
MYSQL_ROOT_PASSWORD: "123456"
SLAVE_SYNC_USER: "sync_admin"
SLAVE_SYNC_PASSWORD: "123456"
ADMIN_USER: "root"
ADMIN_PASSWORD: "123456"
MASTER_HOST: "10.10.10.10"
TZ: "Asia/Shanghai"
networks:
- mysql
volumes:
- /root/mysql/slave2:/docker-entrypoint-initdb.d
command: #这里需要修改server-id,保证每个mysql容器的server-id都不一样
- "--server-id=300"
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
networks:
mysql:
driver: bridge
ipam:
driver: default
config:
- subnet: "10.10.0.0/16"
3、create_sync_user.sh文件内容如下:
#!/usr/bin/env bash
#定义用于同步的用户名
MASTER_SYNC_USER=${MASTER_SYNC_USER:-sync_admin}
#定义用于同步的用户密码
MASTER_SYNC_PASSWORD=${MASTER_SYNC_PASSWORD:-123456}
#定义用于登录mysql的用户名
ADMIN_USER=${ADMIN_USER:-root}
#定义用于登录mysql的用户密码
ADMIN_PASSWORD=${ADMIN_PASSWORD:-123456}
#定义运行登录的host地址
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"
4、slave.sh文件内容如下:
#!/usr/bin/env bash
#定义连接master进行同步的账号
SLAVE_SYNC_USER="${SLAVE_SYNC_USER:-sync_admin}"
#定义连接master进行同步的账号密码
SLAVE_SYNC_PASSWORD="${SLAVE_SYNC_PASSWORD:-123456}"
#定义slave数据库账号
ADMIN_USER="${ADMIN_USER:-root}"
#定义slave数据库密码
ADMIN_PASSWORD="${ADMIN_PASSWORD:-123456}"
#定义连接master数据库host地址
MASTER_HOST="${MASTER_HOST:-%}"
#连接master数据库,查询二进制数据,并解析出logfile和pos,这里同步用户要开启 REPLICATION CLIENT权限,才能使用SHOW MASTER STATUS;
RESULT=`mysql -u"$SLAVE_SYNC_USER" -h$MASTER_HOST -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_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"
5、效果如下:
小结:
docker版本:25.0.0
docker compose版本:version v2.24.1,新的docker版本自带docker compose,不需要额外安装
MySQL镜像版本:8.3.0,跟老版本有点区别。很多找到的博客是老版本的,有点累。