zoukankan      html  css  js  c++  java
  • sql执行效率,半同步复制

    简述项目中优化sql语句执行效率的方法,从哪些方面,sql语句性能如何分析?

    (1)尽量选择较小的列;

    (2)将where中用的比较频繁的字段建立索引;

    (3)select中避免使用*;

    (4)避免在索引列上使用计算、not in和<>等操作;

    (5)当只需要一行数据时候使用limit1;

    (6)保证单表数据不超过200w,实时分割表;

    针对查询较慢的语句,可以使用explain来分析该语句具体的执行情况。

    sql语句应考虑哪些安全性?

    (1)少使用root账户,应该为不同的动作分配不同的账户;
    (2)sql执行出错后,不能把数据库中显示的出错信息,直接展示给用户。防止泄露服务器和数据库相关信息;
    (3)防止sql注入,对特殊字符进行转义、过滤或者使用预编译的sql语句绑定变量

    接下来重点说下Mysql半同步复制,从MySQL5.5开始,MySQL以插件的形式支持半同步复制。先来区别下mysql几个同步模式概念:

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

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

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

    -  对于异步复制,主库将事务Binlog事件写入到Binlog文件中,此时主库只会通知一下Dump线程发送这些新的Binlog,然后主库就会继续处理提交操作,而此时不会保证这些Binlog传到任何一个从库节点上。

    -  对于全同步复制,当主库提交事务之后,所有的从库节点必须收到,APPLY并且提交这些事务,然后主库线程才能继续做后续操作。这里面有一个很明显的缺点就是,主库完成一个事务的时间被拉长,性能降低。

    -  对于半同步复制,是介于全同步复制和异步复制之间的一种,主库只需要等待至少一个从库节点收到并且Flush Binlog到Relay Log文件即可,主库不需要等待所有从库给主库反馈。同时,这里只是一个收到的反馈,而不是已经完全执行并且提交的反馈,这样就节省了很多时间。

                                                            Mysql半同步复制技术                                                                
    一般而言,普通的replication,即MySQL的异步复制,依靠MySQL二进制日志也即binary log进行数据复制。比如两台机器,一台主机(master),另外一台是从机(slave)。
    正常的复制为:事务一(t1)写入binlog buffer;dumper线程通知slave有新的事务t1;binlog buffer进行checkpoint;slave的io线程接收到t1并写入到自己的的relay log;slave的sql线程写入到本地数据库。 这时,master和slave都能看到这条新的事务,即使master挂了,slave可以提升为新的master。
    异常的复制为:事务一(t1)写入binlog buffer;dumper线程通知slave有新的事务t1;binlog buffer进行checkpoint;slave因为网络不稳定,一直没有收到t1;master挂掉,slave提升为新的master,t1丢失。
    很大的问题是:主机和从机事务更新的不同步,就算是没有网络或者其他系统的异常,当业务并发上来时,slave因为要顺序执行master批量事务,导致很大的延迟。

    为了弥补以上几种场景的不足,MySQL从5.5开始推出了半同步复制。相比异步复制,半同步复制提高了数据完整性,因为很明确知道,在一个事务提交成功之后,这个事务就至少会存在于两个地方。即在master的dumper线程通知slave后,增加了一个ack(消息确认),即是否成功收到t1的标志码,也就是dumper线程除了发送t1到slave,还承担了接收slave的ack工作。如果出现异常,没有收到ack,那么将自动降级为普通的复制,直到异常修复后又会自动变为半同步复制。 

    半同步复制具体特性
    -  从库会在连接到主库时告诉主库,它是不是配置了半同步。
    -  如果半同步复制在主库端是开启了的,并且至少有一个半同步复制的从库节点,那么此时主库的事务线程在提交时会被阻塞并等待,结果有两种可能,要么至少一个从库节点通知它已经收到了所有这个事务的Binlog事件,要么一直等待直到超过配置的某一个时间点为止,而此时,半同步复制将自动关闭,转换为异步复制。
    -  从库节点只有在接收到某一个事务的所有Binlog,将其写入并Flush到Relay Log文件之后,才会通知对应主库上面的等待线程。
    -  如果在等待过程中,等待时间已经超过了配置的超时时间,没有任何一个从节点通知当前事务,那么此时主库会自动转换为异步复制,当至少一个半同步从节点赶上来时,主库便会自动转换为半同步方式的复制。
    -  半同步复制必须是在主库和从库两端都开启时才行,如果在主库上没打开,或者在主库上开启了而在从库上没有开启,主库都会使用异步方式复制。

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

    半同步复制的意思表示MASTER 只需要接收到其中一台SLAVE的返回信息,就会commit;否则需等待直至达到超时时间然后切换成异步再提交。这个做可以使主从库的数据的延迟较小,可以在损失很小的性能的前提下提高数据的安全性。

    主库产生binlog到主库的binlog file,传到从库中继日志,然后从库应用;也就是说传输是异步的,应用也是异步的。半同步复制指的是传输同步,应用还是异步的!
    好处:保证数据不丢失(本机和远端都有binlog)
    坏处:不能保证应用的同步。

    mysql半同步复制模式的流程图

    即主库忽然崩了时,从库虽然说有延迟,但是延迟过后,可以把从库提升为主库继续服务,事后恢复到主库即可

    mysql异步复制模式的流程图

    半同步复制的潜在问题
    客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了,此时,可能的情况有两种
    -  事务还没发送到从库上
    此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主上,当宕机的主库重新启动后,以从库的身份重新加入到该主从结构中,会发现,该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主同步过来的。
    -  事务已经发送到从库上
    此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主上。

    无数据丢失的半同步复制
    针对上述潜在问题,MySQL 5.7引入了一种新的半同步方案:Loss-Less半同步复制。针对上面这个图,"Waiting Slave dump"被调整到"Storage Commit"之前。当然,之前的半同步方案同样支持,MySQL 5.7.2引入了一个新的参数进行控制: rpl_semi_sync_master_wait_point, 这个参数有两种取值:1) AFTER_SYNC , 这个是新的半同步方案,Waiting Slave dump在Storage Commit之前。2) AFTER_COMMIT, 这个是老的半同步方案。

    来看下面半同步复制原理图,分析下半同步复制潜在问题

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

    在MySQL 5.5-5.6使用after_commit的模式下,客户端事务在存储引擎层提交后,在得到从库确认的过程中,主库宕机了。此时,即主库在等待Slave ACK的时候,虽然没有返回当前客户端,但事务已经提交,其他客户端会读取到已提交事务。如果Slave端还没有读到该事务的events,同时主库发生了crash,然后切换到备库。那么之前读到的事务就不见了,出现了幻读。

    如果主库永远启动不了,那么实际上在主库已经成功提交的事务,在从库上是找不到的,也就是数据丢失了,这是MySQL不愿意看到的。所以在MySQL 5.7版本中增加了after_sync(无损复制)参数,并将其设置为默认半同步方式,解决了数据丢失的问题。

    半同步复制的安装部署条件
    要想使用半同步复制,必须满足以下几个条件:
    1)MySQL 5.5及以上版本
    2)变量have_dynamic_loading为YES (查看命令:show variables like "have_dynamic_loading";)
    3)主从复制已经存在 (即提前部署mysql主从复制环境,主从同步要配置基于整个数据库的,不要配置基于某个库的同步,即同步时不要过滤库)

    -  首先加载插件
    因用户需执行INSTALL PLUGIN, SET GLOBAL, STOP SLAVE和START SLAVE操作,所以用户需有SUPER权限。

    半同步复制是一个功能模块,库要能支持动态加载才能实现半同步复制! (安装的模块存放路径为/usr/local/mysql/lib/plugin)
    主数据库执行:

    1
    2
    3
    4
    5
    6
    mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
     
    [要保证/usr/local/mysql/lib/plugin/目录下有semisync_master.so文件 (默认编译安装后就有)]
    ---------------------------------------------------------------------------------------
    如果要卸载(前提是要关闭半同步复制功能),就执行
    mysql> UNINSTALL PLUGIN rpl_semi_sync_master;

    从数据库执行:

    1
    2
    3
    4
    5
    6
    mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
     
    [要保证/usr/local/mysql/lib/plugin/目录下有semisync_slave.so文件 (默认编译安装后就有)]
    ---------------------------------------------------------------------------------------
    如果要卸载(前提是要关闭半同步复制功能),就执行
    mysql> UNINSTALL PLUGIN rpl_semi_sync_slave;

    -  查看插件是否加载成功的两种方式:
    1) 方式一

    1
    2
    3
    mysql> show plugins;
    ........
    | rpl_semi_sync_master       | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |

    2) 方式二

    1
    2
    3
    4
    5
    6
    7
    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)

    -  启动半同步复制
    在安装完插件后,半同步复制默认是关闭的,这时需设置参数来开启半同步
    主数据库执行:

    1
    mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;

    从数据库执行:

    1
    mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;

    以上的启动方式是在登录mysql后的命令行操作,也可写在my.cnf配置文件中(推荐这种启动方式)。
    主数据库的my.cnf配置文件中添加:

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

    从数据库的my.cnf配置文件中添加:

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

    在个别高可用架构下,master和slave需同时启动,以便在切换后能继续使用半同步复制!即在主从数据库的my.cnf配置文件中都要添加:

    1
    2
    3
    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线程

    1
    2
    mysql> STOP SLAVE IO_THREAD;
    mysql> START SLAVE IO_THREAD;

    特别注意: 如果没有重启,则默认的还是异步复制模式!,重启后,slave会在master上注册为半同步复制的slave角色。这时候,主的error.log中会打印如下信息:

    1
    2
    3
    4
    2019-01-05T10:03:40.104327Z 5 [Note] While initializing dump thread for slave with UUID <ce9aaf22-5af6-11e6-850b-000c2988bad2>, found a zombie dump thread with the same UUID. Master is killing the zombie dump thread(4).
    2019-01-05T10:03:40.111175Z 4 [Note] Stop asynchronous binlog_dump to slave (server_id: 2)
    2019-01-05T10:03:40.119037Z 5 [Note] Start binlog_dump to master_thread_id(5) slave_server(2), pos(mysql-bin.000003, 621)
    2019-01-05T10:03:40.119099Z 5 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000003, 621)

    -  查看半同步是否在运行
    主数据库:

    1
    2
    3
    4
    5
    6
    7
    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)

    从数据库:

    1
    2
    3
    4
    5
    6
    7
    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半同步复制环境就部署完成了!

                                                                                                                                                                          

    需要注意下,其实Mysql半同步复制并不是严格意义上的半同步复制。当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。[一旦有一次超时自动降级为异步].

    1
    2
    3
    4
    5
    6
    7
    mysql> show variables like "rpl_semi_sync_master_timeout";
    +------------------------------+-------+
    | Variable_name                | Value |
    +------------------------------+-------+
    | rpl_semi_sync_master_timeout | 10000 |
    +------------------------------+-------+
    1 row in set (0.01 sec)

     接下来可以测试下:

    1) 主数据库 (从数据库在执行"stop slave"之前)

    1
    2
    3
    4
    5
    6
    7
    8
    mysql> create database bobo;
    Query OK, 1 row affected (0.05 sec)
     
    mysql> create table bobo.ceshi(id int);
    Query OK, 0 row affected (0.28 sec)
     
    mysql> insert into bobo.ceshi values(1);
    Query OK, 1 row affected (0.09 sec)

    2) 从数据执行"stop slave"

    1
    mysql> stop slave;

    再观察主数据库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    mysql> insert into bobo.ceshi values(2);
    Query OK, 1 row affected (10.01 sec)
     
    mysql> show status like 'Rpl_semi_sync_master_status';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | Rpl_semi_sync_master_status | OFF   |
    +-----------------------------+-------+
    1 row in set (0.00 sec)

    查看从数据库

    1
    2
    3
    4
    5
    6
    7
    mysql> show status like 'Rpl_semi_sync_slave_status';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | Rpl_semi_sync_slave_status  | OFF   |
    +-----------------------------+-------+
    1 row in set (0.01 sec)

    3) 接着再在从数据库执行"start slave"

    1
    mysql> start slave;

    再观察主数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    mysql> insert into bobo.ceshi values(3);
    Query OK, 1 row affected (0.00 sec)
     
    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)

    查看从数据库

    1
    2
    3
    4
    5
    6
    7
    mysql> show status like 'Rpl_semi_sync_slave_status';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | Rpl_semi_sync_slave_status  | ON   |
    +-----------------------------+-------+
    1 row in set (0.00 sec)

    以上验证分为三个阶段:
    1) 在Slave执行stop slave之前,主的insert操作很快就能返回。
    2) 在Slave执行stop slave后,主的insert操作需要10.01s才返回,而这与rpl_semi_sync_master_timeout参数的时间相吻合。这时,查看两个状态的值,均为“OFF”了。同时,主的error.log中打印如下信息:

    1
    2
    2019-01-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.
    2019-01-05T11:51:49.855742Z 6 [Note] Semi-sync replication switched OFF.

    3) 在Slave执行start slave后,主的insert操作很快就能返回,此时,两个状态的值也变为“ON”了。同时,主的error.log中会打印如下信息:

    1
    2
    3
    2019-01-05T11:52:40.477098Z 7 [Note] Start binlog_dump to master_thread_id(7) slave_server(2), pos(mysql-bin.000003, 1196)
    2019-01-05T11:52:40.477168Z 7 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000003, 1196)
    2019-01-05T11:52:40.523475Z 0 [Note] Semi-sync replication switched ON at (mysql-bin.000003, 1447)

                                                     其他变量说明                                                  

    环境变量(show variables like '%Rpl%';)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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,即异步复制。

    简单来说,如果mysql架构是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,则会立刻变成异步复制。

    状态变量(show status like '%Rpl_semi%';)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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 bobo.ceshi values(2)这个事务。

    Rpl_semi_sync_master_yes_tx
    The number of commits that were acknowledged successfully by a slave.
    具体到上面的测试中,指的是以下四个事务:
    mysql> create database bobo;
    mysql> create table bobo.ceshi(id int);
    mysql> insert into bobo.ceshi values(1);
    mysql> insert into bobo.ceshi 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
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    mysql主数据库: 172.16.60.205
    mysql从数据库: 172.16.60.206
    mysql5.6.39 安装部署,参考:https://www.cnblogs.com/kevingrace/p/6109679.html
     
    主数据库172.16.60.205配置:
    [root@mysql-master ~]# cat /usr/local/mysql/my.cnf
    .......
    server-id=1
    log-bin=mysql-bin
    sync_binlog = 1
    binlog_checksum = none
    binlog_format = mixed
     
    从数据库172.16.60.206配置:
    [root@mysql-slave ~]# cat /usr/local/mysql/my.cnf
    .........
    server-id=2
    log-bin=mysql-bin
    slave-skip-errors = all
     
    然后从库同步操作,不需要跟master_log_file 和 master_log_pos=120
    mysql> change master to master_host = '172.16.60.205', master_port = 3306, master_user ='slave', master_password ='slave@123';
     
    其他的配置,参考https://www.cnblogs.com/kevingrace/p/6256603.html
    即主从同步配置不过滤库,是基于整个数据库的同步。其他的操作和这个文档中记录的差不多
     
    ========================================================
    主数据库
    [root@mysql-master ~]# mysql -p123456
    ......
    mysql> use kevin;
    mysql> show tables;
    +-----------------+
    | Tables_in_kevin |
    +-----------------+
    | haha            |
    +-----------------+
    1 row in set (0.00 sec)
       
    mysql> select * from haha;
    +----+--------+
    id | name   |
    +----+--------+
    |  2 | anxun  |
    |  3 | huoqiu |
    |  4 | xihuju |
    +----+--------+
    3 rows in set (0.00 sec)
       
    从数据库:
    [root@mysql-slave ~]# mysql -p123456
    ..........
    ..........
    mysql> show slave status G;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 172.16.60.205
                      Master_User: slave
                      Master_Port: 3306
                    Connect_Retry: 60
    .........
    .........
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
       
    mysql> select * from kevin.haha;
    +----+--------+
    id | name   |
    +----+--------+
    |  2 | anxun  |
    |  3 | huoqiu |
    |  4 | xihuju |
    +----+--------+
    3 rows in set (0.00 sec)
       
    主数据库插入数据
    mysql> insert into haha values(1,"linux");
    Query OK, 1 row affected (0.03 sec)
    mysql> insert into haha values(11,"linux-ops");
    Query OK, 1 row affected (0.04 sec)
       
    从数据库查看
    mysql> select * from kevin.haha;
    +----+-----------+
    id | name      |
    +----+-----------+
    |  1 | linux     |
    |  2 | anxun     |
    |  3 | huoqiu    |
    |  4 | xihuju    |
    | 11 | linux-ops |
    +----+-----------+
    5 rows in set (0.00 sec)
       
    mysql> select version();
    +------------+
    | version()  |
    +------------+
    | 5.6.39-log |
    +------------+
    1 row in set (0.00 sec)
       
    mysql> show variables like "have_dynamic_loading";
    +----------------------+-------+
    | Variable_name        | Value |
    +----------------------+-------+
    | have_dynamic_loading | YES   |
    +----------------------+-------+
    1 row in set (0.00 sec)
       
    从上面可知,已满足mysql半同步复制功能部署的条件:
    1)MySQL 5.5及以上版本!
    2)变量have_dynamic_loading为YES
    3)主从复制已经存在!
       
    ===================================================
    接下来进行mysql半同步复制环境部署:
       
    1)加载mysql半同步复制的插件
    主数据库执行:
    mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
    Query OK, 0 row affected (0.04 sec)
       
    从数据库执行:
    mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
    Query OK, 0 row affected (0.04 sec)
       
    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> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';
    +----------------------+---------------+
    | PLUGIN_NAME          | PLUGIN_STATUS |
    +----------------------+---------------+
    | rpl_semi_sync_slave  | ACTIVE        |
    +----------------------+---------------+
    2 rows in set (0.01 sec)
       
    3) 启动半同步复制
    主数据库执行:
    mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
    Query OK, 0 rows affected (0.00 sec)
       
    从数据库执行:
    mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
    Query OK, 0 rows affected (0.00 sec)
       
    ----------------------------------------------------------------------------------------------------------------------------------------------
    温馨提示:
    除了上面的设置方法以外, 还可以以下面方式启动半同步复制,即在my.cnf文件中添加启动配置(推荐这种方式):
    主数据库
    [root@mysql-master ~]# vim /usr/local/mysql/my.cnf      #在[mysqld]区域添加下面内容
    ........
    plugin-load=rpl_semi_sync_master=semisync_master.so
    rpl_semi_sync_master_enabled=ON         #或者设置为"1",即开启半同步复制功能
    rpl-semi-sync-master-timeout=1000       #超时时间为1000ms,即1s
       
    [root@mysql-master ~]# /etc/init.d/mysqld restart
       
    主数据库
    [root@mysql-slave ~]# vim /usr/local/mysql/my.cnf
    ........
    plugin-load=rpl_semi_sync_slave=semisync_slave.so
    rpl_semi_sync_slave_enabled=ON
       
    [root@mysql-slave ~]# /etc/init.d/mysqld restart
    ----------------------------------------------------------------------------------------------------------------------------------------------
       
    4)查看半同步是否在运行
    主数据库执行:
    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)
       
    从数据库执行(此时可能还是OFF状态,需要在下一步重启IO线程后,从库半同步状态才会为ON):
    mysql> show status like 'Rpl_semi_sync_slave_status';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | ON    |
    +----------------------------+-------+
    1 row in set (0.00 sec)
      
    5)重启从数据库上的IO线程
    mysql> STOP SLAVE IO_THREAD;
    Query OK, 0 rows affected (0.04 sec)
       
    mysql> START SLAVE IO_THREAD;
    Query OK, 0 rows affected (0.00 sec)
       
    重启从数据的IO线程之后,  slave会在master上注册为半同步复制的slave角色
    查看主数据库上的error日志,就会发现下面信息:
    [root@mysql-master ~]# tail -f /data/mysql/data/mysql-error.log
    2019-01-06 23:23:34 10436 [Note] Semi-sync replication initialized for transactions.
    2019-01-06 23:23:34 10436 [Note] Semi-sync replication enabled on the master.
    2019-01-06 23:27:28 10436 [Note] Stop asynchronous binlog_dump to slave (server_id: 2)
    2019-01-06 23:27:28 10436 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000004, 2944)
    2019-01-06 23:32:03 10436 [Note] Stop semi-sync binlog_dump to slave (server_id: 2)
    2019-01-06 23:32:03 10436 [Note] Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000004, 3357)
       
    如上操作,就已经部署了mysql的半同步复制环境
       
    现在往主数据库插入新数据
    mysql> insert into kevin.haha values(5,"grace");
    Query OK, 1 row affected (0.13 sec)
       
    mysql> insert into kevin.haha values(6,"huihui");
    Query OK, 1 row affected (0.11 sec)
       
    到从数据库上查看,正常复制过来了
       
    mysql> show slave status G;
    .........
    .........
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
       
    mysql> select * from kevin.haha;
    +----+-----------+
    id | name      |
    +----+-----------+
    |  1 | linux     |
    |  2 | anxun     |
    |  3 | huoqiu    |
    |  4 | xihuju    |
    |  5 | grace     |
    |  6 | huihui    |
    | 11 | linux-ops |
    +----+-----------+
    7 rows in set (0.00 sec)
       
    查看主数据库
    mysql> show status like '%Rpl_semi%';
    +--------------------------------------------+-------+
    | Variable_name                              | Value |
    +--------------------------------------------+-------+
    | Rpl_semi_sync_master_clients               | 1     |
    | Rpl_semi_sync_master_net_avg_wait_time     | 475   |               #网络等待的平均时间
    | Rpl_semi_sync_master_net_wait_time         | 1427  |               #网络等待时间   
    | Rpl_semi_sync_master_net_waits             | 3     |
    | Rpl_semi_sync_master_no_times              | 0     |
    | Rpl_semi_sync_master_no_tx                 | 0     |               #大于0就是异步。半同步是应为0 
    | Rpl_semi_sync_master_status                | ON    |
    | Rpl_semi_sync_master_timefunc_failures     | 0     |
    | Rpl_semi_sync_master_tx_avg_wait_time      | 622   |               # 平均等待时间
    | Rpl_semi_sync_master_tx_wait_time          | 1868  |               #总的等待时间
    | Rpl_semi_sync_master_tx_waits              | 3     |
    | Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
    | Rpl_semi_sync_master_wait_sessions         | 0     |
    | Rpl_semi_sync_master_yes_tx                | 3     |               #大于0就是半同步模式
    +--------------------------------------------+-------+
    14 rows in set (0.00 sec)
      
    ==========================================================
    现在做下测试:
    当半同步复制发生超时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。
    当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。
      
    mysql> show variables like "rpl_semi_sync_master_timeout";
    +------------------------------+-------+
    | Variable_name                | Value |
    +------------------------------+-------+
    | rpl_semi_sync_master_timeout | 10000 |
    +------------------------------+-------+
    1 row in set (0.00 sec)
      
    关闭从数据库的slave
    mysql> stop slave;
    Query OK, 0 rows affected (0.14 sec)
      
    然后在主数据库插入一条数据,发现半同步复制会发生超时
    发生超时后,暂时关闭半同步复制,转而使用异步复制
    mysql> insert into kevin.haha values(55,"laolao");
    Query OK, 1 row affected (10.13 sec)
      
    mysql> show status like 'Rpl_semi_sync_master_status';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | Rpl_semi_sync_master_status | OFF   |
    +-----------------------------+-------+
    1 row in set (0.00 sec)
      
    从数据库也会关闭半同步
    mysql> show status like 'Rpl_semi_sync_slave_status';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | OFF   |
    +----------------------------+-------+
    1 row in set (0.00 sec)
      
    接着再打开从数据库的slave
    mysql> start slave;
    Query OK, 0 rows affected (0.04 sec)
      
    然后主数据再插入一条数据,就会发现半同步复制不会超时,半同步复制功能打开也打开了
    mysql> insert into kevin.haha values(555,"laolaolao");
    Query OK, 1 row affected (0.04 sec)
      
    mysql> select * from haha;
    +-----+-----------+
    id  | name      |
    +-----+-----------+
    |   1 | linux     |
    |   2 | anhui     |
    |   3 | huoqiu    |
    |   4 | xihuju    |
    |   5 | grace     |
    |   6 | huihui    |
    |  11 | linux-ops |
    |  55 | laolao    |
    | 555 | laolaolao |
    +-----+-----------+
    9 rows in set (0.00 sec)
      
    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> select * from haha;
    +-----+-----------+
    id  | name      |
    +-----+-----------+
    |   1 | linux     |
    |   2 | anhui     |
    |   3 | huoqiu    |
    |   4 | xihuju    |
    |   5 | grace     |
    |   6 | huihui    |
    |  11 | linux-ops |
    |  55 | laolao    |
    | 555 | laolaolao |
    +-----+-----------+
    9 rows 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.00 sec)

    通过上面的验证可知,遇到半同步复制超时情况,就会自动降为异步工作。可以在Slave上停掉半同步协议,然后在Master上创建数据库看一下能不能复制到Slave上。需要注意一点的是,当Slave开启半同步后,或者当主从之间网络延迟恢复正常的时候,半同步复制会自动从异步复制又转为半同步复制,还是相当智能的。

                                                                              删除"半同步复制", 恢复"异步复制"模式                                                  

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    先在从数据库上关闭半同步复制功能,然后卸载半同步插件
    mysql> stop slave;
    Query OK, 0 rows affected (0.07 sec)
     
    mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 0;
    Query OK, 0 rows affected (0.00 sec)
     
    mysql> show status like 'Rpl_semi_sync_slave_status';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | OFF   |
    +----------------------------+-------+
    1 row in set (0.00 sec)
     
    mysql> UNINSTALL PLUGIN rpl_semi_sync_slave;
    Query OK, 0 rows affected (0.00 sec)
     
    mysql> show status like 'Rpl_semi_sync_slave_status';
    Empty set (0.00 sec)
     
    mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';
    Empty set (0.01 sec)
     
    删除my.cnf里面的半同步配置
    [root@mysql-slave mysql]# vim /usr/local/mysql/my.cnf
    #plugin-load=rpl_semi_sync_slave=semisync_slave.so
    #rpl_semi_sync_slave_enabled=ON
     
    一定要重启mysql服务
    [root@mysql-slave mysql]# /etc/init.d/mysql restart
    Shutting down MySQL..                                      [  OK  ]
    Starting MySQL..                                           [  OK  ]
     
    =========================================================
    接着再主数据库关闭半同步复制功能,卸载半同步插件
    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> SET GLOBAL rpl_semi_sync_master_enabled = 0;
    Query OK, 0 rows affected (0.00 sec)
     
    mysql> show status like 'Rpl_semi_sync_master_status';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | Rpl_semi_sync_master_status | OFF   |
    +-----------------------------+-------+
    1 row in set (0.00 sec)
     
    mysql> show status like '%Rpl_semi%';
    +--------------------------------------------+--------+
    | Variable_name                              | Value  |
    +--------------------------------------------+--------+
    | Rpl_semi_sync_master_clients               | 0      |                               #确保这一行的数值为0,即没有半同步复制的客户端
    | Rpl_semi_sync_master_net_avg_wait_time     | 40186  |
    | Rpl_semi_sync_master_net_wait_time         | 401860 |
    | Rpl_semi_sync_master_net_waits             | 10     |
    | Rpl_semi_sync_master_no_times              | 2      |
    | Rpl_semi_sync_master_no_tx                 | 1      |
    | Rpl_semi_sync_master_status                | OFF    |
    | Rpl_semi_sync_master_timefunc_failures     | 0      |
    | Rpl_semi_sync_master_tx_avg_wait_time      | 592    |
    | Rpl_semi_sync_master_tx_wait_time          | 4737   |
    | Rpl_semi_sync_master_tx_waits              | 8      |
    | Rpl_semi_sync_master_wait_pos_backtraverse | 0      |
    | Rpl_semi_sync_master_wait_sessions         | 0      |
    | Rpl_semi_sync_master_yes_tx                | 8      |
    +--------------------------------------------+--------+
    14 rows in set (0.00 sec)
     
    mysql> UNINSTALL PLUGIN rpl_semi_sync_master;
    Query OK, 0 rows affected (0.00 sec)
     
    mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';
    Empty set (0.00 sec)
     
    mysql> show status like 'Rpl_semi_sync_master_status';
    Empty set (0.00 sec)
     
    删除my.cnf里面的半同步配置
    [root@mysql-master ~]# vim /usr/local/mysql/my.cnf
    #plugin-load=rpl_semi_sync_master=semisync_master.so
    #rpl_semi_sync_master_enabled=ON
    #rpl-semi-sync-master-timeout=1000
     
    一定要重启mysql服务
    [root@mysql-master ~]# /etc/init.d/mysql restart
    Shutting down MySQL...                                     [  OK  ]
    Starting MySQL..                                           [  OK  ]
     
    =========================================================
    再接着重启从数据库上的IO线程
    mysql> STOP SLAVE IO_THREAD;
    Query OK, 0 rows affected (0.04 sec)
     
    mysql> START SLAVE IO_THREAD; 
    Query OK, 0 rows affected (0.00 sec)
     
    =========================================================
    通过上面操作,就完全删掉了mysql半同步复制模式,恢复异步复制模式。
    在关闭半同步复制模式的过程中,可以查看/data/mysql/data/mysql-error.log日志信息,从中观察到半同步关闭的信息。
     
    在从机重新start slave
    mysql> start slave;
    Query OK, 0 rows affected, 1 warning (0.00 sec)
     
    mysql> show slave status G;
    .........
    .........
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
     
    接着在主数据插入新数据
    mysql> select * from kevin.haha;
    +-----+-----------+
    id  | name      |
    +-----+-----------+
    |   1 | linux     |
    |   2 | anhui     |
    |   3 | huoqiu    |
    |   4 | xihuju    |
    |   5 | grace     |
    |   6 | huihui    |
    |  11 | linux-ops |
    |  55 | laolao    |
    | 555 | laolaolao |
    +-----+-----------+
    9 rows in set (0.00 sec)
     
    mysql> insert into kevin.haha values(12,"wangjuan");
    Query OK, 1 row affected (0.04 sec)
     
    mysql> insert into kevin.haha values(13,"congcong");
    Query OK, 1 row affected (0.04 sec)
     
    去从库上查看,发现已经同步过来了
    mysql> select * from kevin.haha;
    +-----+-----------+
    id  | name      |
    +-----+-----------+
    |   1 | linux     |
    |   2 | anhui     |
    |   3 | huoqiu    |
    |   4 | xihuju    |
    |   5 | grace     |
    |   6 | huihui    |
    |  11 | linux-ops |
    |  12 | wangjuan |
    |  13 | congcong |
    |  55 | laolao    |
    | 555 | laolaolao |
    +-----+-----------+
    9 rows in set (0.00 sec)
     
    ======================================================
    温馨提示:
    经过几次实验,发现了一个坑,就是在做mysql半同步复制模式下,主从同步配置要是基于整个数据库的同步,而不要使用"binlog_do_db"
    "binlog_ingore_db"进行过滤库的同步配置,否则会造成半同步复制模式下的数据同步失败。
     
    之前做过一次实验,mysql主从关系是针对某个具体库进行配置同步的,即:
    主数据库的my.cnf配置:
    #主从同步配置
    server-id=1       
    log-bin=mysql-bin  
    binlog-do-db=kevin
    binlog-ignore-db=mysql 
    sync_binlog = 1   
    binlog_checksum = none
    binlog_format = mixed
     
    # 半同步复制功能开启
    plugin-load=rpl_semi_sync_master=semisync_master.so
    rpl_semi_sync_master_enabled=ON   
    rpl-semi-sync-master-timeout=1000 
     
    从数据库的my.cnf配置:
    #主从同步配置
    server-id=2  
    log-bin=mysql-bin  
    replicate-do-db=kevin
    replicate-ignore-db=mysql 
    slave-skip-errors = all
     
    # 半同步复制功能开启
    plugin-load=rpl_semi_sync_slave=semisync_slave.so
    rpl_semi_sync_slave_enabled=ON
     
    然后从库通过下面方式跟主数据库同步
    mysql> change  master to master_host='172.16.60.205,master_user='slave',master_password='slave@123',master_log_file='mysql-bin.000007',master_log_pos=120;
     
    以上配置的mysql主从同步是针对kevin这个具体的库的,在后续半同步复制模式下,主从数据同步失败。
    而且在这种情况下,删除半同步复制模式配置,恢复到异步同步模式,主从数据同步还是失败。
     
    -----------------------------------------------------------
    最后修改主从数据库的my.cnf文件,按照下面方式进行主从同步,则半同步复制模式下,主从数据同步正常。
    并且删除半同步复制模式配置,恢复到异步同步模式,主从数据同步一样正常。
     
    主数据库的my.cnf文件调整后的配置:
    #主从同步配置
    server-id=1
    log-bin=mysql-bin
    sync_binlog = 1
    binlog_checksum = none
    binlog_format = mixed
     
    # 半同步复制功能开启
    plugin-load=rpl_semi_sync_master=semisync_master.so
    rpl_semi_sync_master_enabled=1
    rpl-semi-sync-master-timeout=1000
     
    从数据库的my.cnf文件调整后的配置:
    #主从同步配置
    server-id=2
    log-bin=mysql-bin
    slave-skip-errors = all
     
    # 半同步复制功能开启
    plugin-load=rpl_semi_sync_slave=semisync_slave.so
    rpl_semi_sync_slave_enabled=1
      
    然后从库通过下面方式跟主数据库同步
    mysql> change master to master_host = '172.16.60.205', master_port = 3306, master_user ='slave', master_password ='slave@123';
     
    ============================================================
    特别注意下:
    在做mysq主从同步时最好别过滤库了,即最好进行基于整个数据库的同步配置,同步命令为:
    "change master to master_host = '主数据库ip', master_port = 主数据库mysql端口, master_user ='同步的用户', master_password ='同步的密码';"
     
    使用过滤库或过滤表的方式进行主从同步配置,后续会带来一些比较麻烦的坑。
    如果业务数比较多的情况下,就使用mysql多实例方式进行同步,一个业务一个mysql实例,主从同步配置中不要进行过滤库或表的配置,即基于整个数据库同步。

    另外,在实际使用中还碰到一种情况从库IO线程有延迟时,主库会自动把半同步复制降为异步复制;当从库IO延迟没有时,主库又会把异步复制升级为半同步复制。可以进行压测模拟,但是此时查看Master的状态跟上面直接关闭Slave半同步有些不同,会发现Rpl_semi_sync_master_clients仍然等于1,而Rpl_semi_sync_master_status等于OFF。随着MySQL 5.7版本的发布,半同步复制技术升级为全新的Loss-less Semi-Synchronous Replication架构,其成熟度、数据一致性与执行效率得到显著的提升。




  • 相关阅读:
    mysql 主从架构搭建
    tomcat+nginx 反向代理 动静分离
    ELK(Elasticsearch + Logstash + Kibana)安装部署对nginx的日志收集
    Kibana server is not ready yet出现的原因
    apache+tomcat+单机双实例+动静分离+负载均衡
    docker的基本安装和简单使用+Dockerfile常用指令
    LVS+keepalived+DR 负载均衡高可用
    md5sum摘要
    python爬虫
    python和数据库
  • 原文地址:https://www.cnblogs.com/anthony-wang0228/p/11013202.html
Copyright © 2011-2022 走看看