前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >当 MySQL 连接池遇上事务(二):消失的记录

当 MySQL 连接池遇上事务(二):消失的记录

原创
作者头像
Coder Sam
修改于 2017-06-20 03:38:07
修改于 2017-06-20 03:38:07
4.2K03
代码可运行
举报
文章被收录于专栏:Coder Sam的专栏Coder Sam的专栏
运行总次数:3
代码可运行

1. 往事回顾

MySQL连接池是一个很好的设计,通过将大量短连接转化为少量的长连接,从而提高整个系统的吞吐率。但是当跟事务一起使用时,如果使用方式不恰当时,就会发生一些奇怪的事。之前写过一篇文章专门讲述了遇到的一件奇怪的事情,详见《当MySQL连接池遇上事务(一):神秘的幽灵锁》

简单地说,《神秘的幽灵锁》一文,问题出在上层业务使用MySQL公共库时没意识到底层的连接池,导致使用方式不当。在上层看来是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
开启事务->执行SQL->commit

而实际底层实现是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
获取一个连接->开启事务->扔回连接池->获取一个连接->执行SQL->扔回连接池->获取一个连接->commit->扔回连接池。

这个过程无法保证每次拿到的都是同一个连接,也就存在了很大的隐患。当业务接口异常退出时,由于没有执行commit或rollback的连接已经被放回连接池,导致该带状态的连接没有被释放,并且进一步影响到该连接后续操作过的表。

解决方案是修改所有使用事务的接口,在事务结束之前不能将连接放回连接池。但是由于改动量较大,在全部接口修改完成之前,先对可能导致接口退出的异常进行处理,避免异常情况的发生。这样也正常稳定地运行了一段时间,没有再发生之前的问题。

直到……

2. 非阻塞HTTP也来搞怪

2.1 非阻塞HTTP的背景

之前说过,项目组使用OpenResty作为API Server,当需要执行HTTP调用时,早期很自然地选择了成熟的luasocket库。luasocket库是lua的一个开源库,对于常用的HTTP功能都能很好的满足,包括直接调用、代理转发、超时时间设置等。但是lua的库大多数阻塞调用的,对于OpenResty这样一个100%异步非阻塞的高性能服务器来说,阻塞的HTTP调用对对整体性能造成致命的伤害。

因此,近期正在使用非阻塞的resty.http库来替换luasocket库。resty.http是OpenResty的一个第三方开源HTTP调用的实现,采用了与OpenResty一致的风格,支持直接调用、反向代理、超时时间设置等特性,最重要的,它是非阻塞的。

2.2 HTTP调用方式居然影响到MySQL

按理说,替换HTTP库跟MySQL不应该有任何关系。阻塞与非阻塞强调的是调用方,只要保证替换HTTP库前后,对于同一个HTTP调用,被调用方收到的请求参数和请求方法完全一致即可。被调接口不应该也不能感知调用方使用的是阻塞还是非阻塞调用。

但是,奇怪的事情又双叒叕发生了……

替换luasocket库为非阻塞的resty.http之后,在页面配置时必现错误(后续定位是MySQL引起的)。奇怪的是,使用resty.http时错误必现,而恢复luasocket后则不会发生!!

2.3 消失的记录

为了定位,在平台接口内加了很多日志。定位的结果居然是,平台接口往异步任务表X插入一条记录,插入成功并且获取到一个自增长的任务ID N,但是当sleep之后再次查询该任务状态时,发现任务ID为N的记录并不存在。并且,之后再往表X插入记录,自增长的任务ID居然跳过了N,直接是N+1。

接口的日志和N+1的任务ID,都证明了任务ID为N的记录曾经存在过,但是从数据库中却找不到这条记录的任何踪迹。我把这叫做“消失的记录”。

3. 事物是普遍联系滴

奇怪的事情屡次发生,我又开始了艰辛的探索之路。这一次,我需要把两个看起来不相关的东西(HTTP调用方式和MySQL)联系起来。这很艰难,我还是根据现有的线索一步步往前推,看看究竟能走到哪。接下来还是以“提问-解答”的方式进行。

1) 记录会不会是被删除了?

遇到消失的记录,首先的怀疑是,记录会不会被删除了?

于是对该接口代码进行审阅(该接口是其他同事开发的)。审阅的结果令人失望,所有代码都是那么的正常,连让人怀疑的地方都没有。于是又把所有代码都搜索了一遍,居然没找到有删除任务表X的地方。至于第三方脚本删除,从时间上和删除记录的选择性上看,应该是不可能的。

当然,为了验证我的判断,解析了binlog,发现任务ID为N的记录压根就没有插入过,更没有被删除过。

记录被删除的可能,排除!

2) 记录是不是插入失败了?

既然从binlog看,记录没有被插入过,那么接口日志为什么显示获得了自增长的任务ID N呢?一个合理的怀疑是,在获得自增长ID之后,因为某个未知的原因导致插入失败了。查看MySQL文档,确实在插入失败的情况下,仍然可能会占用一个自增长ID。

那么是否是插入失败了呢?因为接口日志显示的是插入成功并且没有发生任何错误,怀疑插入失败就是怀疑resty.mysql库有问题。。没事,咱有怀疑精神,确认就是了。于是又开始阅读resty.mysql库的源码了。源码并不复杂,确认了只有MySQL APi返回正常时,resty.mysql库才会返回正常。MySQL API我还是信得过的,嘿嘿嘿。

也就是说,记录确实是插入成功了!

3) 插入成功的记录为什么没有binlog?

有了上一次《神秘的幽灵锁》的经验,这一次我很快意识到可能是因为事务!在事务内,接口认为插入成功了,但是后面事务rollback了,所以导致没有写入binlog。那么,这一切就解释的通了。

因为平台接口没有使用事务,只有业务接口使用了,所以只能是跨接口影响。于是,我赶紧搜索OpenResty的错误日志,希望找到上次一样的“lua entry thread abort”异常。但是很遗憾,这次所有接口都没有异常退出。

这条路到这里走到了尽头。。

4) HTTP调用方式为什么会跟事务扯上关系?

既然从MySQL本身出发的路走不下去,那就从HTTP调用方式思考。

替换luasocket为resty.http,从HTTP请求的功能上看是完全等价的,唯一的不同在于调用方式从阻塞变成了非阻塞。也就是说,非阻塞调用导致了MySQL连接的混用,平台接口拿到了业务接口开启了事务的连接。

为了验证这个猜想,我再次查看resty.mysql的文档,找到了一个函数get_reused_times(),该函数返回MySQL连接被使用的次数。通过在业务接口和平台接口加上日志打印get_reused_times()的结果,确认了我的猜想:业务接口调用了平台接口,当使用luasocket时,平台接口第一次get_reused_times()的结果是0,说明是新创建的连接;而使用resty.http时,平台接口第一次get_reused_times()的结果是业务接口调用平台接口前get_reused_times()的结果加1,说明平台接口拿到了业务接口的同一个连接。

那么,非阻塞在这个过程中究竟起到什么作用呢?我百思不得其解,直到我看到了这么一句话:

You can specify the max idle timeout (in ms) when the connection is in the pool and the maximal size of the pool every nginx worker process.

重点是“every nginx worker process”!也就是说,resty.mysql的连接池是worker级别的!!

使用luasocket时,因为阻塞,所以新的请求不会被分配到业务请求相同的worker上,也就是说,开启了事务的连接,不会被其他请求使用,因为根本就没有其他请求会使用这个worker的连接池!

但是换成非阻塞的resty.http之后,业务接口发起HTTP请求后,该worker仍然可以接受新的请求,并且非阻塞内部接口调用类似于子查询,在OpenResty看来就是同一个请求,所以必然分配到同一个worker。被调用的平台接口很自然的拿到了开启事务的连接,并往任务表X成功插入了一条记录(任务ID为N)。而在平台接口sleep之后,因为该连接超过了keepalive时间已经被释放,事务没有被提交,再次获取连接查询时,就查不到刚才插入的记录了,从而造成“消失的记录”。

进一步推想,如果sleep时间没超过keepalive时间,那么也是会有问题的。这次不会出现消失的记录,异步任务记录插入成功,但是由于该连接已开启了事务,会导致任务表被加上行锁和间隙锁,从而导致任务处理svr等锁而无法处理任务,任务最终还是会超时失败。

4. 那些年,我们那一如既往的幸运

“消失的记录”问题总算搞清楚了,现在再回顾一下,在《神秘的幽灵锁》一文,我说过我们使用“连接池+事务”的方式一直是错误的,但是却很幸运地没发生过问题,其根本原因就在于我们使用了阻塞的HTTP请求库。阻塞的方式导致我们的连接池同一时刻只有一个请求在使用,也就避免了接口间相互影响的可能。而如今,非阻塞的resty.http,把我们的运气用完了,所以到了需要处理这个问题的时候了。

问题的处理方式之前已经说过,就是修改事务接口用连接池的方式,在事务结束之前不能将连接放回连接池。但这个改动量较大,在全部修改完成之前,resty.http只怕是不能上线了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
NLP(自然语言处理)扫盲
最近在学NLP,给自己扫扫盲,看看NLP具体干什么,本文先学学概念,后面再深入。(不是很深入的文章,高手误入。) 自然语言处理(简称NLP),是研究计算机处理人类语言的一门技术,是人工智能(AI)的一个子领域,包括: 1.句法语义分析:对于给定的句子,进行分词、词性标记、命名实体识别和链接、句法分析、语义角色识别和多义词消歧。 2.信息抽取:从给定文本中抽取重要的信息,比如,时间、地点、人物、事件、原因、结果、数字、日期、货币、专有名词等等。通俗说来,就是要了解谁在什么时候、什么原因、对谁、做了什么事、有什
大数据和云计算技术
2018/03/08
1.7K0
NLP学习路线总结
自然语言处理(Natural Language Processing,NLP)是计算机科学领域与人工智能领域中的一个重要方向。它研究人与计算机之间用自然语言进行有效通信的理论和方法。融语言学、计算机科学、数学等于一体的科学。旨在从文本数据中提取信息。目的是让计算机处理或“理解”自然语言,以执行自动翻译、文本分类和情感分析等。自然语言处理是人工智能中最为困难的问题之一。
全栈程序员站长
2022/11/10
1.4K0
NLP学习路线总结
NLP 基础知识大集合
大纲 NLP基础概念 NLP的发展与应用 NLP常用术语以及扩展介绍 ---- 1.1 什么是NLP 基本分类 自然语言生成(Natural Language Generation,NLG) 指从结构化数据中以读取的方式自动生成文本,主要包括三个阶段: 文本规划:完成结构化数据中的基础内容规划; 语句规划:从结构化数据中组合语句来表达信息流; 实现:产生语法通顺的语句来表达文本; 研究任务 机器翻译 情感分析 智能问答 文摘生成 文本分类 舆论分析 知识图谱 ---- 1
村雨遥
2022/06/15
7370
NLP 基础知识大集合
自然语言处理(NLP)学习路线总结
NLP是自然语言处理(Natural Language Processing)的缩写,它是计算机科学领域中专注于研究如何使计算机理解、生成和处理人类语言的学科。NLP涉及的技术包括但不限于分词、词性标注、句法分析、语义分析、机器翻译、情感分析、信息抽取、文本生成等。通过NLP,计算机可以处理和分析大量的文本数据,帮助人们更好地理解和应用语言信息。
机器学习AI算法工程
2024/07/04
1.4K0
自然语言处理(NLP)学习路线总结
《自然语言处理实战课程》---- 第一课:自然语言处理简介
大家好,今天开始和大家分享,我在自然语言处理(Natural Language Processing,NLP)的一些学习经验和心得体会。
流川疯
2019/04/17
2.4K0
《自然语言处理实战课程》---- 第一课:自然语言处理简介
从语言学到深度学习NLP,一文概述自然语言处理
选自arXiv 机器之心编译 参与:李亚洲、蒋思源 本文从两篇论文出发先简要介绍了自然语言处理的基本分类和基本概念,再向读者展示了深度学习中的 NLP。这两篇论文都是很好的综述性入门论文,希望详细了解自然语言处理的读者可以进一步阅读这两篇论文。 本文第一部分介绍了自然语言处理的基本概念,作者将 NLP 分为自然语言理解和自然语言生成,并解释了 NLP 过程的各个层级和应用,这一篇论文很适合读者系统的了解 NLP 的基本概念。 第二部分描述的是基于深度学习的 NLP,该论文首先描述了深度学习中的词表征,即从
机器之心
2018/05/08
1K0
从语言学到深度学习NLP,一文概述自然语言处理
绝干货! | 最有用的自然语言处理(NLP)入门资料
一周的时间转瞬即逝,今天作者给大家分享一下最近收集关于自然语言处理的一些资料,与大家分享,记得保存喲~不然到期了你还得给我要,^_^
ShuYini
2019/08/08
1.8K0
绝干货! | 最有用的自然语言处理(NLP)入门资料
《人工智能与自然语言处理:开启智能交流新时代》
在当今科技迅猛发展的时代,人工智能已经成为了各个领域的热门话题。其中,自然语言处理(Natural Language Processing,简称 NLP)作为人工智能的一个重要分支,正逐渐改变着我们与计算机交互的方式。那么,人工智能究竟是如何进行自然语言处理的呢?
程序员阿伟
2024/12/09
1710
详解自然语言处理5大语义分析技术及14类应用(建议收藏)
自然语言处理技术的研究,可以丰富计算机知识处理的研究内容,推动人工智能技术的发展。
IT阅读排行榜
2020/08/07
5.9K0
详解自然语言处理5大语义分析技术及14类应用(建议收藏)
【精品】NLP自然语言处理学习路线(知识体系)
下面的鱼骨图就是个人整理的NLP相关的一个学习路线,某种意义上可以理解为一个知识体系,本文将尽量结合示例简单的去描述一下这些基本概念。
MinChess
2023/09/07
1.2K0
【精品】NLP自然语言处理学习路线(知识体系)
一文梳理NLP之机器翻译和自动摘要的发展现状
2 NLP入门:CNN,RNN应用文本分类,个性化搜索,苹果和乔布斯关系抽取(2)
double
2018/07/25
2.6K0
【一分钟知识】依存句法分析
本文简要介绍了自然语言处理中极其重要的句法分析,并侧重对依存句法分析进行了重点总结,包括定义、重要概念、基本方法、性能评价、依存分析数据集,最后,分享了一些流行的工具以及工具实战例子。
zenRRan
2019/07/12
1.7K0
自然语言处理(NLP)技术的详细介绍
自然语言处理(Natural Language Processing,简称NLP)是人工智能(Artificial Intelligence,简称AI)领域的一个重要分支,旨在让计算机能够理解、理解和生成人类语言。
正在走向自律
2024/12/18
3K0
自然语言处理(NLP)技术的详细介绍
《NLP》你真的了解”自然语言处理(NLP)“吗?
上一周,清华大学AMiner发布了《2018自然语言处理研究报告》(下载地址:https://pan.baidu.com/s/1IXuZLgGVHjfYyyX63jcVHQ),因为时间原因,没能及时的更新,希望大家见谅。现在作者以初学者的态度整理了一下该报告的主要内容,希望能帮助大家。
ShuYini
2019/08/08
1.4K0
《NLP》你真的了解”自然语言处理(NLP)“吗?
从技术到人才,清华-中国工程院知识智能联合实验室发布「2018自然语言处理研究报告」
摘自AMiner 机器之心整理 参与:李亚洲、思源 自然语言处理是现代技术最重要的组成部分之一,而最近清华大学和中国工程院知识智能联合实验室发布一份非常全面的 NLP 报告。该报告从 NLP 的概念介
机器之心
2018/08/07
4940
从技术到人才,清华-中国工程院知识智能联合实验室发布「2018自然语言处理研究报告」
NLP学习基础入门(上)
NLP (Natural Langunge Possns,自然语言处理)是计算机科学领域以及人工智能领域的一个重要的研究方向,它研究用计算机来处理、理解以及运用人类语言(如中文、英文等),达到人与计算机之间进行有效通讯。所谓“自然”乃是寓意自然进化形成,是为了区分一些人造语言,类似C++、Java 等人为设计的语言。
菲宇
2020/03/25
1K0
一文概览NLP算法(Python)
NLP是人工智能领域历史较为悠久的领域,但由于语言的复杂性(语言表达多样性/歧义/模糊等等),如今的发展及收效相对缓慢。比尔·盖茨曾说过,"NLP是 AI 皇冠上的明珠。" 在光鲜绚丽的同时,却可望而不可及(...)。
算法进阶
2022/06/02
2.4K0
一文概览NLP算法(Python)
HanLP《自然语言处理入门》笔记--1.新手上路
自然语言处理(Natural Language Processing,NLP)是一门融合了计算机科学、人工智能及语言学的交叉学科,它们的关系如下图所示。这门学科研究的是如何通过机器学习等技术,让计算机学会处理人类语言,乃至实现终极目标–理解人类语言或人工智能。
mantch
2020/02/18
1.4K0
自然语言处理(一)NLP概述
NLP是利用计算机为工具,对人类特有的书面形式和口头形式的自然语言的信息进行各种类型处理和加工的技术.
JNJYan
2019/01/11
1.2K0
NLP随笔(四)
70 年代以后随着互联网的高速发展,语料库越来越丰富以及硬件更新完善,自然语言处理思潮由理性主义向经验主义过渡,基于统计的方法逐渐代替了基于规则的方法。
XianxinMao
2021/08/04
4410
推荐阅读
相关推荐
NLP(自然语言处理)扫盲
更多 >
LV.1
量化类主流自媒体新媒体运营
目录
  • 1. 往事回顾
    • 2. 非阻塞HTTP也来搞怪
    • 2.1 非阻塞HTTP的背景
    • 2.2 HTTP调用方式居然影响到MySQL
    • 2.3 消失的记录
  • 3. 事物是普遍联系滴
  • 4. 那些年,我们那一如既往的幸运
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档