【踩坑记录】记一回MySQL主从复制延迟的坑

如今开支中相见的一个MySQL主从延迟的坑,记录并计算,避免重新犯同样的错误。

情景

一个活动新闻需求审批,审批之后才能立竿见影。因为从此活动要编制,编辑后也可能接触审批,审批中显示的是编写前的位移内容,考虑到字段比较多,也要保留审批活动的始末,由此计划使用了一张临时表,审批中的活动写进审批表(activity_tmp),审批通过之后才把真正的移动内容写进活动表(activity)。表的简约设计如下,那里将活动内容字段合并为content浮现:

activity_tmp()
id
status // 审批状态    
content //  审批阶段提交的活动内容

activity
id
content // 审批通过后真正展示的活动内容

相见的标题

当即是有编制触发审批的情事,发现审批通过之后活动内容是空的,于是从头追查难点的案由。那里说一句,当程序出标题的时候,95%都是代码的题材,先不要去疑虑环境出难点。好好的查日志,然后看看你的代码吧。

追查难点回溯

1、查activity_tmp表,发现立时提交审批的移动内容是健康的,而且场合也换代为审批通过了,可疑是写入activity表战败
2、查activity表,发现审批后的内容真的没有写入,疑惑是代码难题
3、查看代码,代码逻辑没来看难题,疑忌数据库操作失利,查看日志
4、日志突显,有一句insert语句的位移内容为空,活动内容出自上一个mysql执行的是select语句,把该select语句拿出来放到线上的备库查询,发现运动内容是存在的。运行时查询为空,执行完成后查询时内容存在,初阶怀疑是骨干延迟难题。
5、报错只是有些败北,确定是主导延迟的标题。

立时的题材代码

$intStatus = $arrInput[‘status’];
$this->objActTmp->updateInfoByAId($intActId, $intStatus);
// 更新后,马上查
$arrActContent = $this->objActTmp->getActByStatus($intStatus);

这就是着力延迟出现的地点,update后,马上get,那是主从复制架构上支出的一个禁忌。

缓解方案

那类难点的缓解方案有几种:

  • 修改代码逻辑
  • 修改系统架构

对此修改代码逻辑,鄙人有两点看法:

  • 只要第二步获取的数目不需求首先步更新的status字段,那就先读,然后再革新
  • 假若第二步获取的数目必要看重第一步的status字段,那就在读出来的时候先判断是还是不是为空,假若是空的,报错,下一回重试。

总结

实际从前也听到过如此的例证,可是出于没有亲身经历,所以只保留了一种理论上的记得,实际上印象不深,经历了那般一回踩坑后,影像越发深远,现在看来旁人写这么的代码也能及时意识并提议。依然自己切身去踩坑印象最深。

日记很首要,详细的日记更要紧。日志要记录有用的音信,方便追查难点的时候去追溯难题的真面目原因。我觉得日志就应有尽量做成飞机中的黑匣子,扶助大家保留“事故“暴发时的拥有相关新闻。

尔后的就学里,主从延迟的体制和规律也值得去研讨一番。

网站地图xml地图