原创

docker形式mysql创建主从

温馨提示:
本文最后更新于 2025年10月26日,已超过 229 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

shell脚本

#!/bin/bash
# mysql-replication.sh

# 配置参数
#MASTER_CONTAINER="mysql-master" 定义主数据库容器的名称,用于 Docker 中标识主服务器实例。
#SLAVE_CONTAINER="mysql-slave" 定义从数据库容器的名称,用于 Docker 中标识从服务器实例。
#NETWORK_NAME="mysql-replication-net" 定义 Docker 网络名称,用于主从服务器之间的通信。
#MYSQL_ROOT_PASSWORD="admin1.2" 设置 MySQL 根用户(root)的密码,用于数据库访问认证。
#MYSQL_REPLICA_PASSWORD="slave%1" 设置复制用户(repl)的密码,用于主从复制连接认证。
#MYSQL_VERSION="8.0" 指定 MySQL 镜像版本,确保使用 MySQL 8.0 版本进行部署。
MASTER_CONTAINER="mysql-master"
SLAVE_CONTAINER="mysql-slave"
NETWORK_NAME="mysql-replication-net"
MYSQL_ROOT_PASSWORD="admin1.2"
MYSQL_REPLICA_PASSWORD="slave%1"
MYSQL_VERSION="8.0"



# 暴露端口配置
#主mysql端口
MASTER_PORT="3306"
#从mysql端口
SLAVE_PORT="3307"

echo "? 开始设置 MySQL 主从复制..."

# 创建自定义网络
echo "? 创建 Docker 网络..."
docker network create $NETWORK_NAME >/dev/null 2>&1

# 创建主服务器配置
echo "⚙️  创建主服务器配置..."
cat > master.cnf <<EOF
[mysqld]
default_authentication_plugin=mysql_native_password
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
log-slave-updates = 1
gtid-mode = on
enforce-gtid-consistency = on
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
EOF

# 创建从服务器配置
echo "⚙️  创建从服务器配置..."
cat > slave.cnf <<EOF
[mysqld]
default_authentication_plugin=mysql_native_password
server-id = 2
relay-log = relay-bin
log-slave-updates = 1
gtid-mode = on
enforce-gtid-consistency = on
replicate-ignore-db = mysql
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = sys
read-only = 1
EOF

# 启动主服务器
echo "? 启动主服务器..."
docker run -d \
  --name $MASTER_CONTAINER \
  --network $NETWORK_NAME \
  -e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD \
  -v $(pwd)/master.cnf:/etc/mysql/conf.d/master.cnf:ro \
  -p $MASTER_PORT:3306 \
  mysql:$MYSQL_VERSION >/dev/null

# 启动从服务器
echo "? 启动从服务器..."
docker run -d \
  --name $SLAVE_CONTAINER \
  --network $NETWORK_NAME \
  -e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD \
  -v $(pwd)/slave.cnf:/etc/mysql/conf.d/slave.cnf:ro \
  -p $SLAVE_PORT:3306 \
  mysql:$MYSQL_VERSION >/dev/null

# 等待 MySQL 启动完成
echo "⏳ 等待 MySQL 服务启动..."
sleep 10

# 在主服务器上创建复制用户并修改认证方式
echo "? 在主服务器上创建复制用户并修改认证方式..."
docker exec $MASTER_CONTAINER mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY '$MYSQL_REPLICA_PASSWORD';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
FLUSH TABLES WITH READ LOCK;
"

# 获取主服务器状态
echo "? 获取主服务器状态..."
MASTER_STATUS=$(docker exec $MASTER_CONTAINER mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "SHOW MASTER STATUS\G" | grep "File\|Position")
BINLOG_FILE=$(echo "$MASTER_STATUS" | grep "File:" | awk '{print $2}')
BINLOG_POSITION=$(echo "$MASTER_STATUS" | grep "Position:" | awk '{print $2}')

echo "? 主服务器 Binlog 文件: $BINLOG_FILE"
echo "? 主服务器 Binlog 位置: $BINLOG_POSITION"

# 配置从服务器
echo "? 配置从服务器..."
docker exec $SLAVE_CONTAINER mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "
CHANGE MASTER TO
  MASTER_HOST='$MASTER_CONTAINER',
  MASTER_USER='repl',
  MASTER_PASSWORD='$MYSQL_REPLICA_PASSWORD',
  MASTER_LOG_FILE='$BINLOG_FILE',
  MASTER_LOG_POS=$BINLOG_POSITION,
  GET_MASTER_PUBLIC_KEY=1;
START SLAVE;
"

# 检查从服务器状态
echo "? 检查从服务器状态..."
docker exec $SLAVE_CONTAINER mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "SHOW SLAVE STATUS\G" | grep "Slave_IO_Running\|Slave_SQL_Running"

echo "✅ MySQL 主从复制配置完成!"
echo ""
echo "? 连接到主服务器: docker exec -it $MASTER_CONTAINER mysql -uroot -p$MYSQL_ROOT_PASSWORD"
echo "? 连接到从服务器: docker exec -it $SLAVE_CONTAINER mysql -uroot -p$MYSQL_ROOT_PASSWORD"
echo "? 主服务器端口: $MASTER_PORT"
echo "? 从服务器端口: $SLAVE_PORT"
echo ""
echo "? 账号密码信息:"
echo "   主服务器 root 用户密码: $MYSQL_ROOT_PASSWORD"
echo "   复制用户 repl 密码: $MYSQL_REPLICA_PASSWORD"
正文到此结束