设为首页 收藏本站
查看: 1060|回复: 0

[经验分享] mysql半同步复制问题排查

[复制链接]

尚未签到

发表于 2018-10-8 11:39:44 | 显示全部楼层 |阅读模式
  1.问题背景
  默认情况下,线上的mysql复制都是异步复制,因此在极端情况下,主备切换时,会有一定的概率备库比主库数据少,因此切换后,我们会通过工具进行回滚回补,确保数据不丢失。半同步复制则要求主库执行每一个事务,都要求至少一个备库成功接收后,才真正执行完成,因此可以保持主备库的强一致性。为了确保主备库数据强一致,减少数据丢失,尝试在生产环境中开启mysql的复制的半同步(semi-sync)特性。实际操作过程中,发现大部分实例半同步都可以正常运行,但有少部分实例始终开不起来(只能以普通复制方式运行),更奇葩的是同一个主机的两个实例,一个能开启,一个不能。最终定位的问题也很简单,但排查出来还是花了一番功夫,下文将描述整个问题的排查过程。
  2.半同步复制原理
  mysql的主备库通过binlog日志保持一致,主库本地执行完事务,binlog日志落盘后即返回给用户;备库通过拉取主库binlog日志来同步主库的操作。默认情况下,主库与备库并没有严格的同步,因此存在一定的概率备库与主库的数据是不对等的。半同步特性的出现,就是为了保证在任何时刻主备数据一致的问题。相对于异步复制,半同步复制要求执行的每一个事务,都要求至少有一个备库成功接收后,才返回给用户。实现原理也很简单,主库本地执行完毕后,等待备库的响应消息(包含最新备库接收到的binlog(file,pos)),接收到备库响应消息后,再返回给用户,这样一个事务才算真正完成。在主库实例上,有一个专门的线程(ack_receiver)接收备库的响应消息,并以通知机制告知主库备库已经接收的日志,可以继续执行。有关半同步的具体实现,可以参考另外一篇文章,mysql半同步(semi-sync)源码实现。
  3.问题分析
  前面简单介绍了半同步复制的原理,现在来看看具体问题。在主备库打开半同步开关后,问题实例的状态变量"Rpl_semi_sync_master_status"始终是OFF,表示复制一直运行在普通复制的状态。
  (1).修改rpl_semi_sync_master_timeout参数。
  半同步复制参数中有一个rpl_semi_sync_master_timeout参数,用以控制主库等待备库响应消息的时间,如果超过该值,则认为备库一直没有收到(备库可能挂了,也可能备库执行很慢,较主库相差很远),这个时候复制会切换为普通复制,避免主库的执行事务长时间等待。线上这个值默认是50ms,简单想是不是这个值太小了,遂将其改到10s,但问题依然不解。
  (2).打印日志
  排查问题最简单最笨的方法就是打日志,看看到底是哪个环节出了问题。主库和备库分别有rpl_semi_sync_master_trace_level和rpl_semi_sync_slave_trace_level参数来控制半同步复制打印日志。将两个参数值设置为80(64+16),记录详细日志信息,以及进出的函数调用。

master:2016-01-04 18:00:30 13212 [Note] ReplSemiSyncMaster::updateSyncHeader: server(-1721062019), (mysql-bin.000006, 500717950) sync(1), repl(1)2016-01-04 18:00:40 13212 [Warning] Timeout waiting for reply of binlog (file: mysql-bin.000006, pos: 500717950), semi-sync up to file , position 0.2016-01-04 18:00:40 13212 [Note] Semi-sync replication switched OFF.  

  
slave:2016-01-04 18:00:30 38932 [Note] ---> ReplSemiSyncSlave::slaveReply enter2016-01-04 18:00:30 38932 [Note] ReplSemiSyncSlave::slaveReply: reply (mysql-bin.000006, 500717950)2016-01-04 18:00:30 38932 [Note] 1024的情况,所以这个bug不是很容易出现,但问题是普遍存在的。
  (7)问题延伸
  问题定位后,另外一个问题还困扰我了半天。因为mysql内核中有监听的部分有3块,1是监听端口的select,2是线程池的监听epoll,3是半同步的select监听。slave binlog dump的线程就是普通的工作线程,而工作线程的socket会受epoll的监听,这样一来,binlog dump的socket会同时受半同步的select监听和线程池的epoll监听,这不乱了吗?后来仔细看了看代码,才发现线程池的epoll监听采用的是EPOLLONESHOT模式,每次接收消息后会解绑,需要重新注册,因此不会出现同一个句柄被两种监听机制同时监听的情况。
  到此,排查问题过程就结束了,结论是比较简单的,但定位这个问题确实花费了一些功夫。由于select一种比较通用的多路IO复用机制,因此有用到select函数的童鞋,可能要注意下它的限制。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-616458-1-1.html 上篇帖子: MySQL 5.7新支持--------通用表空间实战 下篇帖子: MySQL基础——事务隔离级别
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表