MySQL同步机制、主从复制半同步和双主配置

SyncNavigator是一款功能强大的数据库同步软件,适用于SQL SERVER, MySQL,具有自动/定时同步数据、无人值守、故障自动恢复、同构/异构数据库同步、断点续传和增量同步等功能,支持Windows xp以上所有操作系统,适用于大容量数据库快速同步。

安装包下载地址:https://www.syncnavigator.cn/Setup.zip

帮助文档地址:https://www.syncnavigator.cn/Help_zh-CN.chm

Web文档地址:https://www.syncnavigator.cn/chm/index.htm


复制架构衍生史

在谈这个特性之前,我们先来看看MySQL的复制架构衍生史。

在2000年,MySQL 3.23.15版本引入了Replication。Replication作为一种准实时同步方式,得到广泛应用。这个时候的Replicaton的实现涉及到两个线程,一个在Master,一个在Slave。Slave的I/O和SQL功能是作为一个线程,从Master获取到event后直接apply,没有relay log。这种方式使得读取event的速度会被Slave replay速度拖慢,当主备存在较大延迟时候,会导致大量binary log没有备份到Slave端。

在2002年,MySQL 4.0.2版本将Slave端event读取和执行独立成两个线程(IO线程和SQL线程),同时引入了relay log。IO线程读取event后写入relay log,SQL线程从relay log中读取event然后执行。这样即使SQL线程执行慢,Master的binary log也会尽可能的同步到Slave。当Master宕机,切换到Slave,不会出现大量数据丢失。

在2010年MySQL 5.5版本之前,一直采用的是这种异步复制的方式。主库的事务执行不会管备库的同步进度,如果备库落后,主库不幸crash,那么就会导致数据丢失。于是在MySQL在5.5中就顺其自然地引入了半同步复制,主库在应答客户端提交的事务前需要保证至少一个从库接收并写到relay log中。那么半同步复制是否可以做到不丢失数据呢?下面分析。

在2016年,MySQL在5.7.17中引入了一个全新的技术,称之为InnoDB Group Replication。目前官方MySQL 5.7.17基于Group replication的全同步技术已经问世,全同步技术带来了更多的数据一致性保障。相信是未来同步技术一个重要方向,值得期待。MySQL 5.7 Group Replication

同步机制

主从复制机制:

  • 1.对于异步复制,主库将事务Binlog事件写入到Binlog文件中,此时主库只会通知一下Dump线程发送这些新的Binlog,然后主库就会继续处理提交操作,而此时不会保证这些Binlog传到任何一个从库节点上。
  • 2.对于全同步复制,当主库提交事务之后,所有的从库节点必须收到,APPLY并且提交这些事务,然后主库线程才能继续做后续操作。这里面有一个很明显的缺点就是,主库完成一个事务的时间被拉长,性能降低。
  • 3.对于半同步复制,是介于全同步复制和异步复制之间的一种,主库只需要等待至少一个从库节点收到并且Flush Binlog到Relay Log文件即可,主库不需要等待所有从库给主库反馈。同时,这里只是一个收到的反馈,而不是已经完全执行并且提交的反馈,这样就节省了很多时间。

主主复制机制:组复制之多主模式
组复制是一种可用于实现容错系统的技术。 复制组是一个通过消息传递相互交互的 server 集群。通信层提供了原子消息(atomicmessage)和完全有序信息交互等保障机制,实现了基于复制协议的多主更新

复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事务。但所有读写(RW)事务只有在冲突检测成功后才会提交。只读(RO)事务不需要在冲突检测,可以立即提交。句话说,对于任何 RW 事务,提交操作并不是由始发 server 单向决定的,而是由组来决定是否提交。准确地说,在始发 server 上,当事务准备好提交时,该 server 会广播写入值(已改变的行)和对应的写入集(已更新的行的唯一标识符)。然后会为该事务建立一个全局的顺序。最终,这意味着所有 server 成员以相同的顺序接收同一组事务。因此,所有 server 成员以相同的顺序应用相同的更改,以确保组内一致。
在这里插入图片描述
组复制主要用于数据库集群中,多主数据同步,和主从同步不同,每个主库的数据保持一致,都可以接受写操作

MySQL使用半同步协议复制

1. 半同步机制

A. 当Master上开启半同步复制的功能时,至少应该有一个Slave开启其功能。此时,一个线程在Master上提交事务将受到阻塞,直到得知一个已开启半同步复制功能的Slave已收到此事务的所有事件,或等待超时。

B. 当Slave主机连接到Master时,能够查看其是否处于半同步复制的机制。

C. 当一个事务的事件都已写入其relay-log中且已刷新到磁盘上,Slave才会告知已收到;这取决于sync_relay_log参数。

D. 如果等待超时,也就是Master没被告知已收到,此时Master会自动转换为异步复制的机制。当至少一个半同步的Slave赶上了,Master与其Slave自动转换为半同步复制的机制。

E. 半同步复制的功能要在Master,Slave都开启,半同步复制才会起作用;否则,只开启一边,它依然为异步复制。

Master配置(接着上一个主从复制实验开始)

首先,安装半同步模块并启动,此模块根据MySQL安装方式不同位置也可能不太一样。如果是二进制安装,则会在MySQL安装目录的./lib/plugin/下存放。建议无论主从都安装master & slave模块,以免高可用模式下遗忘。

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
  • 1
  • 2

查看半同步相关的状态信息,如下:

mysql> show global variables like '%semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | OFF   |
| rpl_semi_sync_master_timeout       | 10000 |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
| rpl_semi_sync_slave_enabled        | OFF   |
| rpl_semi_sync_slave_trace_level    | 32    |
+------------------------------------+-------+
6 rows in set (0.00 sec)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

其中rpl_semi_sync_master_enabled参数表示Master是否开启了半同步协议,参数rpl_semi_sync_master_timeout表示与Slave半同步协议通信超时时间,如果超过这个时间则自动降级为异步复制。

下面开启Master上的半同步复制协议,并且调小了超时时间为2s,一旦有一次超时自动降级为异步。

mysql> set global rpl_semi_sync_master_enabled = 1;
mysql> set global rpl_semi_sync_master_timeout = 2000;
 
  • 1
  • 2
  • 3

以上内容要想永久有效需要写到配置文件中,生产需写入配置文件,避免重启后半同步失效。

rpl_semi_sync_master_enabled = 1;
rpl_semi_sync_master_timeout = 2000;

  • 1
  • 2
  • 3

3. Slave配置(接着上一个实验开始)

首先,安装半同步模块并启动。


mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql> set global rpl_semi_sync_slave_enabled = 1;
mysql> show global variables like '%semi_sync_slave%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

从节点需要重新连接主服务器半同步才会生效。

mysql> stop slave io_thread;
mysql> start slave io_thread;
 
  • 1
  • 2
  • 3

PS:如果想卸载异步模块就使用uninstall即可。

4. Master上查看是否启用了半同步

此时,半同步复制应该已经正常工作了。可以在Master上查看半同步相关状态变量。

mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| 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     |
| Rpl_semi_sync_slave_status                 | OFF   |
+--------------------------------------------+-------+
15 rows in set (0.00 sec)
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

现在半同步已经正常工作了,主要看Rpl_semi_sync_master_clients是否不为0,Rpl_semi_sync_master_status是否为ON。其中Rpl_semi_sync_master_clients=1表示此时有一个Slave以半同步协议连接Master。如果Rpl_semi_sync_master_status为OFF,说明出现了网络延迟或Slave IO线程异常,导致自动切换为异步复制了。

那么可以验证一下半同步超时,是否会自动降为异步工作。可以在Slave上停掉半同步协议,然后在Master上创建数据库看一下能不能复制到Slave上。

Slave 关闭半同步

mysql> set global rpl_semi_sync_slave_enabled = 0;
mysql> stop slave io_thread;
mysql> start slave io_thread;
  • 1
  • 2
  • 3

Master

mysql> create database dbtest;
Query OK, 1 row affected (2.01 sec)

mysql> create database dbtest01;
Query OK, 1 row affected (0.01 sec)
  • 1
  • 2
  • 3
  • 4
  • 5

创建第一个数据库花了2.01秒,而我们前面设置的超时时间是2秒,而创建第二个数据库花了0.01秒,由此得出结论是超时转换为异步传送。可以在Master上查看半同步相关的参数值Rpl_semi_sync_master_clients和Rpl_semi_sync_master_status是否正常。

mysql> show global status like '%semi%';   
+--------------------------------------------+-------------+
| Variable_name                              | Value       |
+--------------------------------------------+-------------+
| Rpl_semi_sync_master_clients               | 0           |
| Rpl_semi_sync_master_net_avg_wait_time     | 294         |
| Rpl_semi_sync_master_net_wait_time         | 588         |
| Rpl_semi_sync_master_net_waits             | 2           |
| Rpl_semi_sync_master_no_times              | 1           |
| Rpl_semi_sync_master_no_tx                 | 2           |
| Rpl_semi_sync_master_status                | OFF         |
| Rpl_semi_sync_master_timefunc_failures     | 0           |
| Rpl_semi_sync_master_tx_avg_wait_time      | 317         |
| Rpl_semi_sync_master_tx_wait_time          | 635         |
| Rpl_semi_sync_master_tx_waits              | 2           |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0           |
| Rpl_semi_sync_master_wait_sessions         | 0           |
| Rpl_semi_sync_master_yes_tx                | 2           |
| Rpl_semi_sync_slave_status                 | OFF         |
| Rpl_status                                 | AUTH_MASTER |
+--------------------------------------------+-------------+
16 rows in set (0.00 sec)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

可以看到都自动关闭了,需要注意一点的是,当Slave开启半同步后,或者当主从之间网络延迟恢复正常的时候,半同步复制会自动从异步复制又转为半同步复制,还是相当智能的。

另外,参数Rpl_semi_sync_master_no_times表示主库启动切换为异步的次数,可以看到我们这里模拟了一次切换,值加1了。参数Rpl_semi_sync_master_no_tx表示降级为异步后产生的事务数,这里变为2了。需要注意的是,DDL一条语句执行成功就会加1,DML一个事务成功才会加1。这些参数都可以用来做监控使用。

另外个人在实际使用中还碰到一种情况从库IO线程有延迟时,主库会自动把半同步复制降为异步复制;当从库IO延迟没有时,主库又会把异步复制升级为半同步复制。可以进行压测模拟,但是此时查看Master的状态跟上面直接关闭Slave半同步有些不同,会发现Rpl_semi_sync_master_clients仍然等于1,而Rpl_semi_sync_master_status等于OFF。

MySQL双主复制

MySQL双主复制模型如果配置出现问题,很有可能会导致主从数据不一致。单双主模型能做什么呢?可以分摊读的压力,但写数据同一时刻只能有一台。另外可以在双主模型下做高可用。

1)在两台服务器上各自建立一个具有复制权限的用户。

2)修改配置文件。

主服务器上配置

[mysqld]
server-id = 10
log-bin = mysql-bin
relay-log = relay-mysql
relay-log-index = relay-mysql.index
auto-increment-increment = 2
auto-increment-offset = 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

从服务器上配置

[mysqld]
server-id = 20
log-bin = mysql-bin
relay-log = relay-mysql
relay-log-index = relay-mysql.index
auto-increment-increment = 2
auto-increment-offset = 2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

两台服务器都需要开启二进制日志和中继日志。对于Master设置主键自动增长auto-increment-offset起始值从1开始,auto-increment-increment步长为2,也就是auto_increment为奇数。而对于Slava自动增长从2开始,偏移为2,也就是auto_increment为偶数。这样才能避免两台服务器数据同步时出现主键冲突问题。

3)主从各自连接对方服务器CHANGE MASTER

4)主从服务器各自自动复制对方的Slave

Percona toolkit

对于MySQL的管理,percona toolkit工具可以说非常强大,建议使用。

其中percona toolkit的pt-table-checksum工具可以用来评估主从服务表中的数据是否一致,而pt-table-sync工具可以用来解决主从数据的不一致问题。使用这些工具时在主服务器上操作,会主动去检测所有的从服务器。

©️2020 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值