docker-compose 搭建mysql主从

本文介绍如何使用Docker和docker-compose快速搭建MySQL主从复制环境。通过详细配置步骤和脚本实现,确保数据同步并降低单服务器负载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

docker-compose 搭建mysql主从
版本负责人备注说明
v1.0Kevin.xu

密级: 公开

文档说明

基于docker-compose快速搭建mysql 主从。实现mysql 主从复制

场景说明

mysql 数据量级增大后,需要对mysql 进行主从复制。降低单服务器IO负载。

环境准备

  1. Centos8
  2. Docker version 19.03.13, build 4484c46d9d
  3. 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.sh

3 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.cnf

0 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.sh

0 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:

  1. Master 启动并未创建对应的create_sync_user.sh

  2. Slaver 启动并未执行slaver.sh

原因:

​ /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

重新进行构建

  1. 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

重新进行构建

读写分离实现参考

shardingProxy 实现mysql读写分离

1. 首先,在两个不同的主机上分别安装dockerdocker-compose。 2. 在其中一个主机上创建一个名为`docker-compose.yml`的文件,如下所示: ``` version: '3' services: master: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: testdb volumes: - ./master-init:/docker-entrypoint-initdb.d ports: - "3306:3306" networks: - db-network command: --server-id=1 --log-bin=mysql-bin --binlog-do-db=testdb slave: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: password volumes: - ./slave-init:/docker-entrypoint-initdb.d ports: - "3307:3306" networks: - db-network command: --server-id=2 --log-bin=mysql-bin --binlog-do-db=testdb --relay-log=mysqld-relay-bin --relay-log-index=mysqld-relay-bin.index --read-only=1 --replicate-do-db=testdb networks: db-network: ``` 在该文件中,我们定义了两个服务:`master`和`slave`。`master`服务使用mysql:5.7镜像,并将其端口映射到主机的3306端口。 `slave`服务也使用mysql:5.7镜像,并将其端口映射到主机的3307端口。我们还定义了一个`db-network`网络,以使两个服务能够相互通信。 3. 在同一台主机上创建一个名为`master-init`的文件夹,并在其中创建一个名为`init.sql`的文件,如下所示: ``` CREATE DATABASE testdb; CREATE TABLE testdb.users ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL ); INSERT INTO testdb.users (username, email) VALUES ('john', 'john@example.com'), ('jane', 'jane@example.com'); ``` 在这个文件中,我们定义了一个名为`testdb`的数据库,以及一个名为`users`的表,然后插入了一些数据。 4. 在同一台主机上创建一个名为`slave-init`的文件夹,并在其中创建一个名为`init.sql`的文件,如下所示: ``` CHANGE MASTER TO MASTER_HOST='master', MASTER_USER='root', MASTER_PASSWORD='password', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; START SLAVE; ``` 在这个文件中,我们定义了`slave`服务的主服务器是`master`,用户名为`root`,密码为`password`,并指定了主服务器的端口和binlog文件的名称和位置。然后,我们启动了从服务器。 5. 在同一台主机上打开终端,切换到包含`docker-compose.yml`文件的目录,并运行以下命令: ``` docker-compose up ``` 这将启动两个服务:`master`和`slave`。在输出中,您应该看到MySQL服务器已成功启动,并且主从复制已经开始。 6. 测试主从复制是否正常工作。我们可以使用以下命令登录到`master`服务器的MySQL shell: ``` mysql -h localhost -u root -p ``` 然后,我们可以使用以下命令创建一个新用户: ``` USE testdb; INSERT INTO users (username, email) VALUES ('mike', 'mike@example.com'); ``` 现在,我们可以使用以下命令登录到`slave`服务器的MySQL shell: ``` mysql -h localhost -P 3307 -u root -p ``` 然后,我们可以使用以下命令检查是否已成功复制数据: ``` USE testdb; SELECT * FROM users; ``` 如果一切正常,您将看到`users`表中包含了新创建的`mike`用户。 这就是使用docker-compose搭建MySQL主从复制的整个过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值