Mysql之半同步复制

1.  什么是半同步复制

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

2.  半同步复制特性

    1.  半同步复制必须在主库和从库两端都开启时才行,如果在主库上没打开,或者主库开启了,而在从库没有开启,主库都会使用异步方式复制。

    2.  从库会在连接到主库时告诉主库,它是不是配置了半同步。

    3.  如果半同步复制在主库端是开启了的,并且至少有一个半同步复制的从库节点,那么此时主库的事务线程在提交时会被阻塞并等待,结果有两种可能,要么至少一个从库节点通知它已经收到了所有这个事务的Binlog事件,要么一直等待直到超过配置的某一个时间点为止,而此时,半同步复制将自动关闭,转换为异步复制。

    4.  从库节点只有在接收到某一个事务的所有Binlog,将其写入并Flush到Relay Log文件之后,才会通知对应主库上面的等待线程。

    5.  如果在等待过程中,等待时间已经超过了配置的超时时间,没有任何一个从节点通知当前事务,那么此时主库会自动转换为异步复制,当至少一个半同步从节点赶上来时,主库便会自动转换为半同步方式的复制。

3.  半同步复制优缺点

    1.  优点

        1.  保证数据不丢失

            主库产生binlog到主库的binlog file,传到从库中继日志,然后从库应用;也就是说传输是异步的,应用也是异步的。半同步复制指的是传输同步,应用还是异步的!                    

    2.  缺点

        1.  不能保证应用同步

4.  安装部署半同步复制

    1.  准备条件

        1.  Mysql5.5以上版本

        2.  变量have_dynamic_loading为YES (查看命令:show variables like "have_dynamic_loading";)

        3.  主从复制已经存在 (即提前部署mysql主从复制环境,主从同步要配置基于整个数据库的,不要配置基于某个库的同步,即同步时不要过滤库)

    2.  加载插件

        半同步复制是一个功能模块,库要能支持动态加载才能实现半同步复制(模块存放路径:安装目录下的lib/plugin)

        1.  命令行加载与卸载

            1.  加载

                主库加载:  INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

                从库加载:  INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

            2.  卸载

                主库卸载:  UNINSTALL PLUGIN rpl_semi_sync_master;  

                从库卸载:  UNINSTALL PLUGIN rpl_semi_sync_slave; 

            3.  检验加载是否成功:

                show plugins;

                  rpl_semi_sync_master     |  ACTIVE  |  REPLICATION

                SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';

            4.  启动半同步复制

                主库:  SET GLOBAL rpl_semi_sync_master_enabled = 1;  

                从库:  SET GLOBAL rpl_semi_sync_slave_enabled = 1;                             

        2.  配置文件加载 

            1.  my.cnf配置文件添加

                主库

                  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
                如果即是主又是从
                  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
    3.  加载完成后,重启从数据库的IO线程
        STOP SLAVE IO_THREAD;
        START SLAVE IO_THREAD;
        如果不重启IO线程,还是使用的是异步模式
    4.  查看半同步是否在运行
        主库:  show status like 'Rpl_semi_sync_master_status';  
        从库:  show status like 'Rpl_semi_sync_slave_status';
    5.  超时限制
        show variables like "rpl_semi_sync_master_timeout";  单位是毫秒
        当半同步复制发生超时,超过10s,会暂时关闭半同步复制,使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。

5.  删除半同步复制,恢复异步复制

    1.  先处理从库
        1.  从库关闭半同步复制功能,然后卸载半同步插件
            stop slave;
            SET GLOBAL rpl_semi_sync_slave_enabled = 0;
            show status like 'Rpl_semi_sync_slave_status';
            UNINSTALL PLUGIN rpl_semi_sync_slave;
             show status like 'Rpl_semi_sync_slave_status';
            SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';            
        2.  删除my.cnf配置
            #plugin-load=rpl_semi_sync_slave=semisync_slave.so
            #rpl_semi_sync_slave_enabled=ON
        3.  重启mysql服务
    2.  处理主库
        1.  主库关闭半同步复制功能,然后卸载半同步模块
            SET GLOBAL rpl_semi_sync_master_enabled = 0;  
            UNINSTALL PLUGIN rpl_semi_sync_master; 
        2.  删除my.cnf配置
            #plugin-load=rpl_semi_sync_master=semisync_master.so
            #rpl_semi_sync_master_enabled=ON
            #rpl-semi-sync-master-timeout=1000
        3.  重启mysql服务
    3.  重启从数据库的IO线程
        STOP SLAVE IO_THREAD;
        START SLAVE IO_THREAD;

6.  Mysql5.7半同步复制改进                              

    1.  支持无损复制

        无损复制其实就是对semi sync增加了rpl_semi_sync_master_wait_point参数,来控制半同步模式下主库在返回给会话事务成功之前提交事务的方式。rpl_semi_sync_master_wait_point该参数有两个值:AFTER_COMMIT和AFTER_SYNC

        1.  AFTER_COMMIT  5.6默认值

            master将每个事务写入binlog(sync_binlog=1),传递到slave刷新到磁盘(sync_relay=1),同时主库提交事务。master等待slave反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。

        2.  AFTER_SYNC  5.7默认值

            master将每个事务写入binlog , 传递到slave刷新到磁盘(relay log)。master等待slave反馈接收到relay log的ack之后,再提交事务并且返回commit OK结果给客户端。 即使主库crash,所有在主库上已经提交的事务都能保证已经同步到slave的relay log中。                  

    2.  半同步复制与无损复制的对比

        1) ACK的时间点不同
          半同步复制在InnoDB层的Commit Log后等待ACK,主从切换会有数据丢失风险。
          无损复制在MySQL Server层的Write binlog后等待ACK,主从切换会有数据变多风险。
        2) 主从数据一致性
          半同步复制意味着在Master节点上,这个刚刚提交的事物对数据库的修改,对其他事物是可见的。因此,如果在等待Slave ACK的时候crash了,那么会对其他事务出现幻读,数据丢失。
          无损复制在write binlog完成后就传输binlog,但还没有去写commit log,意味着当前这个事物对数据库的修改,其他事物也是不可见的。因此,不会出现幻读,数据丢失风险。

                

               

posted @ 2022-10-10 10:24  奋斗史  阅读(409)  评论(0)    收藏  举报