zoukankan      html  css  js  c++  java
  • 安装MySQL半同步复制

    一、简介

    从MySQL5.5开始,MySQL以插件的形式支持半同步复制。如何理解半同步呢?首先我们来看看异步,全同步的概念

    异步复制(Asynchronous replication)

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

    全同步复制(Fully synchronous replication)

      指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同
    步复制的性能必然会收到严重的影响。

    半同步复制(Semisynchronous replication)

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

    下面来看看半同步复制的原理图:

    半同步复制的潜在问题

    客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了,此时,可能的情况有两种:

    1.事务还没发送到从库上

    此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份
    重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。

    2.事务已经发送到从库上

    此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。

    无数据丢失的半同步复制

    针对上述潜在问题,MySQL 5.7引入了一种新的半同步方案:Loss-Less半同步复制。针对上面这个图,“Waiting Slave dump”被调整到“Storage Commit”之前。

    当然,之前的半同步方案同样支持,MySQL 5.7.2引入了一个新的参数进行控制-rpl_semi_sync_master_wait_point

    rpl_semi_sync_master_wait_point有两种取值:

    AFTER_SYNC   #这个即新的半同步方案,Waiting Slave dump在Storage Commit之前。
    AFTER_COMMIT   #老的半同步方案,如图所示。

    二、安装环境和要求

    环境:

    关闭防火墙

    时间同步

    连接网络并配置yum和epel源

    安装要求:

    1. MySQL 5.5及以上版本(实验使用的为MySQL-5.6.36二进制版本)
    2. 变量have_dynamic_loading为YES
    3. 异步复制已经存在(主从)

    三、安装与配置

    1.在两台MySQL服务器上检查"have_dynamic_loading"是否为YES

    mysql> show variables like 'have_dynamic_loading';  
    +----------------------+-------+
    | Variable_name        | Value |
    +----------------------+-------+
    | have_dynamic_loading | YES   |
    +----------------------+-------+

    2.master(192.168.1.11)服务器安装插件

    mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; #安装插件
    Query OK, 0 rows affected (0.20 sec)
    
    mysql> show plugins; #查看是否安装成功
    +----------------------------+----------+--------------------+--------------------+---------+
    | Name                       | Status   | Type               | Library            | License |
    +----------------------------+----------+--------------------+--------------------+---------+     |
    | rpl_semi_sync_master       | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |
    +----------------------------+----------+--------------------+--------------------+---------+
    43 rows in set (0.14 sec)
    
    mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;  #开启半同步复制,默认是关闭的
    Query OK, 0 rows affected (0.29 sec)

    3.slave(192.168.1.12)服务器安装插件

    mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; #安装插件
    Query OK, 0 rows affected (0.29 sec) 
    
    mysql> show plugins;  #查看插件是否安装成功
    +----------------------------+----------+--------------------+-------------------+---------+
    | Name                       | Status   | Type               | Library           | License |
    +----------------------------+----------+--------------------+-------------------+---------+   |
    | rpl_semi_sync_slave        | ACTIVE   | REPLICATION        | semisync_slave.so | GPL     |
    +----------------------------+----------+--------------------+-------------------+---------+
    43 rows in set (0.04 sec)
    
    mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1; #开启半同步复制
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> STOP SLAVE IO_THREAD;   #重启从服务器IO线程,手动将异步模式切换为半同步模式
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> START SLAVE IO_THREAD;
    Query OK, 0 rows affected (0.00 sec)

    重启后,slave会在master上注册为半同步复制的slave角色。这时候,主的error.log中会打印如下信息:

    2018-01-19 20:09:56 33021 [Note] Semi-sync replication initialized for transactions.
    2018-01-19 20:09:56 33021 [Note] Semi-sync replication enabled on the master.
    2018-01-19 20:13:16 33021 [Note] Stop asynchronous binlog_dump to slave (server_id: 2)
    2018-01-19 20:13:16 33021 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000002, 695)

    4.查看半同步是否在运行

    master(192.168.1.11):

    mysql>  show status like 'Rpl_semi_sync_master_status';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | Rpl_semi_sync_master_status | ON    |
    +-----------------------------+-------+
    1 row in set (0.02 sec)

    slave(192.168.1.12):

    mysql>  show status like 'Rpl_semi_sync_slave_status';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | ON    |
    +----------------------------+-------+
    1 row in set (0.06 sec)

    5.配置MySQL配置文件

    master(192.168.1.11):

    plugin-load=rpl_semi_sync_master=semisync_master.so
    rpl_semi_sync_master_enabled=1

    slave(192.168.1.12):

    plugin-load=rpl_semi_sync_slave=semisync_slave.so
    rpl_semi_sync_slave_enabled=1

    在有的高可用架构下,master和slave需同时启动,以便在切换后能继续使用半同步复制(即同时安装master和slave插件)

    plugin-load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
    rpl-semi-sync-master-enabled = 1
    rpl-semi-sync-slave-enabled = 1

    6.查看相关参数

    master(192.168.1.11):

    mysql> show variables like '%semi%'; #环境变量
    +------------------------------------+-------+
    | Variable_name                      | Value |
    +------------------------------------+-------+
    | rpl_semi_sync_master_enabled       | ON    |   #表示开启半同步复制 
    | rpl_semi_sync_master_timeout       | 10000 |   #默认1000毫秒,即10秒超时,将切换为异步复制
    | rpl_semi_sync_master_trace_level   | 32    |   #表示用于开启半同步复制时的调试级别,默认32
    | rpl_semi_sync_master_wait_no_slave | ON    |   #表示是否允许master每个事物都要等待slave接收确认,默认为ON.说得直白一点,如果我的架构是1主2从,2个从都采用了半同步复制,且设置的是rpl_semi_sync_master_wait_for_slave_count=2,如果其中一个挂掉了,对于rpl_semi_sync_master_wait_no_slave设置为ON的情况,此时显示的仍然是半同步复制,如果rpl_semi_sync_master_wait_no_slave设置为OFF,则会立刻变成异步复制。
    +------------------------------------+-------+
    4 rows in set (0.00 sec)
    mysql> show 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     |  #表示从服务器确认成功提交的数量
    +--------------------------------------------+-------+
    14 rows in set (0.00 sec)

    slave(192.168.1.12):

    mysql> show variables like '%semi%';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | rpl_semi_sync_slave_enabled     | ON    |  #表示在slave已经开始半同步复制模式
    | rpl_semi_sync_slave_trace_level | 32    |  #表示用于开启半同步复制时的调试级别,默认32
    +---------------------------------+-------+
    2 rows in set (0.20 sec)
    mysql> show status like '%semi%';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | ON    |  #表示从服务器开启半同步复制
    +----------------------------+-------+
    1 row in set (0.08 sec)

    至此,MySQL半同步复制搭建完毕!

    四、测试

    事实上,半同步复制并不是严格意义上的半同步复制

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

    下面来测试一下:

    1.slave执行stop slave;关闭主从复制

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

    2、master上创建一个表,没接收到反馈信号,等待十秒后(Rpl_semi_sync_master_timeout=1000等待超时),继续执行

    mysql> use test;
    Database changed
    mysql> create table table1(id int);
    Query OK, 0 rows affected (10.48 sec)
    
    mysql> show tables;
    +----------------+
    | Tables_in_test |
    +----------------+
    | table1         |
    +----------------+
    1 row in set (0.01 sec)

    slave上查看是否有table1表

    mysql> use test;
    Database changed
    mysql> show tables;
    Empty set (0.00 sec)

    3、master在数据库中再创建table2,不需要等待反馈,直接执行(因为当反馈超时时,master将切换到异步复制模式。此时是异步模式,不需要等待)

    mysql> create table table2(id int);
    Query OK, 0 rows affected (0.11 sec)
    
    mysql> show tables;
    +----------------+
    | Tables_in_test |
    +----------------+
    | table1         |
    | table2         |
    +----------------+
    2 rows in set (0.00 sec)

    4、slave执行start slave,数据开始同步,建立table1、table2,反馈给master,并切换为半同步复制

    mysql> start slave;
    Query OK, 0 rows affected (0.07 sec)
    
    mysql> show tables;
    +----------------+
    | Tables_in_test |
    +----------------+
    | table1         |
    | table2         |
    +----------------+
    2 rows in set (0.01 sec)

    总结:

    1. 在一主多从的架构中,如果要开启半同步复制,并不要求所有的从都是半同步复制。
    2. MySQL 5.7极大的提升了半同步复制的性能。
        5.6版本的半同步复制,dump thread 承担了两份不同且又十分频繁的任务:传送binlog 给slave ,还需要等待slave反馈信息,而且这两个任务是串行的,
    dump thread 必须等待 slave 返回之后才会传送下一个 events 事务。dump thread 已然成为整个半同步提高性能的瓶颈。在高并发业务场景下,这样的机制
    会影响数据库整体的TPS 。
    5.7版本的半同步复制中,独立出一个 ack collector thread ,专门用于接收slave 的反馈信息。这样 master 上有两个线程独立工作, 可以同时发送

    binlog 到slave ,和接收slave的反馈。

    参考:https://www.cnblogs.com/ivictor/p/5735580.html

  • 相关阅读:
    两小时入门Docker
    Django之Model操作
    Django-channels 实现WebSocket实例
    Python项目中的单元测试
    將Python打包成 exe可执行文件
    CORS 跨域
    购物车模块
    登陆模块
    Git 基本用法
    Django ORM性能优化 和 图片验证码
  • 原文地址:https://www.cnblogs.com/panwenbin-logs/p/8318808.html
Copyright © 2011-2022 走看看