基于docker 搭建mysql8.0主从复制

本文详述如何使用Docker部署MySQL8.0实现主从复制,涵盖配置、启动容器、设置账户及测试步骤,助力读写分离架构搭建。

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

如何基于docker搭建mysql8.0主从复制从而实现读写分离
前言

1、 docker的安装与mysql8.0镜像的打包这里不做详细介绍。以后有时间再出详细教程。安装好docker运行环境拉去mysql8镜像,我使用的是自己源码编译的mysql8.0。docker-hub地址如下

docker pull gongxulei/centos-lnmp:mysql8

2、主从复制原理

mysql的主从复制是基于bin-log实现的,因此需要开启bin-log配置,另外mysql8.0默认是开启bin-log的。
如下图所示mysql的主从复制主要分三步实现:

  • Master 主库在事务提交时,会把数据变更作为时间 Events 记录在二进制日志文件 Binlog 中。
  • 主库推送二进制日志文件 Binlog 中的日志事件到从库的中继日志 Relay Log 。
  • slave重做中继日志中的事件,将改变反映它自己的数据。
    在这里插入图片描述
    知道了原理我们下面开始搭建
搭建mysql8.0主从复制
1、master搭建
  • 修改配置并启动一个msql的容器
    (1)my.cnf 配置如下
# bin-log二进制日志设置
log-bin=/usr/local/mysql/log/mysqlbin/mysql-bin
# logging format: mixed|statement|row
binlog_format=statement

# 主从配置master
# required unique id between 1 and 2^32 - 1 defaults to 1 if master-host is not set
server-id = 1
#是否只读,1 代表只读, 0 代表读写
read-only=0
#忽略的数据, 指不需要同步的数据库
binlog-ignore-db=mysql
#指定同步的数据库
#binlog-do-db=db01

(2) 启动容器

我这里使用的 -v 来挂载了mysql 的data数据目录、etc配置目录、log日志目录
并映射的容器的3306端口到宿主机3306端口

# docker-mysql-master
docker run -d -it --privileged=true -p 3306:3306  -v /Users/gongxulei/docker/mysql/master/data:/usr/local/mysql/data   -v  /Users/gongxulei/docker/mysql/master/etc:/usr/local/mysql/etc -v /Users/gongxulei/docker/mysql/master/log:/usr/local/mysql/log --name my-app-mysql8-master 449f953ecd8b

(3) 初始化mysql并启动mysql

我这里初始化指定了mysql的 --log-bin 文件路径,是因为我没有采用默认的目录(data目录)
如果指定会无法初始化。具体原因见我的之前的一篇文章

# 初始化data目录
/usr/local/mysql/bin/mysqld --initialize-insecure --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --log-bin=/usr/local/mysql/log/mysqlbin/mysql-bin --user=mysql
# 以守护进程方式启动mysql
/usr/local/mysql/bin/mysqld_safe --user=mysql &

(4) 设置mysql主从复制账户

# 登录mysql
/usr/local/mysql/bin/mysql -uroot -p
# 设置master的root账户密码 并且允许外部连接mysql
alter mysql.user set host='%' where user='root' and host='localhost';
alter user 'root'@'%' identified by 'root123456';

# 设置当前master授予slave的账户(用于从库复制)
# 注意:这里的ip为slave的ip地址。意思是允许此ip通过账户slave1来访问master数据库
create user 'slave1'@'172.17.0.5' identified by 'slave1123456';
# 授予slave权限并刷新权限
grant replication slave on *.* to 'slave1'@'172.17.0.5';
flush privileges;

此时可以使用 show master status命令查看master数据库状态

# 后面设置slave会用到下面的字段
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 |     869 |              | mysql            |                   |
+------------------+----------+--------------+------------------+-------------------+
字段含义:
File : 从哪个日志文件开始推送日志文件 
Position : 从哪个位置开始推送日志
Binlog_Ignore_DB : 指定不需要同步的数据库
2、slave搭建

(1)my.cnf 配置如下

# bin-log二进制日志设置
log-bin=/usr/local/mysql/log/mysqlbin/mysql-bin
# logging format: mixed|statement|row
binlog_format=statement

# 主从配置slave
# required unique id between 1 and 2^32 - 1 defaults to 1 if master-host is not set
server-id = 2

(2) 启动容器

我这里使用的 -v 来挂载了mysql 的data数据目录、etc配置目录、log日志目录
并映射的容器的3306端口到宿主机3307端口

# docker-mysql-slave
docker run -d -it --privileged=true -p 3307:3306 -v /Users/gongxulei/docker/mysql/slave1/data:/usr/local/mysql/data   -v  /Users/gongxulei/docker/mysql/slave1/etc:/usr/local/mysql/etc -v /Users/gongxulei/docker/mysql/slave1/log:/usr/local/mysql/log  --name my-app-mysql8-slave1 449f953ecd8b

(3) 初始化mysql并启动mysql

初始化与上面master一致

(4) 设置slave账户并开启salve复制

下面用到的master_host地址为master服务器的IP地址。
master_user,master_password 是之前在master服务器设置的用于主从复制的账户密码
master_log_file,master_log_pos 是master服务器中执行show master status的信息

# 设置密码: 参考上面master的root账户设置
# 设置slave账户
change master to master_host= '172.17.0.4', master_user='slave1', master_password='slave1123456', master_log_file='mysql-bin.000006', master_log_pos=869;
# 开启slave模式
start slave;

此时可通过 show slave status命令查看slave是否设置成功

Slave_IO_Running: Yes Slave_SQL_Running: Yes 说明slave设置成功

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.4
                  Master_User: slave1
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 1713
               Relay_Log_File: 4a63c19c8af1-relay-bin.000002
                Relay_Log_Pos: 1168
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1713
              Relay_Log_Space: 1384
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 7f06a326-b845-11ea-85b9-0242ac110002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

ERROR: 
No query specified
3、测试主从是否成功

在mysql的master服务器中创建数据库并查看是否同步到slave中

# 在master中创建数据库并新增一张测试表
CREATE DATABASE `master_test`
DROP TABLE IF EXISTS `test1`;
CREATE TABLE `test1` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='这是一张测试master-slave的表';

在这里插入图片描述
如图上图所示,在slave服务器也有了对应的库跟表,那么恭喜你搭建成功了

### 配置Docker环境下的MySQL 8.0主从复制 #### 准备工作 为了实现MySQL 8.0主从复制,在Docker环境中需先获取MySQL镜像并创建必要的数据卷。 下载指定版本的MySQL镜像: ```bash docker pull mysql:8.0.36 ``` 为本地服务器上的MySQL实例准备持久化存储路径,例如 `/Users/docker/data/mysql/`[^1]。 #### 启动主节点服务 启动主节点时,通过挂载自定义配置文件和数据目录来确保其稳定性和灵活性: ```bash docker run --name=mysql_master \ -p 3301:3306 \ --privileged=true \ -v /path/to/master/conf.d:/etc/mysql/conf.d \ -v /path/to/master/datadir:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=root_password \ -d mysql:8.0.36 ``` 其中 `-v` 参数用于映射主机与容器间的文件夹;`-e` 设置环境变量以初始化root用户的密码[^4]。 #### 修改主节点配置 进入正在运行中的MySQL Master容器内部修改配置文件 `my.cnf` 或者新增一个 `.cnf` 文件到 `/etc/mysql/conf.d/` 下面。编辑内容如下所示: ```ini server-id=1 log-bin=/var/log/mysql/mysql-bin.log binlog-format=row gtid-mode=ON enforce-gtid-consistency=ON ``` 这些参数的作用分别是设定唯一的Server ID、开启二进制日志记录功能以及启用全局事务ID支持GTIDs[^2]。 #### 初始化主节点数据库 连接至Master MySQL客户端执行SQL语句激活相关特性: ```sql SET GLOBAL gtid_purged=''; FLUSH TABLES WITH READ LOCK; SHOW MASTER STATUS\G; UNLOCK TABLES; ``` 上述操作可以清除可能存在的旧GTID集合,并展示当前master状态以便后续slave同步使用[^3]。 #### 启动从节点服务 同样方式启动Slave节点,区别在于需要调整部分参数适应于跟随角色: ```bash docker run --name=mysql_slave \ -p 3302:3306 \ --privileged=true \ -v /path/to/slave/conf.d:/etc/mysql/conf.d \ -v /path/to/slave/datadir:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=root_password \ -d mysql:8.0.36 ``` 注意这里监听不同端口(如3302),防止冲突。 #### 修改从节点配置 对于Slave而言,除了保持一致的基础设置外还需要额外指明自己的身份编号: ```ini server-id=2 relay-log=/var/log/mysql/mysql-relay-bin.log read-only=ON gtid-mode=ON enforce-gtid-consistency=ON ``` 此处在原有基础上增加了只读模式(`read-only`) 和继电器日志 (`relay-log`) 的配置项[^5]。 #### 建立主从关联 回到Master端授权给远程访问权限,并记下授予的信息供Slave连接验证: ```sql CREATE USER 'repl_user'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%'; FLUSH PRIVILEGES; ``` 接着前往Slave端输入之前获得的状态信息完成最终绑定过程: ```sql CHANGE MASTER TO MASTER_HOST='<master_ip>', MASTER_USER='repl_user', MASTER_PASSWORD='password', MASTER_AUTO_POSITION = 1; START SLAVE; ``` 最后确认两者间已经成功建立了联系可以通过查询 Slave_IO_Running 及 Slave_SQL_Running 字段均为 Yes 来判断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值