若是你的生产线开启了半同步复制,那么对数据的一致性会要求较高,但在MySQL5.5/5.6里,会存在数据不一致的风险。有这么一个场景,客户端提交了一个事务,master把binlog发送给slave,在发送的期间,网络出现波动,此时Binlog Dump线程发送就会卡住,要等待slave把binlog写到本地的relay-log里,而后给master一个反馈,等待的时间以rpl_semi_sync_master_timeout参数为准,默认为10秒。在这等待的10秒钟里,在其余会话里,查看刚才的事务是能够看见的,此时一旦master发生宕机,因为binlog没有发送给slave,前端app切到slave查看,就会发现刚才已提交的事务不见了。前端
例如,在双十一期间,抢购产品,出现了上面这种状况,用户下了一个订单,因为网络波动,发送binlog给slave卡住了(10秒),那个用户又刷新了一下浏览器,看见了刚才下的订单,此时master宕机,经过高可用failover到了slave上(slave未接收到那个binlog),他发现我刚才下的订单没了,他确定大骂,老子钱花了,订单不见了,直接投诉。sql
为了解决这种问题,MySQL5.7 改善了半同步复制这个缺陷。经过rpl_semi_sync_master_wait_point这个参数加以控制,默认是AFTER_SYNC,官方推荐用这个,它的工做原理是:master把binlog发送给slave,只有在slave把binlog写到本地的relay-log里,才提交到存储引擎层,而后把请求返回给客户端,客户端才能够看见刚才提交的事务。若是slave未保存到本地的relay-log里,客户端是看不见刚才的事务的,这样就不会形成上述那个场景发生。另外一个值是AFTER_COMMIT,这个值是采用老式的MySQL5.5/5.6半同步复制工做。数据库
另外:在MySQL5.7 半同步复制能够经过rpl_semi_sync_master_wait_slave_count参数指定有几台slave接收到了binlog才成功返回客户端请求,默认是一台,但不能指定是具体哪台。
浏览器
参考:服务器
AFTER_SYNC (the default): The master writes each transaction to its binary log and the slave, and syncs the binary log to disk. The master waits for slave acknowledgment of transaction receipt after the sync. Upon receiving acknowledgment, the master commits the transaction to the storage engine and returns a result to the client, which then can proceed.
主库把每个事务写到二进制日志并保存磁盘上,且发送给从库。主库在等待从库写到本身的relay-log里确认信息。在接到确认信息后,主数据库把事务写到存储引擎里并把相应结果反馈给客户端,客户端将在那时进行处理。
AFTER_COMMIT: The master writes each transaction to its binary log and the slave, syncs the binary log, and commits the transaction to the storage engine. The master waits for slave acknowledgment of transaction receipt after the commit. Upon receiving acknowledgment, the master returns a result to the client, which then can proceed.
主库把每个事务写到二进制日志并保存磁盘上,且发送给从库,并把事务写到存储引擎里。主库在等待从库写到本身的relay-log里确认信息。在接到确认信息后,主库把相应结果反馈给客户端,客户端将在那时进行处理。
The replication characteristics of these settings differ as follows:
这两个参数不一样之处在于:
With AFTER_SYNC, all clients see the committed transaction at the same time: After it has been acknowledged by the slave and committed to the storage engine on the master.。Thus, all clients see the same data on the master.
在设置为AFTER_SYNC参数,全部的客户端能够同时看到提交的数据:在获得从库写到本身的relay-log里的确认信息后,并把事务写到存储引擎里。这样,全部的客户端均可以在主库上看到一样的数据。
In the event of master failure, all transactions committed on the master have been replicated to the slave (saved to its relay log). A crash of the master and failover to the slave is lossless because the slave is up to date.
主库报错,全部已经写到从库的事务都已经保存到了relay log里。主库的崩溃,HA切换到从库,不会带来任何损失,由于从库的relay-log的数据是最新的。
With AFTER_COMMIT, the client issuing the transaction gets a return status only after the server commits to the storage engine and receives slave acknowledgment. After the commit and before slave acknowledgment, other clients can see the committed transaction before the committing client.
在设置为AFTER_COMMIT 参数,发起事务的客户端仅在服务器向存储引擎写入数据并接受从库获得确认以后才返回状态。在写入数据后和获得从库确认以前,其余的客户端能够看到在这一事务。
If something goes wrong such that the slave does not process the transaction, then in the event of a master crash and failover to the slave, it is possible that such clients will see a loss of data relative to what they saw on the master.
若是出现了某种错误,好比说从库的sql_thread线程没有执行,那么主库崩溃和故障转移给从服务器的前提下,有可能这个客户端会丢失那些他们曾经在主库上看到的信息。
网络