zoukankan      html  css  js  c++  java
  • MySQL-半同步复制原理实践

    参考文档:

    http://mysql.taobao.org/monthly/2017/04/01/ 阿里内核月报半同步复制的数据一致性

    https://www.cnblogs.com/ivictor/p/5735580.html 半同步复制搭建

    https://www.cnblogs.com/f-ck-need-u/p/9166452.html 大神博客

    复制类型

    异步复制(Asynchronous replication)

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

    全同步复制(Fully synchronous replication)

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

    半同步复制(Semisynchronous replication

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

     

    半同步复制的两种模式

    5.7.2开始,半同步支持两种类型

    控制参数

    rpl_semi_sync_master_wait_point

    两个值:AFTER_SYNC和AFTER_COMMIT。

    在MySQL 5.7.2之后,默认值为AFTER_SYNC,在此版本之前,等价的类型为AFTER_COMMIT

    这个变量控制master何时提交,何时接时ACK以及何时将成功信息回复给客户端

    1. AFTER_SYNC模式:master将新的事务写进binlog(buffer),然后发送给slave,再sync到自己的binlog file(disk)。之后才允许接收slave的ack回复,接收到ack之后才会提交事务,并返回成功信息给客户端。
    2. AFTER_COMMIT模式:master将新的事务写进binlog(buffer),然后发送给slave,再sync到自己的binlog file(disk),然后直接提交事务。之后才允许接收slave的ack回复,然后再返回成功信息给客户端。

    前提:已经设置了sync_binlog=1,否则binlog刷盘时间由操作系统决定

     

    两种模式的优缺点

    • AFTER_SYNC

      • 对于所有客户端来说,它们看到的数据是一样的,因为它们看到的数据都是在接收到slave的ack后提交后的数据。

      • 这种模式下,如果master突然故障,不会丢失数据,因为所有成功的事务都已经写进slave的relay log中了,slave的数据是最新的。

    • AFTER_COMMIT
      • 不同客户端看到的数据可能是不一样的。对于发起事务请求的那个客户端,它只有在master提交事务且收到slave的ack后才能看到提交的数据。但对于那些非本次事务的请求客户端,它们在master提交后就能看到提交后的数据,这时候master可能还没收到slave的ack。
      • 如果master收到ack回复前,slave和master都故障了,那么将丢失这个事务中的数据。

    在MySQL 5.7.2之前,等价的模式是 AFTER_COMMIT ,在此版本之后,默认的模式为 AFTER_SYNC ,该模式能最大程度地保证数据安全性,且性能上并不比 AFTER_COMMIT 差。

     

    MySQL半同步插件介绍

    MySQL的半同步是通过加载google为MySQL提供的半同步插件 semisync_master.so 和 semisync_slave.so 来实现的。其中前者是master上需要安装的插件,后者是slave上需要安装的插件。

    MySQL的插件位置默认存放在$basedir/lib/plugin目录下

    [mysql@g1-db-test ~/jin1_mysql/lib/plugin]$ ll|grep semi
    -rwxr-xr-x 1 mysql mysql   708290 Nov 29  2018 semisync_master.so
    -rwxr-xr-x 1 mysql mysql   152309 Nov 29  2018 semisync_slave.so
    

      

    查看MySQL是否支持半同步插件

    (admin@g1-db-test-v07:6005)[(none)]>select @@global.have_dynamic_loading;
    +-------------------------------+
    | @@global.have_dynamic_loading |
    +-------------------------------+
    | YES                           |
    +-------------------------------+
    1 row in set (0.00 sec)
    

      

    1.MySQL安装插件

    安装方式有2种:

    1、在mysql客户端里安装

    2、在配置文件中配置好永久生效

    1、MySQL中INSTALL PLUGIN语法:

    Syntax:
    INSTALL PLUGIN plugin_name SONAME 'shared_library_name'
    
    This statement installs a server plugin. It requires the INSERT
    privilege for the mysql.plugin system table.
    
    UNINSTALL PLUGIN plugin_name
    

      

    主库安装插件:

    INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

    从库安装插件

    INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
    

      

    2、在配置文件中配置

    [mysqld]
    plugin-load='plugin_name=shared_library_name'
    

     在配置文件中加载semisync_master.so插件

    [mysqld]
    plugin-load="rpl_semi_sync_master=sermisync_master.so"
    

     如果需要加载多个插件,使用分号分割,考虑到以后高可用切换,最好把插件都配置上

    [mysqld]
    plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_sync_slave=semisync_slave.so"
    

      

    2.验证插件是否安装成功

    方法一:

    (admin@g1-db-test:6005)[(none)]>show plugins;
    | rpl_semi_sync_master       | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |
    

      

    方法二:

    或者查看information_schema.plugins表获取更详细的信息

    (admin@g1-db-test:6005)[(none)]>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.01 sec)
    

      

    3.启动半同步复制

    master:

    set @@global.rpl_semi_sync_master_enabled=1;

    slave

    set @@global.rpl_semi_sync_slave_enabled=1;
    

      也可以配置到配置文件中

    [mysqld]
    rpl_semi_sync_master_enabled=1
    
    [mysqld]
    rpl_semi_sync_slave_enabled=1
    

      

    4.重启线上IO线程

    slave上执行

    STOP SLAVE IO_THREAD;
    Query OK, 0 rows affected (0.26 sec)
    
    START SLAVE IO_THREAD;
    Query OK, 0 rows affected (0.00 sec)
    

      

    5.查看半同步是否开启

    主库

    mysql> show status like 'Rpl_semi_sync_master_status';
    

      

     从库

    show status like 'Rpl_semi_sync_slave_status';
    

      

    6.半同步插件相关变量

    环境变量

    how 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_for_slave_count | 1          |
    | rpl_semi_sync_master_wait_no_slave        | ON         |
    | rpl_semi_sync_master_wait_point           | AFTER_SYNC |
    | rpl_semi_sync_slave_enabled               | ON         |
    | rpl_semi_sync_slave_trace_level           | 32         |
    +-------------------------------------------+------------+
    8 rows in set (0.07 sec)
    

      

    • rpl_semi_sync_master_enabled : master是否开启半同步复制。
    • rpl_semi_sync_master_timeout:当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。
    • rpl_semi_sync_master_trace_level:半同步复制时master的调试级别。
    • rpl_semi_sync_master_wait_for_slave_count :MySQL 5.7.3引入的,该变量设置主需要等待多少个slave应答,才能返回给客户端,默认为1
    • rpl_semi_sync_master_wait_no_slave:值为ON(默认)或者OFF。ON表示master在超时时间内如果未收到指定数量的ack消息,则会一直等待下去直到收满ack,即一直采用半同步复制方式,不会降级;OFF表示如果在超时时间内未收到指定数量的ack,则超时时间一过立即降级为异步复制。

      ON:默认值,当状态变量Rpl_semi_sync_master_clients中的值小于rpl_semi_sync_master_wait_for_slave_count时,Rpl_semi_sync_master_status依旧显示为ON。

      OFF:当状态变量Rpl_semi_sync_master_clients中的值于rpl_semi_sync_master_wait_for_slave_count时,Rpl_semi_sync_master_status立即显示为OFF,即异步复制。说得直白一点,如果我的架构是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,则会立刻变成异步复制。

    • rpl_semi_sync_master_wait_point:控制master上commit、接收ack、返回消息给客户端的时间点。值为 AFTER_SYNC 和 AFTER_COMMIT ,该选项是MySQL5.7.2后引入的,默认值为 AFTER_SYNC ,在此版本之前,等价于使用了 AFTER_COMMIT 模式。关于这两种模式,见前文对两种半同步类型的分析。
    • rpl_semi_sync_slave_enabled :slave是否开启半同步复制。
    • rpl_semi_sync_slave_trace_level :slave的调试级别。

    状态变量

    how global status like '%semi%';
    +--------------------------------------------+-------+
    | 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                | OFF   |
    | 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                 | ON    |
    +--------------------------------------------+-------+
    

    1、master相关变量

    Rpl_semi_sync_master_clients:(状态变量)master所拥有的半同步复制slave的主机数量。

    Rpl_semi_sync_master_net_avg_wait_time:

    Rpl_semi_sync_master_net_wait_time:

    Rpl_semi_sync_master_net_waits:

    Rpl_semi_sync_master_no_times:

    Rpl_semi_sync_master_no_tx

    Rpl_semi_sync_master_status:(状态变量)master当前是否以半同步复制状态工作(ON),OFF表示降级为了异步复制。

  • 相关阅读:
    WebView Android 调用js且须要获取返回结果
    推荐系统--揭开推荐的神奇面纱
    回调函数
    对CAB文件进行数字签名
    adodb.RecordSet的属性和方法
    Code Review中的几个提示
    Linux下find命令具体解释
    html5中关于input使用方法的改变
    关于 ioctl 的 FIONREAD 參数
    Grant的时候报错的解决:Access denied for user 'root'@'localhost' (using password: YES)
  • 原文地址:https://www.cnblogs.com/asea123/p/12331710.html
Copyright © 2011-2022 走看看