目录结构
.
├── build.sh
├── docker-compose.yml
└── init
├── master
│ └── master.sh
└── slave
└── slave.sh
创建文件
build_databases/docker-compose.yml
version: '3'
services:
master:
image: mysql:8.0.28
container_name: mysql-master # 容器名称
# platform: "linux/amd64" # 苹果m1适用,其他win or linux注释此行
ports:
- '33069:3306' # 主库映射ip
restart: always
hostname: mysql-master
environment:
MYSQL_ROOT_PASSWORD: "123456" # 超级账号密码
MASTER_SYNC_USER: "sync_admin" # 给从库创建连接用户名
MASTER_SYNC_PASSWORD: "123456" # 给从库创建连接密码
ALLOW_HOST: "%"
TZ: "Asia/Shanghai"
deploy:
resources:
limits:
memory: 512M
cpus: 50m
logging:
options:
max-file: '1'
max-size: '128k'
command:
- "--server-id=1"
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
- "--log-bin=mysql-bin"
- "--sync_binlog=1"
- "--binlog-ignore-db=mysql"
- "--binlog-ignore-db=sys"
- "--binlog-ignore-db=performance_schema"
- "--binlog-ignore-db=information_schema"
- "--sql_mode=NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,PIPES_AS_CONCAT,ANSI_QUOTES"
volumes:
- ./init/master/master.sh:/docker-entrypoint-initdb.d/steup.sh
- ./data/master:/var/lib/mysql
networks:
dev_compose_env:
ipv4_address: 172.29.0.6 # 定义容器具体ip
slave:
image: mysql:8.0.28
container_name: mysql-slave
# platform: "linux/amd64" # m1适用,其他win or linux注释此行
ports:
- '33076:3306' # 从库映射ip
restart: always
hostname: mysql-slave
environment:
MYSQL_ROOT_PASSWORD: "123456"
SLAVE_SYNC_USER: "sync_admin"
SLAVE_SYNC_PASSWORD: "123456"
MASTER_HOST: "172.29.0.6"
ALLOW_HOST: "%"
TZ: "Asia/Shanghai"
deploy:
resources:
limits:
memory: 512M
cpus: 50m
logging:
options:
max-file: '1'
max-size: '128k'
depends_on:
# 等待主库容器启动再启动该容器
- master
command:
- "--server-id=2"
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
- "--sql_mode=NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,PIPES_AS_CONCAT,ANSI_QUOTES"
volumes:
- ./init/slave/slave.sh:/docker-entrypoint-initdb.d/steup.sh
- ./data/slave:/var/lib/mysql
networks:
dev_compose_env:
ipv4_address: 172.29.0.7 # 定义容器具体ip
networks:
dev_compose_env:
# 创建网络组
ipam:
config:
- subnet: 172.29.0.0/16 # 指定静态网段
build_databases/init/master/master.sh
#!/bin/bash
# 此脚本主要是根据环境变量,创建出用于主从同步的用户。关于为什么要创建出master,slave脚本,是为了区分master和slave环境,因为只要把sql和sh文件放到master目录下面,master在第一次初始化的时候,会自动执行里面的文件内容
#定义用于同步的用户名
echo " --------------------------------- 运行主库配置 ----------------------------------- "
#定义用于同步的用户密码
MASTER_SYNC_USER=${MASTER_SYNC_USER}
MASTER_SYNC_PASSWORD=${MASTER_SYNC_PASSWORD}
#定义运行登录的host地址
ALLOW_HOST=${ALLOW_HOST}
#管理员账号密码
MYSQL_USER="root"
MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
#定义创建账号的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 SELECT,REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO '$MASTER_SYNC_USER'@'$ALLOW_HOST';"
#定义刷新权限的sql
FLUSH_PRIVILEGES_SQL="FLUSH PRIVILEGES;"
#执行sql
mysql -u$MYSQL_USER -p$MYSQL_ROOT_PASSWORD -e "$CREATE_USER_SQL $GRANT_PRIVILEGES_SQL $FLUSH_PRIVILEGES_SQL"
echo " --------------------------------- 运行主库配置 ----------------------------------- "
build_databases/init/slave/slave.sh
#!/bin/bash
# slave主要是去master查询最新的pos位置和binlog文件名称,然后创建同步需要的相关信息,然后执行start slave;
echo " --------------------------------- 运行从库配置 ----------------------------------- "
#管理员账号密码
MYSQL_USER="root"
MYSQL_ROOT_PASSWORD="${MYSQL_ROOT_PASSWORD}"
#定义连接master进行同步的账号密码
SLAVE_SYNC_USER="${SLAVE_SYNC_USER}"
echo "master进行同步的账号:$SLAVE_SYNC_USER"
SLAVE_SYNC_PASSWORD="${SLAVE_SYNC_PASSWORD}"
echo "master进行同步的账号密码:$SLAVE_SYNC_PASSWORD"
#定义连接master数据库host地址
MASTER_HOST="${MASTER_HOST}"
echo "master数据库host地址:$MASTER_HOST"
echo "等待主库启动,延迟60秒"
#等待主库启动,睡眠等待
sleep 60
echo "等待完成,继续执行任务...."
#连接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}')
echo "logfile:$LOG_FILE_NAME"
echo "pos:$LOG_FILE_POS"
#设置连接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;"
echo "连接master的同步相关指令:$SYNC_SQL"
#开启同步
START_SYNC_SQL="start slave;"
#查看同步状态
STATUS_SQL="show slave status\G;"
mysql -u$MYSQL_USER -p$MYSQL_ROOT_PASSWORD -e "$SYNC_SQL $START_SYNC_SQL $STATUS_SQL"
echo " --------------------------------- 运行从库配置 ----------------------------------- "
build_databases/build.sh
#!/bin/bash
# 运行构建
# sh ./build.sh
# 处理shell权限
chmod +x ./master/master.sh
chmod +x ./slave/slave.sh
docker compose up -d
踩坑记录
- /docker-entrypoint-initdb.d初始shell不执行,如果需要创建用户需要避开创建root,否则初始shell中创建root用户失败导致shell执行出错而退出。注意查看shell执行时候的报错,docker compose控制台错误信息不太明显,注意查看ERROR内容是否与指定初始化shell脚本有关系并及时处理。
- /bin/sh: 1: docker-compose: Permission denied,初始shell执行权行不足,映射shell会映射权限,需要给予对应的shell脚本权限,参考build_databases/build.sh
- 从库未成功开启主从,检查发现未获取到master binlog信息,检查发现主库容器binlog开启成功,考虑是从库脚本执行到检查时候,主库还未开启binlog,未验证编排文件中depends_on是否影响,在slave.sh中获取binlog信息的位置增加了延时。重新编排验证通过。