MySQ主从复制,基于GTID的主从复制和半同步,并行复制

版权声明:©2004 Microsoft Corporation. All rights reserved. https://blog.csdn.net/qq_42036824/article/details/87912223

实验环境:rhel7.3 selinux and firewalld disabled

主机环境:

  • 主库端: server3:172.25.19.3
  • 从库端: server4:172.25.19.4

一、mysql5.7主从复制

  • 主从复制的要求:
    (1)主库开启binlog日志(设置log-bin参数)
    (2)主从server-id不同
    (3)从库服务器能连同主库

  • 主从复制原理:
      mysql的主从配置又叫replication,AB复制,基于binlog二进制日志,主数据库必须开启binlog二进制日志才能进行复制。

(1)主数据库将更改操作记录到binlog二进制日志(主数据库有log dump线程和从数据库的i/o线程传递binlog)。
(2)从库生成两个线程,一个i/o线程,一个SQL线程
(3)i/o线程去请求主库的binlog,并且得到的binlog日志写到relay log(中继日志)文件中
(4)然后主库会生成一个log dump线程,用来给从库的i/o线程传binlog;SQL线程,会读取中继日志文件,并解析成具体的操作执行,这样主从的操作就一致了,而最终的数据也就一致了。
  作为异步复制,其主库将事件写入binlog二进制文件,dump线程将binlog文件发送出去,不保证其他从节点是否会收到binlog二进制文件。

  • 部署过程:

配置主库端:
1.在主库中安装mysql

[root@server3 ~]# 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@server3 ~]# yum install *

2.打开数据库

[root@server3 ~]# systemctl start mysqld

3.查看密码

[root@server3 ~]# cat /var/log/mysqld.log | grep password
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190225094744512.png)

4.进行初始化,修改密码否则进入数据库也无法操作

  • 注意:密码需要有数字 大小写字母 特殊字符 三者构成 缺一不可! 密码位数大于8
[root@server3 ~]# mysql_secure_installation 

Securing the MySQL server deployment.

Enter password for user root:   ##刚才找出的密码

The existing password for the user account root has expired. Please set a new password.      ##设置新的密码

New password: 

Re-enter new password: 
The 'validate_password' plugin is installed on the server.
The subsequent steps will run with the existing configuration
of the plugin.
Using existing password for root.

Estimated strength of the password: 100 
Change the password for root ? ((Press y|Y for Yes, any other key for No) : 

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Success.
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
Success.
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.

All done! 
  1. 编辑配置文件
[root@server3 ~]# vim /etc/my.cnf
最后面添加:
 29 log-bin=mysql-bin     ##开启二进制日志
 30 server-id=1           服务器ID

在这里插入图片描述

  1. 重启服务,则配置文件生效
[root@server3 ~]# systemctl restart mysqld
  1. 创建用户并授权
    在这里插入图片描述
    参数解释:
    replication    表示授权复制的权限  
    *.*         表示所有数据库可以进行同步 
    Hui         表示授权名,可以随意填写 
    '172.25.19.%'   表示授权172.25.19.0/24的网段所有服务器可以同步, %表示任意
  • 查看二进制日志是否打开
    在这里插入图片描述
  • 查看主库的状态
    在这里插入图片描述
    配置从库端:
  1. 安装mysql
[root@server4 ~]# 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 
  1. 能够登陆视为授权成功
[root@server4 ~]# mysql -u hui -p -h 172.25.19.3

在这里插入图片描述

  1. 打开mysql
[root@server4 ~]# systemctl start mysqld
  1. 查看密码
[root@server4 ~]# cat /var/log/mysqld.log | grep password

在这里插入图片描述

  1. 初始化,和主库端一样
[root@server4 ~]# mysql_secure_installation 同3
  1. 编写配置文件
[root@server4 ~]# vim /etc/my.cnf
 29 server-id=2          ##填写server-id和主端不同即可
  1. 重启服务
[root@server4 ~]# systemctl restart mysqld
  1. 设定从设备并开启从设备
  • 注意:master_log_file 和master_log_pos 的值都要依照主设备状态中的值来设定,因为会变化
    在这里插入图片描述
    在这里插入图片描述

测试:

  1. 在主库端创建库,创建表,并插入数据
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 注意:主库的状态信息中的Position 一直在变更
    在这里插入图片描述
  1. 在从库中查看是否复制到 (可以查到代表复制成功)
    在这里插入图片描述
    在这里插入图片描述

二、基于GDIT主从复制

  • mysql数据库从5.6.5开始新增一种基于GDIT的复制方式。GTID (Global Transaction ID) 是对于一个已提交事务的编号,并且是一个全局唯一的编号。 GTID 实际上 是由 UUID+TID 组成的。其中 UUID 是一个 MySQL 实例的唯一标识。

  • 主从复制,默认是通过pos复制(postion),就是说在日志文档里,将用户进行的每一项操作都进行编号(pos),每一个event都有一个起始编号,一个终止编号,我们在配置主从复制时从节点时,要输入master的log_pos值就是这个原因,要求它从哪个pos开始同步数据库里的数据,这也是传统复制技术。

  • MySQL5.6增加了GTID复制,GTID就是类似于pos的一个作用,不过它是整个mysql复制架构全局通用的,就是说在这整个mysql冗余架构中,它们的日志文件里事件的GTID值是一致的.

  • GTID (Global Transaction ID) 是对于一个已提交事务的编号,并且是一个全局唯一的编号。 GTID 实际上 是由 UUID+TID 组成的。其中 UUID 是一个 MySQL 实例的唯一标识。TID 代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。

  • 通过GDIT保证每个主库上提交的事务在集群中有一个唯一的ID.这种方式强化了数据库的主备一致性,故障恢复以及容错能力。

pos与GTID有什么区别?

  • 两者都是日志文件里事件的一个标志,如果将整个mysql集群看作一个整体,pos就是局部的,GTID就是全局的.

部署过程:

1.主从端都修改配置文件

[root@server3 ~]# vim /etc/my.cnf
 32 gtid_mode=ON            开启gtid模式
 33 enforce-gtid-consistency=true    强制gtid一直性,用于保证启动gitd后事务的安全

在这里插入图片描述

[root@server4 ~]# vim /etc/my.cnf
 32 gtid_mode=ON      
 33 enforce-gtid-consistency=true
  1. 主从端都重启服务
[root@server3 ~]# systemctl restart mysqld
[root@server4 ~]# systemctl restart mysqld
  1. 在从库端先停掉slave,然后重新创建连接
  • 如果进行change master to时使用MASTER_AUTO_POSITION = 1, slave连接master将使用基于GTID的复制协议。
    在这里插入图片描述
    在这里插入图片描述

测试:

  1. 在主库表中添加新的信息
    在这里插入图片描述

  2. 从库查看是否复制成功
    在这里插入图片描述
    以上,同步成功

三、基于GDIT的半同步

  • MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。
  • 半同步复制就是为了解决数据丢失的问题。

部署过程:

1.主库安装服务插件,并且开启半同步复制

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.35 sec)

mysql> set global rpl_semi_sync_master_enabled=ON;
Query OK, 0 rows affected (0.01 sec)

mysql> select plugin_name,plugin_status
    -> from information_schema.plugins
    -> where plugin_name like '%semi%';
+----------------------+---------------+
| plugin_name          | plugin_status |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+
1 row in set (0.00 sec)

mysql> show variables like '%semi%';    #环境变量
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |     ## ##默认10000毫秒(10秒),生产环境中建议设置为无穷大
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

mysql> show status like '%rpl_semi_sync%';   #状态变量
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
  1. 在从端也安装插件,开启半同步复制
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.10 sec)

mysql> set global rpl_semi_sync_slave_enabled=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%semi%';    
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)

- 注意:要重启从上的IO线程,如果没有重启,则默认还是异步复制,重启后,slave会在master上注册为半同步复制的slave角色

mysql> stop slave io_thread;
Query OK, 0 rows affected (0.35 sec)

mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)

测试: 半同步失败的情况

  1. 先测试一个没有通过半同步复制的
  • 从端关掉IO线程:
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.63 sec)
  • 再在主端表中插入数据,会等待10秒中,10s后会变为异步复制
mysql> use westos;

mysql> insert into userlist values ('user5','555');
Query OK, 1 row affected (10.38 sec)
  • 此时在主端发现半同步失败次数+1
    (1)Rpl_semi_sync_master_no_tx
    表示没有成功接收slave提交的次数,也就是使用半同步失败的次数,10s后没有得到反馈信息,会转为异步复制
    (2)Rpl_semi_sync_master_yes_tx
    使用半同步成功的次数,数据的一致性能提高

在这里插入图片描述

  • 然后从端会发现没有同步过来,再次打开IO线程后,数据才能同步过来,此时复制过来的是异步复制的结果

测试2:半同步正常情况

  • 从端打开IO:
mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)
  • 主端插入新数据:
mysql> use westos;
Database changed
mysql> insert into userlist values ('user6','666');
Query OK, 1 row affected (0.53 sec)

mysql> show status like '%rpl%';  ##发现Rpl_semi_sync_master_yes_tx 变为1,成功了一次
  • 从端验证同步结果:
##user6用户信息被成功复制到
mysql> select * from userlist;
+----------+----------+
| username | password |
+----------+----------+
| user1    | 123      |
| user2    | 356      |
| user3    | 789      |
| user4    | 444      |
| user5    | 555      |
| user6    | 666      |
+----------+----------+
6 rows in set (0.00 sec)

四、MySQL5.7基于组提交的并行复制

并行复制的原理:

  • 在普通的主从复制架构中,slave服务器上有两个线程:IO线程和SQL线程。IO线程负责接收master的二进制日志(准确的说是二进制日志的event),SQL线程负责应用二进制日志(准确的说是relay-log)。
  • 在MySQL5.6版本中的并行复制中(需开启并行复制功能),SQL线程变为coordinator线程,判断是否可以并发执行:
    • 如可以并行执行,选择worker线程执行二进制日志
    • 如不可并行执行,是DDL或是跨schema的操作,则等待所有的worker线程执行完成之后再执行当前日志
  • coordinator线程不仅仅可以将日志发送给worker线程,也可以回放日志,但是并行的操作都会交给worker线程来完成
  • 5.7中引入了slave-parallel-type参数,用来控制并发复制的方式,可用的值为DATABASE和LOGICAL_CLOCK
    • DATABASE:默认值,基于库的并行复制方式
    • LOGICAL_CLOCK:基于组提交的并行复制方式(LOGICAL_CLOCK是一个全局递增的64位长整型数字,主要通过它来判断哪些事务能够并发)

并行复制:解决延迟的问题
如何判断延迟:

  • show master status\G
    (1)Seconds_Behind_Master: 0 ##数字0代表没有延迟
    (2)对比一下后面的数字是否一样,一样则没有延迟
    Read_Master_Log_Pos: 2664
    Exec_Master_Log_Pos: 2664

配置:只需要在slave上设置

  1. 编写配置文件
[root@server4 ~]# vim /etc/my.cnf

 34 slave-parallel-type=LOGICAL_CLOCK     基于组提交的并行复制方式 
 35 slave-parallel-workers=5             
 36 master_info_repository=TABLE        以表的形式记录,如果是file(默认),则会进行刷盘的动作,对mysql的性能会有很大的影响
 37 relay_log_info_repository=TABLE
 38 relay_log_recovery=ON       开启日至恢复
  • slave-parallel-workers=5
    开启5个线程,如果设置为0,则退化成原来的单线程,如果设置为1,则SQL线程功能转化为coordinator线程,但是只有一个worker线程回放(也就是单线程复制),但是因为多了一次coordinator线程的转化,因此=1的性能反而比=0的还差。
  1. 重启服务
[root@server4 ~]# systemctl restart mysqld
  1. 查看工作进程
mysql> show tables;
mysql> select * from slave_master_info;
mysql> select * from slave_relay_log_info
mysql> show processlist;            ##就发现有5个worker进程

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42036824/article/details/87912223