在日常开发或线上运维中,我们经常会遇到各种数据库异常,例如超时、死锁等。但有些问题,表面看似平常,背后却藏着意想不到的原因。

今天就分享一次由服务器时间跳跃引发的 MySQL 获取锁超时问题的排查过程。

问题现象:大量锁超时日志出现

某天系统日志中突然频繁出现如下报错信息:

Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction

获取锁超时导致事务失败。

初步分析:死锁?

可能是出现死锁了,于是根据异常栈定位到问题代码,但发现该方法逻辑简单,仅修改一个entity,类似下面这样。(非真实业务代码)

// 仅更新用户的最后访问时间
user.setLastVisitTime(LocalDateTime.now());
userRepository.save(user);

强行分析(猜想),这个修改是每个请求都会改到的,由于在请求事务内,事务没提交就会一直锁着,直到请求完成。

但一个长期稳定运行的项目,请求不太可能突然变慢

深入排查:慢日志未出现异常

如果出现死锁,那么慢日志里面一定有记录。但实际排查袭来,慢日志并无User相关的慢查询。

蛛丝马迹:不太常见的日志

om.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=1m26s857ms76µs413ns).

翻阅日志,发现一条clock leap detected的异常记录。于是验证服务器时间,发现比本地环境快了40多秒。

真相大白:服务器时间跳跃引发误判

MySQL进行锁等待和事务超时时,依赖系统时间戳进行判断。当系统时间突然跳跃到未来时间,导致MYSQL误判。

至于跳跃原因,推测是 NTP 客户端在检测到时间漂移后进行了强制同步(stepping)操作,瞬间将时间快进了几十秒。

更近一步:有哪些操作会导致获取锁超时?

在 MySQL 使用 InnoDB 引擎的前提下,锁超时Lock wait timeout exceeded)的出现通常有两个主要诱因:

1. 死锁(Deadlock)

最常见的原因就是死锁。死锁往往由于多个事务以不同顺序下修改相同资源,彼此持有对方需要的锁,造成互相等待、永远无法释放。

比如:

  • 事务 A 修改顺序是:先改用户,再改订单;

  • 事务 B 修改顺序是:先改订单,再改用户;

  • 双方各自持有一个锁,又想获取对方的,结果就死锁了。

MySQL 会检测到死锁并主动中断其中一个事务。(这时候日志里就会出现Dealock报错了)

其实,只要在项目中统一规定 Entity 的修改顺序,大部分死锁是可以避免的。

2. 长事务导致的锁未及时释放

InnoDB 中,事务未提交期间会一直持有锁。如果事务执行时间过长,会导致其他并发请求长时间阻塞,最终抛出锁等待超时异常。

事务执行过长,常见原因包括:

  • Entity 修改过多

    比如循环中逐个修改并保存,每次都 save(),反复刷 SQL。

  • 事务中包含耗时操作

    例如调用外部服务、HTTP 接口、微服务 RPC 等,尤其是对慢接口没有超时控制时。

  • 事务中存在显式等待

    Thread.sleep() 用于调试、限速等场景,期间锁不会释放。

【杂谈】死锁?NO,时间跳跃!的更多相关文章

  1. 使用SQL Server 扩展事件来创建死锁的时间跟踪

    我们通过SQL Server 2012图形界面来部署一个扩展事件跟踪会话.然后可以生成SQL脚本,在2008或2008 R2版本下运行类似的跟踪. 步骤1: 通过“Object Explorer”连接 ...

  2. 【DP】【P5615】 [MtOI2019] 时间跳跃

    Description 给定 \(n\) 条边,第 \(i\) 条边的长度为 \(i\),每条边都有 \(50\%\) 的概率被选择,求如果选出的边能组成一个平面凸多边形,则方案的权值是方案中边的数量 ...

  3. DB2死锁的解决办法

    db2 get snapshot for locks on sampledb2 get db cfg for sampledb2 update db cfg using dlchktime 10000 ...

  4. 时间,闰秒,及NTP

    1.时间 格林尼治时间 GMT,以地球自转为准的时间,也叫世界时UT,但是由于自转速度会变化,所以后来不被作为标准. 世界协调时UTC,以原子钟为准,现在时间校准的标准就是原子钟. 2.闰秒 是指地球 ...

  5. 数据结构与算法(c++)——跳跃表(skip list)

    今天要介绍一个这样的数据结构: 单向链接 有序保存 支持添加.删除和检索操作 链表的元素查询接近线性时间 ——跳跃表 Skip List 一.普通链表 对于普通链接来说,越靠前的节点检索的时间花费越低 ...

  6. 基于innodb_print_all_deadlocks从errorlog中解析MySQL死锁日志

    本文是说明如何获取死锁日志记录的,不是说明如何解决死锁问题的. MySQL的死锁可以通过show engine innodb status;来查看,但是show engine innodb statu ...

  7. java和mysql之间的时间日期类型传递

    摘自:http://blog.csdn.net/weinianjie1/article/details/6310770 MySQL(版本:5.1.50)的时间日期类型如下: datetime 8byt ...

  8. 一次查找sqlserver死锁的经历

    查找bug是程序员的家常便饭,我身边的人喜欢让用户来重现问题.当然他们也会从正式服务器上下载错误log,然后尝试分析log,不过当错误不是那种不经思考就可识别的情况,他们就会将问题推向用户,甚至怪罪程 ...

  9. mysql和java的时间对应关系

    引用:http://blog.csdn.net/xinghuo0007/article/details/51500923 MySQL(版本:5.1.50)的时间日期类型如下: datetime 8by ...

  10. linux环境下的时间编程

    Linux下提供了丰富的api以供开发者们处理和时间相关的问题.然而这些接口看似各自为政实则有有着千丝万缕的联系,在学习和时间中引发了各种各样的混乱.因此时间处理成为了许多Linux开发者的梦魇,遇到 ...

随机推荐

  1. delphi编写sql脚本文件批量执行程序

    程序使用DelphiXE11.1开发,用到控件UniDac9.1.1,QDAC里面的Qlog组件. 程序实现了SQL脚本文件批处理执行应用,运行效果图. 文件.pas代码 unit main; int ...

  2. ISA-L库调研

    本文分享自天翼云开发者社区<ISA-L库调研>,作者:何****尔 1.Intel SIMD指令集 SIMD(single instruction multiple data)单指令多数据 ...

  3. ChatGPT 背后的英雄——AI芯片

    本文分享自天翼云开发者社区<ChatGPT 背后的英雄--AI芯片>,作者:w****n AI芯片能为人工智能应用提供所需的基础算力:按技术架构主要分为GPU.FPGA和ASIC.Chat ...

  4. 在 PyTorch 中理解词向量,将单词转换为有用的向量表示

    你要是想构建一个大型语言模型,首先得掌握词向量的概念.幸运的是,这个概念很简单,也是本系列文章的一个完美起点. 那么,假设你有一堆单词,它可以只是一个简单的字符串数组. animals = [&quo ...

  5. Flink名词介绍

    一.常用名词 1.Slot:处理槽,一般为服务器核数*4,平分服务器内存 2.Window:时间窗口 滚动窗口(Tumbling Window)将事件拆分成固定长度,窗口之间不重叠,窗口长度固定 例: ...

  6. RFID基础——高频RFID协议、读写模块和标签

    RFID技术中的低频.高频.超高频有各自的优点和应用场景.其中,与我们个人生活息息相关的门禁卡.公交卡.身份证.图书标签主要用到的是高频RFID.这些应用也对应着高频RFID中不同的协议. 高频RFI ...

  7. OpenCascade 开源的三维建模几何造型开发平台

    官方文档 https://dev.opencascade.org/doc/overview/html/index.html Open CASCADE(简称OCC)平台是由法国Matra Datavis ...

  8. 库卡KUKA机器人KRC2示教器维修常见方法

    库卡KUKA机器人以稳定性而备受赞誉.作为其重要组成部分,KRC2示教器在机器人的编程.监控和调试过程中发挥着至关重要的作用.然而,就像其他任何电子设备一样,KRC2示教器在长期使用过程中也可能会遇到 ...

  9. QT5笔记:6. QT 与 C++

    QT 对标准的C++进行了扩展,引入了一些新的概念和功能 QT 的元对象编译器(Meta-Object Compiler, MOC)是一个预处理器,它预处理QT项目,先将QT的一些特性代码转换为标准的 ...

  10. TDH - 使用DBeaver连接InceptorSQL

    TDH版本:TDH 4.3.x DBeaver版本:dbeaver-ce-23.0.4-win32.win32.x86_64 1.下载客户端(即为DBeaver连接InceptorSQL所需的驱动包) ...