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数据库主从复制搭建完成

相关推荐
初晴~8 分钟前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱5813613 分钟前
InnoDB 的页分裂和页合并
数据库·后端
YashanDB2 小时前
【YashanDB知识库】XMLAGG方法的兼容
数据库·yashandb·崖山数据库
独行soc2 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍11基于XML的SQL注入(XML-Based SQL Injection)
数据库·安全·web安全·漏洞挖掘·sql注入·hw·xml注入
小林coding2 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
风间琉璃""3 小时前
bugkctf 渗透测试1超详细版
数据库·web安全·网络安全·渗透测试·内网·安全工具
drebander3 小时前
SQL 实战-巧用 CASE WHEN 实现条件分组与统计
大数据·数据库·sql
IvorySQL3 小时前
IvorySQL 4.0 发布:全面支持 PostgreSQL 17
数据库·postgresql·开源数据库·国产数据库·ivorysql
18号房客3 小时前
高级sql技巧进阶教程
大数据·数据库·数据仓库·sql·mysql·时序数据库·数据库架构
Dawnㅤ3 小时前
使用sql实现将一张表的某些字段数据存到另一种表里
数据库·sql