当前位置: 首页 > 后端技术 > PHP

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

时间:2023-03-29 22:20:01 PHP

最近开发中遇到的一个MySQL主从延迟的坑,记录总结一下,避免重蹈覆辙。场景一条活动信息需要审批,审批通过后才能生效。因为activity后面需要编辑,编辑后也可能会触发审批。编辑前的活动内容显示在审批中。考虑到字段比较多,审批活动的内容也要保存下来。因此在设计中使用了临时表。将活动写入审批表(activity_tmp),审批通过后才将真正的活动内容写入活动表(activity)。表的简要设计如下,其中活动内容字段合并为内容展示:activity_tmp()idstatus//审批状态内容//审批阶段提交的活动内容activityidcontent//活动内容提交后的实际展示批准通过。当时遇到的问题是编辑触发审批的情况,审批通过后发现活动内容为空,于是开始追查问题原因。在这里说一下,当程序出现问题的时候,95%是代码的问题,所以不要怀疑环境有问题。仔细查看日志,然后查看您的代码。追溯问题回溯1.查看activity_tmp表,发现当时提交审批的活动内容正常,状态更新为通过审批。怀疑是写activity表失败了。2.查看活动表,发现审批后的内容确实没有写回车,怀疑是代码问题3.查看代码,代码逻辑没看出问题,怀疑是数据库操作失败,查看日志4、日志显示一条??insert语句的active内容为空,active内容来自于之前mysql执行的是select语句,取出select语句放入在线备库查询,发现active内容存在。运行时查询为空,执行完查询后内容存在。初步怀疑是主从延迟问题。5、报错只是部分失败,确定是主从延迟问题。当时的问题代码$intStatus=$arrInput['status'];$this->objActTmp->updateInfoByAId($intActId,$intStatus);//更新后立即查看$arrActContent=$this->objActTmp->getActByStatus($intStatus);这就是主从延迟发生的地方。更新后,立即获取。这是在主从复制架构上发展起来的一个忌讳。解决方案此类问题有两种解决方案:修改代码逻辑和修改系统架构。对于修改代码逻辑,我有两种意见:如果第二步获取的数据不需要第一步更新的status字段,先读取,如果第二步获取的数据依赖status再更新第一步中的字段,然后在读出时判断是否为空,如果为空则报错,下次再试。总结其实以前也听过这样的例子,但是因为没有亲身经历,所以只保留了一个理论上的记忆。其实我没有很深的印象。经过这样的一次踩坑,印象特别深刻。现在看到别人写这样的代码也能马上找到并指出来。自己踩坑还是印象最深。日志很重要,详细的日志更重要。日志应该记录有用的信息,以便在追查问题时方便追溯问题的本质原因。我觉得日志应该尽可能做成飞行器中的黑匣子,帮助我们保存“意外”发生时的所有相关信息。接下来我将学习主从复制的原理,敬请期待。更多精彩内容,请关注我公众号。