MySQL半同步复制
从MySQL5.5开始,MySQL以插件的形式支持半同步复制。如何理解半同步呢?首先我们来看看异步,全同步的概念
 
异步复制(Asynchronous replication)
MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。
 
全同步复制(Fully synchronous replication)
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。
 
半同步复制(Semisynchronous replication)
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
 
下面来看看半同步复制的原理图:

半同步复制的潜在问题
客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了,此时,可能的情况有两种
 
事务还没发送到从库上
此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。
 
事务已经发送到从库上
此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。
 
无数据丢失的半同步复制
针对上述潜在问题,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
老的半同步方案,如图所示。
 
半同步复制的安装部署
要想使用半同步复制,必须满足以下几个条件:

  1. MySQL 5.5及以上版本
  2. 变量have_dynamic_loading为YES
  3. 异步复制已经存在
     
    首先加载插件
    因用户需执行INSTALL PLUGIN, SET GLOBAL, STOP SLAVE和START SLAVE操作,所以用户需有SUPER权限。
    主:
    mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
    从:
    mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
     
    查看插件是否加载成功
    有两种方式
    1. 
    mysql> show plugins;
    rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL
    2. 
    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> SET GLOBAL rpl_semi_sync_master_enabled = 1;
    从:
    mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
     
    以上的启动方式是在命令行操作,也可写在配置文件中。
    主:
    plugin-load=rpl_semi_sync_master=semisync_master.so
    rpl_semi_sync_master_enabled=1
    从:
    plugin-load=rpl_semi_sync_slave=semisync_slave.so
    rpl_semi_sync_slave_enabled=1
    在有的高可用架构下,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
     
    重启从上的IO线程
    mysql> STOP SLAVE IO_THREAD;
    mysql> START SLAVE IO_THREAD;
    如果没有重启,则默认还是异步复制,重启后,slave会在master上注册为半同步复制的slave角色。
    这时候,主的error.log中会打印如下信息:
    2016-08-05T10:03:40.104327Z 5 [Note] While initializing dump thread for slave with UUID , found a zombie dump thread with the same UUID. Master is killing the zombie dump thread(4).2016-08-05T10:03:40.111175Z 4 [Note] Stop asynchronous binlog_dump to slave (server_id: 2)2016-08-05T10:03:40.119037Z 5 [Note] Start binlog_dump to master_thread_id(5) slave_server(2), pos(mysql-bin.000003, 621)2016-08-05T10:03:40.119099Z 5 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000003, 621)
     
    查看半同步是否在运行
    主:
    mysql> show status like 'Rpl_semi_sync_master_status';
    +-----------------------------+-------+
    | Variable_name | Value |
    +-----------------------------+-------+
    |Rpl_semi_sync_master_status | ON |
    +-----------------------------+-------+
    1 row in set (0.00 sec)
    从:
    mysql> show status like 'Rpl_semi_sync_slave_status';
    +----------------------------+-------+
    | Variable_name | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | ON |
    +----------------------------+-------+
    1 row in set (0.20 sec)
    这两个变量常用来监控主从是否运行在半同步复制模式下。
    至此,MySQL半同步复制搭建完毕~
     
    事实上,半同步复制并不是严格意义上的半同步复制
    当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。
     
    下面来测试一下

 
该验证分为三个阶段
 

  1. 在Slave执行stop slave之前,主的insert操作很快就能返回。
  2. 在Slave执行stop slave后,主的insert操作需要10.01s才返回,而这与rpl_semi_sync_master_timeout参数的时间相吻合。
    这时,查看两个状态的值,均为“OFF”了。
    同时,主的error.log中打印如下信息:
    2016-08-05T11:51:49.855452Z 6 [Warning] Timeout waiting for reply of binlog (file: mysql-bin.000003, pos: 1447), semi-sync up to file mysql-bin.000003, position 1196.2016-08-05T11:51:49.855742Z 6 [Note] Semi-sync replication switched OFF.
     
  3. 在Slave执行start slave后,主的insert操作很快就能返回,此时,两个状态的值也变为“ON”了。
    同时,主的error.log中会打印如下信息:
    2016-08-05T11:52:40.477098Z 7 [Note] Start binlog_dump to master_thread_id(7) slave_server(2), pos(mysql-bin.000003, 1196)2016-08-05T11:52:40.477168Z 7 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000003, 1196)2016-08-05T11:52:40.523475Z 0 [Note] Semi-sync replication switched ON at (mysql-bin.000003, 1447)
     
    其它变量
    环境变量
    mysql> show variables like '%Rpl%';
    +-------------------------------------------+------------+
    | Variable_name | Value |
    +-------------------------------------------+------------+
    | rpl_semi_sync_master_enabled | ON |
    | 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_stop_slave_timeout | 31536000 |
    +-------------------------------------------+------------+
    7 rows in set (0.30 sec)
     
    rpl_semi_sync_master_wait_for_slave_count
    MySQL 5.7.3引入的,该变量设置主需要等待多少个slave应答,才能返回给客户端,默认为1。
     
    rpl_semi_sync_master_wait_no_slave
    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,则会立刻变成异步复制。
     
    状态变量
    mysql> show status like '%Rpl_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 | 6 |
    | Rpl_semi_sync_master_no_times | 1 |
    | Rpl_semi_sync_master_no_tx | 1 |
    | Rpl_semi_sync_master_status | ON |
    | Rpl_semi_sync_master_timefunc_failures | 0 |
    |Rpl_semi_sync_master_tx_avg_wait_time | 1120 |
    | Rpl_semi_sync_master_tx_wait_time | 4483 |
    | Rpl_semi_sync_master_tx_waits | 4 |
    | Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
    | Rpl_semi_sync_master_wait_sessions | 0 |
    | Rpl_semi_sync_master_yes_tx | 4 |
    +--------------------------------------------+-------+
    14 rows in set (0.00 sec)
     
    上述状态变量中,比较重要的有以下几个
     
    Rpl_semi_sync_master_clients
    当前半同步复制从的个数,如果是一主多从的架构,并不包含异步复制从的个数。
     
    Rpl_semi_sync_master_no_tx
    The number of commits that were not acknowledged successfully by a slave.
    具体到上面的测试中,指的是insert into test.test values(2)这个事务。
     
    Rpl_semi_sync_master_yes_tx
    The number of commits that were acknowledged successfully by a slave.
    具体到上面的测试中,指的是以下四个事务
    create database test;
    create table test.test(id int);
    insert into test.test values(1);
    insert into test.test values(3);
     
    总结
    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的反馈。

转mysql半主从同步的更多相关文章

  1. MySQL数据库主从同步延迟分析及解决方案

    一.MySQL的数据库主从复制原理 MySQL主从复制实际上基于二进制日志,原理可以用一张图来表示: 分为四步走: 1. 主库对所有DDL和DML产生的日志写进binlog: 2. 主库生成一个 lo ...

  2. mysql数据库主从同步

    环境: Mater:   CentOS7.1  5.5.52-MariaDB  192.168.108.133 Slave:   CentOS7.1  5.5.52-MariaDB  192.168. ...

  3. 【转】MySQL数据库主从同步管理

    MYSQL主从同步架构是目前使用最多的数据库架构之一,尤其是负载比较大的网站,因此对于主从同步的管理也就显得非常重要,新手往往在出现主从同步错误的时候不知道如何入手,这篇文章就是根据自己的经验来详细叙 ...

  4. MySQL数据库主从同步安装与配置总结

    MySQL的主从同步是一个很成熟的架构,优点为: ①在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力: ②在从主服务器进行备份,避免备份期间影响主服务器服务: ③当主服务器出现问题时 ...

  5. MYSQL配置主从同步

    MYSQL配置主从同步 mysql主服务器配置 vim /etc/my.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql. ...

  6. mysql数据库主从同步读写分离(一)主从同步

    1.mysql数据库主从同步读写分离 1.1.主要解决的生产问题 1.2.原理 a.为什么需要读写分离? 一台服务器满足不了访问需要.数据的访问基本都是2-8原则. b.怎么做?  不往从服务器去写了 ...

  7. mysql 之 主从同步(单向同步和双向同步)

    一. 实验环境部署 主服务器(MySQL-01) IP: 192.168.8.241  端口3306  ,操作系统:Centos6.5 64位 从服务器(MySQL-02)  IP: 192.168. ...

  8. Mysql Replication 主从同步

    简介: Mysql 的主从同步功能,这种解决方案是企业很常见的一种.常用于备份数据库,当客户端操作主库时,主库会产生binlog日志文件, 从库通过复制主库的binlog日志文件,然后解析成相应的 S ...

  9. Linux下MySQL数据库主从同步配置

    说明: 操作系统:CentOS 5.x 64位 MySQL数据库版本:mysql-5.5.35 MySQL主服务器:192.168.21.128 MySQL从服务器:192.168.21.129 准备 ...

随机推荐

  1. 20135234mqy-——信息安全系统设计基础第十周学习总结

    ls1:显示当前目录下的文件. ls2:查看文件的详细信息(用户名,群组名,大小,创建时间,读写权限等). who:读取需要的信息到存储器,并用标准输出函数打印到屏幕上 filesize:计算文件的字 ...

  2. java在访问https资源时的证书信任问题

    java程序在访问https资源时,出现报错 sun.security.validator.ValidatorException: PKIX path building failed: sun.sec ...

  3. Is it bad to rely on foreign key cascading? 外键 级联操作

    Is it bad to rely on foreign key cascading? I'll preface前言 this by saying that I rarely delete rows ...

  4. [BZOJ3613][Heoi2014]南园满地堆轻絮 二分答案

    Description 小 Z 是 ZRP(Zombies’ Republic of Poetry,僵尸诗歌共和国)的一名诗歌爱好者,最近 他研究起了诗词音律的问题.   在过去,诗词是需要编成曲子唱 ...

  5. vuejs全局api概念

    什么是全局API? 全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,比如我们今天要学习的指令Vue.directive.说的简单些就是,在构造 ...

  6. Unity3D学习笔记(一):Unity3D简介

    Unity3D简介一.什么是Unity.U3D?全面整合的专业引擎 二.这个软件能做什么?1.内容:3D2D游戏,教育,建筑,网页,VRAR,家庭娱乐系统2.媒体:PC平台,主机,移动,VR 1.UE ...

  7. MySQL数据库调优技巧

    原文链接:https://m.aliyun.com/bbs/read/300762.html MySQL是一个功能强大的开源数据库.随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它 ...

  8. linux设置端口转发(一键设置)

    linux设置端口转发 #下载rinetd程序并进入文件夹 wget http://www.boutell.com/rinetd/http/rinetd.tar.gz&&tar -xv ...

  9. shell printf

    printf 可以格式化字符串,还可以制定字符串的宽度.左右对齐方式等.默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n. 例子: $ echo "Hello, ...

  10. Linux 之 ./configure --prefix 命令

    参考 http://blog.sina.com.cn/s/blog_406127500101dsmy.html 源码的安装一般由3个步骤组成:配置(configure).编译(make).安装(mak ...