Mysql的主从复制,基于gtid的主从复制、半同步复制、并行复制,组复制。

一、概念

在这里插入图片描述
复制原理:
Mysql中有一种日志叫做bin日志(二进制日志)。这个日志会记录下所有修改了数据库的SQL语句主从复制的原理其实就是把主服务器上的bin日志复制到从服务器上执行一遍,这样从服务器上的数据就和主服务器上的数据相同了。
Mysql复制特点:

数据复制技术有以下一些特点:
(1)    数据分布
(2)    负载平衡(load balancing)
(3)    备份
(4)    高可用性(high availability)和容错

Mysql主从复制原理:

从库生成两个线程,一个I/O线程,一个SQL线程;
i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中;
主库会生成一个 log dump 线程,用来给从库 i/o线程传binlog;
SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致;

mysql的日志类型:

1、Error log 错误日志
2、General query log普通查询日志
3、Slow query log 慢查询日志(记录哪些查询比较慢 )
4、Binary log二进制日志文件(1、用于增量备份。2、主从)
5、要实现MySQL的主从复制,首先必须打开Master端的Binlog记录功能,否则就无法实现。
因为整个复制过程实际上就是Slave从Master端获取BInlog日志,然后再在Slave上以相同
顺序执行获取的binlog日志中记录的各种SQL操作。

主从复制原理:
在这里插入图片描述

如果想要配置一主多从,从节点配置相同,server-id不同即可

**主节点:**
    启用二进制日志。
    为当前节点设置一个全局唯一的server_id。
    创建有复制权限的用户账号 REPLIACTION SLAVE ,REPLIATION CLIENT。

**从节点:**
    启动中继日志。
    为当前节点设置一个全局唯一的server_id。
    使用有复制权限的用户账号连接至主节点,并启动复制线程。

二、主从复制:

实验环境:

主端(maste) :
IP:172.25.34.1  主机名:server1
从端 (slave):
IP:172.25.34.2  主机名:server2

在主端(master)上:

下载mysql安装包解压:

[root@server1 mysql]# ls
mysql-community-client-5.7.24-1.el7.x86_64.rpm
mysql-community-common-5.7.24-1.el7.x86_64.rpm
mysql-community-libs-5.7.24-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm
mysql-community-server-5.7.24-1.el7.x86_64.rpm
[root@server1 ~]# yum install -y *  安装服务

在这里插入图片描述
安装成功:
在这里插入图片描述

[root@server1 mysql]# systemctl start mysqld   #开启mysql服务
[root@server1 mysql]# vim /etc/my.cnf    编辑my.cnf常用参数配置

添加:

log-bin=mysql-bin  # 启用二进制功能,主从复制基础
server-id=1        # id唯一

在这里插入图片描述
重启服务文件内容生效

[root@server1 mysql]# systemctl restart mysqld    #重启服务文件内容生效
[root@server1 mysql]# cat /var/log/mysqld.log | grep password
2019-02-24T01:29:22.842004Z 1 [Note] A temporary password is generated for root@localhost: Dqeisanqr3+O
root@localhost:后面为初始密码          密码为 Dqeisanqr3+O

在这里插入图片描述

[root@server1 ~]# mysql -p   # 我们可以用临时密码登录数据库,但是什么都干不了
Enter password: 
mysql> show databases;

在这里插入图片描述

[root@server1 ~]# mysql_secure_installation   # 初始化密码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

[root@server1 ~]# mysql -p   # 再次登录,可以正常使用
Enter password: 
mysql> show databases;	

在这里插入图片描述

mysql> grant replication slave on *.* to repl@'172.25.34.%' identified by 'westoS+1';  
# 为服务器创建一个连接账户并授予权限,*.*表示所有权限;172.25.78.%表示这个网段的所有用户都有这个权限
mysql> show master status;

在这里插入图片描述

在从端(slave)上:

先测试master数据库是否能远程登录

[root@server1 ~]# mysql -h 172.25.34.1 -u repl -p
Enter password: 
mysql> show databases;   # 测试成功

在这里插入图片描述

mysql> quit  #退出数据库

开始配置从端(slave)的数据库

[root@server2 ~]# cd /root/mysql/
[root@server2 mysql]# ls    # 将软件上传
mysql-community-client-5.7.24-1.el7.x86_64.rpm
mysql-community-common-5.7.24-1.el7.x86_64.rpm
mysql-community-libs-5.7.24-1.el7.x86_64.rpm
mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm
mysql-community-server-5.7.24-1.el7.x86_64.rpm
[root@server2 mysql]# yum install -y *

在这里插入图片描述
安装成功:
在这里插入图片描述
配置文件:

[root@server1 ~]# vim /etc/my.cnf
server-id=2
注:从服务器 ID 号,不能和主 ID 相同,如果设置多个从服务
器,每个从服务器必须有一个唯一的 server-id 值,必须与主服
务器的以及其它从服务器的不相同。可以认为 server-id 值
类似于 IP 地址:这些 ID 值能唯一识别复制服务器群集中的
每个服务器实例。
[root@server1 ~]# systemctl start mysqld
[root@server1 ~]# grep password /var/log/mysqld.log   查看日志会看到出是密码
2018-08-08T12:27:29.954223Z 1 [Note] A temporary password is generated for root@localhost: srpy%>EUr5rA
# root@localhost:后面为密码。   密码为:srpy%>EUr5rA

初始化和前面主机一样

[root@server2 ~]# mysql_secure_installation  # 初始化密码
[root@server2 ~]# mysql -p
mysql> change master to master_host='172.25.34.1',master_user='repl',master_password='westoS+1',master_log_file='mysql-bin.000006',master_log_pos=194; 
 # 从库和主库建立连接,必须和主服务器里查看到的数据保持一致
mysql> start slave; 
mysql> show slave status\G;

在这里插入图片描述

在master上创建数据库

[root@server1 ~]# mysql -p
Enter password: 
mysql> create database test;
mysql> use test;
mysql> create table userlist(
    -> username varchar(15) not null,
    -> password varchar(25) not null);
mysql> desc userlist;

在这里插入图片描述

mysql> insert into userlist values ('userq','111');
mysql> insert into userlist values ('user1','222');	
mysql> select * from userlist;   # 建立成功

在这里插入图片描述

在从端(slave)上查看是否同步:

[root@server2 ~]# mysql -p
Enter password: 
mysql> show databases;

在这里插入图片描述

mysql> use test;
mysql> show tables;

在这里插入图片描述

mysql> select * from userlist;    # 同步成功

在这里插入图片描述

三、gtid实现主从复制

相比于传统的主从复制优点:不需要知道复制哪个文件,也不需要知道从哪个号开始复制

#在主机(master)上

[root@server1 mysql]# vim /etc/my.cnf
server-id=1
log-bin=mysql-bin
gtid_mode =ON
enforce-gtid-consistency=true

在这里插入图片描述

[root@base2 ~]# mysql -p
Enter password: 
mysql>grant replication slave on *.* to repl@'172.25.34.%' identified by 'westoS+1';
#为服务器创建一个连接账户并授予权限,*.*表示所有权限;172.25.78.%表示这个网段的所有用户都有这个权限

在这里插入图片描述

#在从端(slave)上

[root@server2 ~]# vim /etc/my.cn
server-id=2
gtid_mode =ON
enforce-gtid-consistency=true

在这里插入图片描述

[root@server2 ~]# systemctl restart mysqld 	
[root@server2 ~]# mysql -p
Enter password: 
mysql> stop slave;
mysql> change master to master_host='172.25.34.1',master_user='repl',master_password='westoS+1',MASTER_AUTO_POSITION=1;   
# 改变slave服务器用于连接master服务器的参数,此处把MASTER值设为动态
mysql> start slave;
mysql> show slave status\G;

在这里插入图片描述

#在主端(master)上创建数据库

mysql> show master status;   # 数据已经改变

在这里插入图片描述

mysql> create database westos;
mysql> show databases;

在这里插入图片描述

#在从端(slave)端查看是否同步

mysql> show databases;     #同步成功

在这里插入图片描述

mysql> use mysql;
mysql> show tables;

在这里插入图片描述

mysql> select * from gtid_executed;   

记录所有gtid的值
在这里插入图片描述

[root@server2 mysql]# cd /var/lib/mysql
[root@server2 mysql]# ls

在这里插入图片描述
mysql主从复制存在的问题:

1.主库宕机后,数据可能丢失
2.从库只有一个sql Thread,主库写压力大,复制很可能延时

解决方法:

1.半同步复制----解决数据丢失的问题
2.并行复制----解决从库复制延迟的问题

四、基于gtid实现半同步复制

关于半同步:
    介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。

在这里插入图片描述

#在主端(master)上:

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';  
                               # 下载插件
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';     
                               # 查看插件是否加载成功

在这里插入图片描述

mysql> show global variables like '%semi%';   	
mysql> set global rpl_semi_sync_master_enabled=1;  
 #设置变量,启用半同步复制,这是临时设置,永久设置需要编辑文件/etc/my.cnf写入rpl_semi_sync_master_enabled=1		
mysql> show global variables like '%semi%';

在这里插入图片描述

mysql> show global status like '%semi%';  # 可以用这些参数进行监控

在这里插入图片描述

mysql>  show status like 'Rpl_semi_sync_master_status';  # 查看半同步是否在运行

在这里插入图片描述

#配置从端(slave)服务

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';  # 下载插件
mysql> set global rpl_semi_sync_slave_enabled=1;  # 设置变量,启用半同步复制
mysql> stop slave IO_THREAD;     # 重启slave上的IO线程,重启后,slave会在master上注册为半同步复制的slave角色,否则还是异步复制
mysql> start slave IO_THREAD;
mysql> show global variables like '%semi%';

在这里插入图片描述

mysql> show status like 'Rpl_semi_sync_slave_status';  # 查看半同步是否在运行

在这里插入图片描述

#测试:

1、在Slave执行stop slave后,master的create操作需要10.76s才返回,而这与rpl_semi_sync_master_timeout参数的时间相吻合。

#在从端(slave)上:

在这里插入图片描述

#在主端(master)上:
mysql> create database student;
Query OK, 1 row affected (10.06 sec)    # 默认延迟10秒才会同步过去

在这里插入图片描述

mysql>  show global status like '%semi%'; 

在这里插入图片描述
2、在Slave执行stop slave之前,master的drop操作很快就能返回。

#在从端(slave)上:
mysql>mysql> start slave IO_THREAD;
mysql> show databases;    # 当slave启动时,数据会自动同步,不会丢失

在这里插入图片描述
在这里插入图片描述

#在主端(master)上:
mysql> drop database student;

在这里插入图片描述
    事实上,半同步复制并不是严格意义上的半同步复制,当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。

五、基于gtid实现并行复制

1、并行复制为什么会出现呢?

    因为在5.7的mysql生产环境中,slave端进行复制时,IO线程和SQL线程都是单线程,而master端是多线程,多新城肯定比单线程快的多,这就出现了复制延迟的问题,我们用并行复制就可以解决这个问题,并行复制的目的就是要让slave尽可能的多线程跑起来,当然基于库级别的多线程也是一种方式(不同库的事务,没有锁冲突)

#在从端(slave)端:

[root@server2 ~]# vim /etc/my.cnf
slave-parallel-type=LOGICAL_CLOCK   # 并行的类型
slave-parallel-workers=5  # 开启多少个线程
master_info_repository=TABLE  # maste.info和relay.info是以表的形式存储的
relay_log_info_repository=TABLE   # 存储日志以表的形式
relay_log_recovery=ON  # 支持恢复

在这里插入图片描述

[root@server2 ~]# systemctl restart mysqld
[root@server2 ~]# mysql -p
Enter password: 
mysql> show processlist;

查看有五个线程

在这里插入图片描述

六、组复制

1、MySQL 组复制实现了基于复制协议的多主更新。

    复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事务。但所有读写(RW)事务只有在冲突检测成功后才会提交。只读(RO)事务不需要在冲突检测,可以立即提交。

(1)、特点:

  • 高一致性
    基于原生复制及 paxos 协议的组复制技术,并以插件的方式提供,提供一致数据安全保证;
  • 高容错性
    只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制;
  • 高扩展性
    节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其他节点自动更新组信息,自动维护新的组信息;
  • 高灵活性
    有单主模式和多主模式,单主模式下,会自动选主,所有更新操作都在主上进行;
    2、什么样的应用场景适合用组复制?
    (1)弹性的数据库复制环境
    组复制可以灵活的增加和减少集群中的数据库实例
    (2)高可用的数据库环境
    组复制允许数据库实例宕机,只要集群中大多数服务器可用,则整个数据库服务可用
    (3)替代传统主从复制结构的数据库环境
实验环境:
server1     172.25.34.1      master1
server2     172.25.34.2      master2
server3     172.25.34.3      master3

恢复环境,准备重新初始化

#server1上:

[root@server1 ~]# systemctl stop mysqld
[root@server1 ~]# cd /var/lib/mysql
[root@server1 mysql]# rm -fr *
[root@server1 mysql]# ps ax | grep mysqld  # 确保没有mysqld进程

在这里插入图片描述

 [root@server1 mysql]# uuidgen       # 随机生成uuid
 60ce4906-784d-43c4-b65e-f00323c2f4eb
 [root@server1 mysql]# vim /etc/my.cnf
 28 server-id=1
 29 gtid_mode=ON        # 启用二进制日志
 30 enforce-gtid-consistency=ON
 31 master_info_repository=TABLE
 32 relay_log_info_repository=TABLE
 33 binlog_checksum=NONE
 34 log_slave_updates=ON        # 开启日志同步
 35 log_bin=binlog
 36 binlog_format=ROW          # 二进制日志格式
 37 
 38 
 39 
 40 transaction_write_set_extraction=XXHASH64
 41 loose-group_replication_group_name="60ce4906-784d-43c4-b65e-f00323c2f4eb"    # 这是随机生成的,但是一旦设定,uuid就是确定的
 42 loose-group_replication_start_on_boot=off    # 开机不启动
 43 loose-group_replication_local_address="172.25.34.1:24901"   # 绑定本地的172.25.78.12以及24901端口接受其他组成员的连接
 44 loose-group_replication_group_seeds="172.25.34.2:24901,172.25.34.2:24901,172    .25.34.3:24901"     # 组复制的成员
 45 loose-group_replication_bootstrap_group=off     # 配置不自动引导组
 46 loose-group_replication_ip_whitelist="127.0.0.1,172.25.34.0/24"     # 允许网段
 47 loose-group_replication_enforce_update_everywhere_checks=ON    # 更新检测
 48 loose-group_replication_single_primary_mode=OFF     # 设置组自动选择一个 server 来处理读/写工作。

在这里插入图片描述

[root@server1 mysql]# systemctl start mysqld  # 开启数据库
[root@server1 mysql]# cat /var/log/mysqld.log | grep password  # 获取初始密码

在这里插入图片描述

[root@server1 mysql]# mysql -p   # 用初始密码登录数据库
Enter password: 
mysql> alter user root@localhost identified by 'westoS+1';  # 修改本地用户密码
mysql> SET SQL_LOG_BIN=0;  # 关闭二进制日志,避免在从服务上复制
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'westoS+1';   # 赋予用户密码
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';    # 授权
mysql> FLUSH PRIVILEGES;   # 刷新
mysql> SET SQL_LOG_BIN=1;  # 开启日志
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='westoS+1' FOR CHANNEL 'group_replication_recovery';   # 配置组用户
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';   # 安装plugin插件
mysql> SET GLOBAL group_replication_bootstrap_group=ON;  #这句只有base2,在第一次执行引导组的时候执行
mysql> START GROUP_REPLICATION;  # 开启组复制
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
mysql> SELECT * FROM performance_schema.replication_group_members;  # 查看组复制成员

在这里插入图片描述
在这里插入图片描述

mysql> CREATE DATABASE test:  # 创建数据库
mysql> use test;   
Database changed
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);  # 创建表
mysql> INSERT INTO t1 VALUES (1, 'Luis');
mysql> SELECT * FROM t1;

在这里插入图片描述

# 在server2上:

除了ip变化其他和server1一样。

[root@server2 ~]# systemctl stop mysqld
[root@server2 ~]# cd /var/lib/mysql
[root@server2 mysql]# rm -fr *
[root@server2 mysql]# vim /etc/my.cnf
server-id=2
gtid_mode=ON  # 启用二进制日志
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON   # 开启日志同步
log_bin=binlog
binlog_format=ROW  # 二进制日志格式


transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="60ce4906-784d-43c4-b65e-f00323c2f4eb" # 这是随机生成的,但是一旦设定,uuid就是确定的
loose-group_replication_start_on_boot=off  # 开机不启动
loose-group_replication_local_address="172.25.34.2:24901"
loose-group_replication_group_seeds="172.25.34.1:24901,172.25.34.2:24901,172.25.34.3:24901" # 组复制的成员
loose-group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist="127.0.0.1,172.25.34.0/24" # 允许网段
loose-group_replication_enforce_update_everywhere_checks=ON # 更新检测
loose-group_replication_single_primary_mode=OFF

在这里插入图片描述

[root@server2 mysql]# mysql -p
Enter password: 
mysql> alter user root@localhost identified by 'westoS+1';
mysql> SET SQL_LOG_BIN=0;
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'westoS+1';
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
mysql> FLUSH PRIVILEGES;
mysql> SET SQL_LOG_BIN=1;
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='westoS+1' FOR CHANNEL 'group_replication_recovery';
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';	
mysql> START GROUP_REPLICATION;

报错:
在这里插入图片描述

mysql> STOP GROUP_REPLICATION;
mysql> reset master;
mysql> START GROUP_REPLICATION;

在这里插入图片描述

mysql> select * from performance_schema.replication_group_members;  # 查看组成员已经为2

在这里插入图片描述

#在server3上:

[root@server3 ~]# ls
mysql-community-client-5.7.24-1.el7.x86_64.rpm  
mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm
mysql-community-common-5.7.24-1.el7.x86_64.rpm  
mysql-community-server-5.7.24-1.el7.x86_64.rpm
mysql-community-libs-5.7.24-1.el7.x86_64.rpm
[root@server3 ~]# yum install -y *
[root@server3 ~]# vim /etc/my.cnf
 28 server-id=3
 29 gtid_mode=ON   # 启用二进制日志
 30 enforce_gtid_consistency=ON
 31 master_info_repository=TABLE
 32 relay_log_info_repository=TABLE
 33 binlog_checksum=NONE
 34 log_slave_updates=ON   # 开启日志同步
 35 log_bin=binlog
 36 binlog_format=ROW  # 二进制日志格式
 37 
 38 transaction_write_set_extraction=XXHASH64
 39 loose-group_replication_group_name="60ce4906-784d-43c4-b65e-f00323c2f4eb" #     这是随机生成的,但是一旦设定,uuid就是确定的
 40 loose-group_replication_start_on_boot=off  # 开机不启动
 41 loose-group_replication_local_address="172.25.34.3:24901"
 42 loose-group_replication_group_seeds="172.25.34.1:24901,172.25.34.2:24901,172    .25.34.3:24901" # 组复制的成员
 43 loose-group_replication_bootstrap_group=off
 44 loose-group_replication_ip_whitelist="127.0.0.1,172.25.34.0/24" # 允许网段
 45 loose-group_replication_enforce_update_everywhere_checks=ON # 更新检测
 46 loose-group_replication_single_primary_mode=OFF

在这里插入图片描述

[root@server3 ~]# systemctl start mysqld
[root@server3 ~]# cat /var/log/mysqld.log | grep password

在这里插入图片描述

[root@server3 ~]# mysql -p
Enter password: 
mysql> alter user root@localhost identified by 'westoS+1';
mysql> SET SQL_LOG_BIN=0;	
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'westoS+1';
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
mysql>  FLUSH PRIVILEGES;
mysql>  SET SQL_LOG_BIN=1;
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='westoS+1' FOR CHANNEL 'group_replication_recovery';
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
mysql> reset master;
mysql>  START GROUP_REPLICATION;    # 开启组复制
mysql> SELECT * FROM performance_schema.replication_group_members; # 查看组成员成员状态

在这里插入图片描述
mysql> show databases; # 直接查看,把master1上的数据同步成功
在这里插入图片描述

mysql> use test;
Database changed
mysql> show tables;

在这里插入图片描述

#在server2(master2)上查看,也同步成功

mysql> use test;
Database changed
mysql> select * from t1;

在这里插入图片描述

#在任意一方插入数据都可以成功,也都能查看到插入的数据
mysql> INSERT INTO t1 VALUES (2, 'redhat');
mysql>  INSERT INTO t1 VALUES (3, 'hongmao');
mysql> select * from t1;

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值