MySQL之不得不说的keepsync和trysync

此文已由做者温正湖受权网易云社区发布。
html

欢迎访问网易云社区,了解更多网易技术产品运营经验。数据库


开宗明义,keepsync和trysync是网易MySQL分支版本InnoSQL的两个参数,很是重要的两个参数。从某种程度上说,他们决定了MySQL主从复制实例是采用异步复制(async)仍是半同步复制(semi-sync)。为何不得不说呢,由于不断有同窗问怎么看当前RDS实例是同步仍是异步状态,keepsync和trysync这两个参数是干吗用的,怎么进行设置?因而简单写下semi-sync和这两个参数关系。服务器


MySQL semi-sync异步

在MySQL中有个很是著名的semi-sync插件(plugin),或者叫半同步插件。若是将主从复制做为一个系统, 处于半同步下的主从复制系统,即便主库MySQL宕机且没法修复,只要从库MySQL正常, 用户向该系统发送的已经返回commit的请求数据仍然不会丢失,知足事务ACID中的D(Durability)。这是在MySQL传统的异步复制体系下迈出的很是具备里程碑意义的一步,其实在这一点上,InnoSQL一直处于领先的位置。为何叫半同步复制,而不是同步(全同步)复制,这是由于在semi-sync复制下,主库MySQL上事务记录的Binlog信息,发送给从库MySQL,在从库MySQL的IO Thread将其以Relay-Log形式(本质上仍是Binlog,只不过披了一个马甲)持久化后即向主库MySQL返回ACK信息,而不是在SQL Thread(其实已经不是一个Thread了,姑且这么说吧)将该事务对应的Relay-Log在从库MySQL上执行后才返回ACK(这个就是全同步)。semi-sync之因此不丢数据,缘由就在于主库只有收到从库ACK信息后,才会给用户/客户端返回事务已提交。显然此时只要从库存放Relay-Log的硬盘不坏,数据是不会丢的。不过最近看来,很不乐观。:)async


虽然有这么牛X一个插件,但默认状况下MySQL复制仍是异步的。要开启semi-sync,仍是简单作几个操做。先要在主从上都安装semi-sync插件(主: INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';从:INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';);而后还要设置几个参数(主:rpl_semi_sync_master_enabled=1;从:rpl_semi_sync_slave_enabled=1);固然,要从异步状态切为同步状态,还须要从新start slave。在上述都作了以后,经过Rpl_semi_sync_slave_status 状态值能够查看当前复制是否已是semi-sync状态(状态为ON)。是否是敲简单。正常的,人一旦理解了一个技术或掌握了一个知识点,就会以为其实挺简单的。须要注意的是,semi-sync在某些场景下会退化为异步,若是用户不知情,恰好这个时候主库MySQL挂了,那就悲剧了(丢数据了),因此,监控Rpl_semi_sync_slave_status状态挺重要,固然,MySQL还提供了其余几个状态用来观察semi-sync复制状态。那么何时会退化为异步呢,就得来讲说rpl_semi_sync_master_timeout,超过所设置的微秒数后,主库MySQL退化为异步复制。默认时间为1000,也就是若是主库发送Binlog后,从库1s以内没有返回ACK,主库就切异步了。若是用户不想轻易切异步,就须要设置一个更大的值。但设置大了又会带来了其余问题。工具


InnoSQL加强.net

为了更好得掌控实例semi-sync和async状态切换,在InnoSQL中新增了两个参数rpl_semi_sync_master_keepsyncrepl和rpl_semi_sync_master_trysyncrepl。用来更灵活得控制状态切换行为,部分取代rpl_semi_sync_master_timeout的做用,二者的取值均为ON/OFF。固然,这两个参数不是独立起做用的,而是在前面所述的参数基础上发挥做用的。不知不过前面所述的参数变为了必要条件而非充分条件。插件


也就是说,即便rpl_semi_sync_master_enabled、rpl_semi_sync_slave_enabled均为1,若是rpl_semi_sync_master_trysyncrepl为OFF,复制状态也没法从async切换为semi-sync。处于semi-sync状态,即便rpl_semi_sync_master_timeout微秒内从库未返回ACK信息,若是rpl_semi_sync_master_keepsyncrepl为ON,则复制状态也没法从semi-sync切为async。只有在用户/系统管理员将rpl_semi_sync_master_keepsyncrepl改成OFF后才能切为async。orm


这里引出一个问题,用户怎么决定要不要切异步,根据什么状态来进行判断呢? 显然,一个事务已经花了多少时间等待ACK这个状态很是关键,但MySQL并无提供该信息给用户,因而在InnoSQL中加入了事务的ACK等待时间状态,可用经过show processlist获取ACK_WAIT_TIME或information_schema.processlist中的ACK_WAIT_TIME来了解每一个事务已花费的等待ACK时间状态。用户可规定一个阈值,经过查询ACK_WAIT_TIME字段,若是有事务超过了阈值,那么就设置rpl_semi_sync_master_keepsyncrepl为OFF切异步。htm


RDS使用方式

接下来进一步聊下网易云RDS如何使用semi-sync。RDS提供了两种高可用实例,分别是同步实例和异步实例,但无论同步仍是异步实例,semi-sync插件均启用,且rpl_semi_sync_master_enabled、rpl_semi_sync_slave_enabled均为ON。区别在于rpl_semi_sync_master_trysyncrepl和rpl_semi_sync_master_keepsyncrepl值,同步实例两个参数均为ON,异步实例两个参数均为OFF。RDS支持用户将异步实例修改成同步实例,重要的一步就是rpl_semi_sync_master_trysyncrepl和rpl_semi_sync_master_keepsyncrepl设置为ON,也支持同步实例修改成异步实例,即将其设置为OFF。


同步实例在出现从库MySQL返回ACK超时(卡主)的时候,目前超时设置为5s,会由RDS管理服务器将该实例设置为修复中,实例复制临时转为异步模式(关闭rpl_semi_sync_master_trysyncrepl和rpl_semi_sync_master_keepsyncrepl),重试从库MySQL重启,从新创建到主库的复制关系,并尝试转为同步模式(开启rpl_semi_sync_master_trysyncrepl和rpl_semi_sync_master_keepsyncrepl),确认Rpl_semi_sync_slave_status为ON以后(即转同步成功),将实例从新置为可用/运行中。


最后,上述描述仅聚焦于semi-sync的一些参数和状态,并无详细介绍semi-sync的原理、实现,介绍说明启用semi-sync的具体步骤。


网易云数据库RDS是一种稳定可靠、可弹性伸缩的在线关系型数据库服务,当前支持MySQL引擎,提供基础版,高可用版,金融版针对不一样业务场景的高可用解决方案,点击可免费试用


网易云免费体验馆,0成本体验20+款云产品! 

更多网易技术、产品、运营经验分享请点击


相关文章:
【推荐】 遭遇各类内容监管,有些企业到底欠缺的是什么,仅仅是价值观吗?
【推荐】 教你如何选择BI数据可视化工具
【推荐】 关于《金字塔原理》的主要内容