一步一步教你MySQL主从复制读写分离

本次我们通过docker搭建环境

  • 虚拟机搭建对机器配置有要求,并且安装mysql步骤繁琐
  • 一台机器上可以运行多个Docker容器
  • Docker容器之间相互独立,有独立ip,互不冲突
  • Docker使用步骤简便,启动容器在秒级别

MySQL的主从复制

主从复制(也称 AB 复制)允许将来自一个MySQL数据库服务器(主服务器)的数据复制到一个或多个MySQL数据库服务器(从服务器)。

主从复制的有好处

MySQL中复制的优点包括:

  • 横向扩展解决方案 - 在多个从站之间分配负载以提高性能。在此环境中,所有写入和更新都必须在主服务器上进行。但是,读取可以在一个或多个从设备上进行。该模型可以提高写入性能(因为主设备专用于更新),同时显着提高了越来越多的从设备的读取速度。
  • 数据安全性 - 因为数据被复制到从站,并且从站可以暂停复制过程,所以可以在从站上运行备份服务而不会破坏相应的主数据。
  • 分析 - 可以在主服务器上创建实时数据,而信息分析可以在从服务器上进行,而不会影响主服务器的性能。
  • 远程数据分发 - 您可以使用复制为远程站点创建数据的本地副本,而无需永久访问主服务器。
    在这里插入图片描述
    读写分离示意图

主从复制原理

在这里插入图片描述

  1. 主服务器上面的任何修改都会通过自己的 I/O tread(I/O 线程)保存在二进制日志 Binary log 里面。

  2. 从服务器上面也启动一个 I/O thread,通过配置好的用户名和密码, 连接到主服务器上面请求读取二进制日志,然后把读取到的二进制日志写到本地的一个Realy log(中继日志)里面。

  3. 从服务器上面同时开启一个 SQL thread 定时检查 Realy log(这个文件也是二进制的),如果发现有更新立即把更新的内容在本机的数据库上面执行一遍。

一主多从

如果一主多从的话,这时主库既要负责写又要负责为几个从库提供二进制日志。此时可以稍做调整,将二进制日志只给某一从,这一从再开启二进制日志并将自己的二进制日志再发给其它从。或者是干脆这个从不记录只负责将二进制日志转发给其它从,这样架构起来性能可能要好得多,而且数据之间的延时应该也稍微要好一些。
在这里插入图片描述

MySQL主从复制搭建步骤

由于我们依托于docker容器,所以要求大家预先有docker的知识铺垫。
服务器规划

服务器 软件 用途
192.168.0.108 docker 启动MySQL容器master
192.168.0.109 docker 启动MySQL容器slave
192.168.0.1010 docker 启动MySQL容器slave

主服务器搭建

步骤1:镜像拉取

首先在192.168.0.108拉取docker镜像,我们这里使用5.7版本的mysql

[root@bogon ~]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
docker.io/mysql       5.7                 e1e1680ac726        7 months ago        373 MB

创建目录mysql-conf

[root@bogon mysql-conf]# pwd
/usr/local/mysql-conf

在当前目录中创建配置文件my.cnf,次文件要映射到mysql的docker容器中的配置文件,文件中加入[mysqld]

[root@bogon mysql-conf]# vi my.cnf
[root@bogon mysql-conf]# more my.cnf
[mysqld]

步骤2:主机MySQL容器创建

创建主机容器
Master对外映射的端口是5566,Slave对外映射的端口是5577。因为docker容器是相互独立的,每个容器有其独立的ip,所以不同容器使用相同的端口并不会冲突。

docker run -p 5566:3306 --name master-mysql -v/usr/local/mysql-conf/:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

查看容器运行情况

[root@bogon mysql-conf]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
1f93892498df        mysql:5.7           "docker-entrypoint..."   4 minutes ago       Up 4 minutes        33060/tcp, 0.0.0.0:5566->3306/tcp   master-mysql

步骤3:修改外部映射文件my.cnf

[root@bogon mysql-conf]# more my.cnf 
[mysqld]
skip-name-resolve
server-id=1       
log-bin=mysql-bin   
binlog-do-db=tx_db
binlog-ignore-db = mysql
binlog-ignore-db = information_schema

进入容器内可以查看到数据卷映射后的结果


[root@bogon mysql-conf]# docker exec -it 1f93892498df /bin/bash
root@1f93892498df:/etc/mysql/conf.d# more my.cnf 
[mysqld]
skip-name-resolve
server-id=1       
log-bin=mysql-bin   
binlog-do-db=tx_db
binlog-ignore-db = mysql
binlog-ignore-db = information_schema

重启容器

docker restart 1f93892498df

步骤四:赋予从机权限

登录mysql,授予192.168.0.109, 192.168.0.110 slave从机复制权限

mysql> grant replication slave,replication client on *.* to slave@'192.168.0.109' identified by "123456";
Query OK, 0 rows affected

mysql>  flush privileges;
Query OK, 0 rows affected

mysql> grant replication slave,replication client on *.* to slave@'192.168.0.110' identified by "123456";
Query OK, 0 rows affected

mysql>  flush privileges;
Query OK, 0 rows affected

查看主机状态

mysql> show master status;
+------------------+----------+--------------+--------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         | Executed_Gtid_Set |
+------------------+----------+--------------+--------------------------+-------------------+
| mysql-bin.000001 |      154 | tx_db        | mysql,information_schema |                   |
+------------------+----------+--------------+--------------------------+-------------------+
1 row in set

从服务器搭建

步骤1:启动两台从机

从节点配置文件创建
在192.168.0.109和192.168.0.110新建目录/usr/local/mysql-conf/
创建 my.cnf
192.168.0.109机器

[root@file mysql-conf]# more my.cnf 
[mysqld]
skip-name-resolve
server-id=   2
log-bin=mysql-bin  
replicate-do-db=tx_db 
binlog-ignore-db = mysql
binlog-ignore-db = information_schema

192.168.0.110机器

[root@file mysql-conf]# more my.cnf 
[mysqld]
skip-name-resolve
server-id=   3
log-bin=mysql-bin  
replicate-do-db=tx_db 
binlog-ignore-db = mysql
binlog-ignore-db = information_schema

启动slave1(109)

[root@file mysql-conf]# docker run -p 5577:3306 --name slave-mysql1 -v /usr/local/mysql-conf/:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

启动slave1(110)

[root@localhost mysql-conf]# docker run -p 5588:3306 --name slave-mysql1 -v /usr/local/mysql-conf/:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

此时我们可以看到三台MySQL服务器都已经启动,并且连接
file

步骤2:每一台从机创建用户赋权

mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected

mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
Query OK, 0 rows affected

mysql> flush privileges;
Query OK, 0 rows affected

mysql> stop slave;
Query OK, 0 rows affected

mysql> 

步骤3 在每一台从机创建从机

分别在109和110机器执行。

mysql> change master to master_host='192.168.0.108', master_user='slave', master_password='123456', master_port=5566, master_log_file='mysql-bin.000002', master_log_pos= 154, master_connect_retry=30;

Query OK, 0 rows affected

说明:
master_host :Master的地址,指的是容器的独立ip
master_port:Master的端口号,指的是容器的端口号
master_user:用于数据同步的用户
master_password:用于同步的用户的密码
master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒

检查两台从机状态:
我们发现从机已经创建,但是内部线程还未启动

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.0.108
                  Master_User: slave
                  Master_Port: 5566
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 154
               Relay_Log_File: d55404be5426-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB: tx_db

正常情况下,SlaveIORunning 和 SlaveSQLRunning 都是No,因为我们还没有开启主从复制过程。使用start slave开启主从复制过程,然后再次查询主从同步状态show slave status \G;。

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.108
                  Master_User: slave
                  Master_Port: 5566
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 154
               Relay_Log_File: d55404be5426-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: tx_db

在主库中创建tx_db数据库,我们发现从库可以同步出来
file
更详细的Spring源码解析请关注:java架构师免费课程
每晚20:00直播分享高级java架构技术
扫描加入QQ交流群264572737
在这里插入图片描述

发布了87 篇原创文章 · 获赞 63 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/renlianggee/article/details/105603483
今日推荐