Docker下搭建MySQL主从复制

目录

主从复制简介

主从复制搭建


主从复制简介

主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库,主数
据库一般是准实时的业务数据库。

主从复制的作用

  1. 做数据的热备。作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作, 避免数据丢失
  2. 架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能
  3. 读写分离,使数据库能支撑更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度

主从复制的原理

  1. 数据库有个bin-log二进制文件,记录了所有sql语句。
  2. 我们的目标是把主数据库的bin-log文件的sql语句复制过来。
  3. 让其在从数据的relay-log重做(中继)日志文件中再执行一次这些sql语句即可
  4. 下面的主从配置就是围绕这个原理配置
  5. 具体需要三个线程来操作
  • binlog输出线程:每当有从库连接到主库的时候,主库都会创建一个线程然后发送,binlog内容到从库。在从库里,当复制开始的时候,从库就会创建如下两个线程进行处理
  • 从库I/O线程:当START SLAVE语句在从库开始执行之后,从库创建一个I/O线程,该线程连接到主库并请求主库发送binlog里面的更新记录到从库上。从库I/O线程读取主库的binlog输出线程发送的更新并拷贝这些更新到本地文件,其中包括relay log文件
  • 从库的SQL线程:从库创建一个SQL线程,这个线程读取从库I/O线程写到relay log的更新事件并执行

主从复制搭建

本次搭建一主一从

新建主服务器容器实例3307

bash 复制代码
docker run -p 3307:3306 --name mysql-master \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7

查看mysql容器

bash 复制代码
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                   CREATED         STATUS         PORTS                                                  NAMES
eac439fb07df   mysql:5.7     "docker-entrypoint.s..."   3 minutes ago   Up 3 minutes   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-master

进入/mydata/mysql-master/conf目录并新建my.cnf

bash 复制代码
[root@localhost ~]# cd /mydata/mysql-master/conf
[root@localhost conf]# vim my.cnf

编辑my.cnf文件

bash 复制代码
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=101
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062

重启mysql容器

bash 复制代码
[root@localhost conf]# docker restart mysql-master
mysql-master

进入mysql容器并登录mysql数据库

bash 复制代码
[root@localhost conf]# docker exec -it mysql-master /bin/bash
root@eac439fb07df:/#  mysql -uroot -proot
mysql> 

创建数据同步用户

sql 复制代码
mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

授予权限

sql 复制代码
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
Query OK, 0 rows affected (0.00 sec)

新建从服务器容器实例3308

bash 复制代码
[root@localhost conf]# docker run -p 3308:3306 --name mysql-slave \
> -v /mydata/mysql-slave/log:/var/log/mysql \
> -v /mydata/mysql-slave/data:/var/lib/mysql \
> -v /mydata/mysql-slave/conf:/etc/mysql \
> -e MYSQL_ROOT_PASSWORD=root \
> -d mysql:5.7

进入 /mydata/mysql-slave/conf目录下新建my.cnf

bash 复制代码
[root@localhost conf]# cd /mydata/mysql-slave/conf
[root@localhost conf]# vim my.cnf

编辑my.cnf文件

bash 复制代码
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062

重启slave容器

bash 复制代码
[root@localhost conf]# docker restart mysql-slave
mysql-slave

查看启动的docker容器

bash 复制代码
[root@localhost conf]# docker ps
CONTAINER ID   IMAGE         COMMAND                   CREATED          STATUS          PORTS                                                  NAMES
f223b1736767   mysql:5.7     "docker-entrypoint.s..."   9 minutes ago    Up 34 seconds   33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp   mysql-slave
eac439fb07df   mysql:5.7     "docker-entrypoint.s..."   24 minutes ago   Up 15 minutes   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-master

在master主机上查看主从同步的状态
记录下Position的值

bash 复制代码
[root@localhost conf]# docker exec -it mysql-master /bin/bash
root@eac439fb07df:/# mysql -uroot -proot
mysql> show master status;
+-----------------------+----------+--------------+------------------+-------------------+
| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| mall-mysql-bin.000001 |      834 |              | mysql            |                   |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

进入 mysql-slave 容器

bash 复制代码
[root@localhost conf]# docker exec -it mysql-slave /bin/bash
root@f223b1736767:/# mysql -uroot -proot
mysql>

按照如下格式在从数据库中配置主从复制
注意master_log_pos参数的值要和主机中的Position参数的值保持一致

bash 复制代码
change master to master_host='宿主机ip', master_user='slave',
master_password='123456', master_port=3307,
master_log_file='mall-mysql-bin.000001', master_log_pos=Position,
master_connect_retry=30;
sql 复制代码
mysql> change master to master_host='192.168.117.131', master_user='slave',
    -> master_password='123456', master_port=3307,
    -> master_log_file='mall-mysql-bin.000001', master_log_pos=834,
    -> master_connect_retry=30;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

在从数据库中查看主从同步状态

bash 复制代码
<mysql> show slave status \G

在从数据库中开启数据同步

sql 复制代码
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

查看从数据库状态

bash 复制代码
mysql> show slave status \G


出现两个yes,说明主从复制成功

测试主从复制效果

在主机创建数据库,数据表

bash 复制代码
[root@localhost conf]# docker exec -it mysql-master /bin/bash
root@eac439fb07df:/# mysql -uroot -proot

mysql> create database mysql_db;
Query OK, 1 row affected (0.00 sec)

mysql> use mysql_db;
Database changed

mysql> create table stu(id int,name varchar(20),score double);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into stu(id,name,score) values(1,'eric',99.5);
Query OK, 1 row affected (0.01 sec)

mysql> select * from stu;
+------+------+-------+
| id   | name | score |
+------+------+-------+
|    1 | eric |  99.5 |
+------+------+-------+
1 row in set (0.00 sec)

在从机查看数据是否同步

bash 复制代码
[root@localhost conf]# docker exec -it mysql-slave /bin/bash
root@f223b1736767:/# mysql -uroot -proot

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| mysql_db           |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use mysql_db;

mysql> select * from stu;
+------+------+-------+
| id   | name | score |
+------+------+-------+
|    1 | eric |  99.5 |
+------+------+-------+
1 row in set (0.00 sec)

数据同步成功,至此Docker下mysql数据库主从复制搭建完成

相关推荐
标贝科技28 分钟前
ChatGPT对话训练数据采集渠道有哪些
数据库·人工智能·机器学习·chatgpt
计算机学姐34 分钟前
基于python+django+vue的影视推荐系统
开发语言·vue.js·后端·python·mysql·django·intellij-idea
乌啼霜满天2491 小时前
如何将MySQL卸载干净(win11)
数据库·mysql
2的n次方_1 小时前
掌握Spring Boot数据库集成:用JPA和Hibernate构建高效数据交互与版本控制
数据库·spring boot·hibernate
NaZiMeKiY2 小时前
SQLServer数据分页
数据库·sql·sqlserver
Python私教2 小时前
Python国产新 ORM 框架 fastzdp_sqlmodel 快速入门教程
java·数据库·python
孟章豪2 小时前
SQL Server全方位指南:从入门到高级详解
数据库
数分大拿的Statham2 小时前
PostgreSQL中的regexp_split_to_table函数详解,拆分字段为多行
大数据·数据库·postgresql·数据分析·数据清洗
mqiqe2 小时前
PostgreSQL主备环境配置
数据库·postgresql
mqiqe2 小时前
PostgreSQL 容器安装
数据库·postgresql