记录一次mysql长事务的经历

目录

一.项目介绍

二.问题暴漏

三.问题排查

1.连接池方向

2.数据库方向

四.代码模拟

五.错误原因分析

1.MySQL参数优化

2.代码优化

六.总结


一.项目介绍

项目是springboot+nacos的微服务架构,商城购物类系统,分多个服务,问题出现在众多服务中的单个服务

二.问题暴漏

在系统日志中显示错误:connection holder is null,空连接

Caused by: java.sql.SQLException: connection holder is nullat com.alibaba.druid.pool.DruidPooledConnection.checkStateInternal(DruidPooledConnection.java:1155)at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1148)at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:336)

这种错误是偶发现象,日志出现时,重启后消失,使用druid连接池

三.问题排查

1.连接池方向

初步认为连接池的问题,通过给druid开源项目提issue,尝试调整druid参数

参数调优过程:

1.调整maxActive,加大连接数

2.开启remove-abandoned,调整remove-abandoned-timeout和log-abandoned,清除未使用的连接

3.druid从1.1.9升级当时最新版本1.2.23

4.开启test-while-idle,启用keep-alive,加大min-evictable-idle-time-millis,用于连接检测

5.开启test-on-borrow和test-on-return,连接在借还时进行检测

spring:datasource:url: jdbc:mysql://localhost:3306/emall?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTCusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverdruid:# 初始化时建立物理连接的个数initial-size: 0# 最小空闲连接数min-idle: 0# 设置连接池中最大活动连接数max-active: 10# 获取连接时最大等待时间,单位毫秒,1000毫秒等1秒max-wait: 30000# 多久进行一次空闲连接的检测,单位毫秒(60,000 毫秒为1分钟)time-between-eviction-runs-millis: 60000# 连接在池中最小生存的时间,单位毫秒min-evictable-idle-time-millis: 300000# 设置用于连接验证的 SQL 查询语句validation-query: SELECT 1# 在空闲时检测连接有效性test-while-idle: true# 获取连接时不测试连接,影响性能test-on-borrow: false# 归还连接时不测试连接,影响性能test-on-return: false# 启用keepAlive,确保连接池中的连接不被数据库服务端关闭keep-alive: true# 是否清除长时间未使用的连接remove-abandoned: false#定义连接被认定为被遗弃之前的超时时间(单位:秒)remove-abandoned-timeout: 1800#是否记录遗弃连接的日志信息log-abandoned: true  # 记录遗弃连接的日志

通过以上几个参数的调整,错误是有变化的,好像是一套组合拳,removeAbandoned: true/testOnBorrow=true/升级版本,三个操作下去,出现connection closed

Caused by: java.sql.SQLException: connection closedat com.alibaba.druid.pool.DruidPooledConnection.checkStateInternal(DruidPooledConnection.java:1178)at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1169)at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:356)

关闭removeAbandoned: false,出现connection disabled

Caused by: java.sql.SQLException: connection disabledat com.alibaba.druid.pool.DruidPooledConnection.checkStateInternal(DruidPooledConnection.java:1184)at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1169)at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:356)

错误都出自druid连接池的DruidPooledConnection的checkStateInternal方法

以上操作并没有解决问题,

2.数据库方向

1.对mysql数据库进行参数调优,应该是开启testOnReturn: true,配置mysq的'max_connections'最大连接数为2000,组合操作下来,看到的新错误,Lock wait timeout exceeded; try restarting transaction

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

另一个错误是Statement cancelled due to timeout or client request

Cause: com.mysql.cj.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request

2.调整mysql以下参数进行观察

SET innodb_lock_wait_timeout = 100; #增加锁等待时间为100s
set global innodb_print_all_deadlocks=1;#控制是否将所有死锁信息打印到 MySQL 错误日志
SET GLOBAL max_allowed_packet = 10M; 指定客户端与服务器之间通信时单个数据包的最大大小4改10

以上操作没有解决问题

3.通过查询数据库中的事务,锁,连接情况,查看是否有慢sql,性能查询语句:

SELECTtrx.trx_id  事务的唯一标识符,trx.trx_state   事务的状态,trx.trx_started 事务开始的时间,trx.trx_mysql_thread_id 事务关联的MySQL线程ID,trx.trx_isolation_level 事物隔离级别,t.name 线程名称,pl.Id 线程ID,pl.USER 线程所属的用户,pl.HOST 线程连接的主机,pl.Command  线程的当前命令,pl.TIME 线程的运行时间,pl.State 线程的状态,pl.Info 正在执行的SQL语句,es.THREAD_ID ,es.SQL_TEXT 当前执行的SQL语句,es.CURRENT_SCHEMA 当前使用的数据库,es.TIMER_WAIT/1000000000 语句的执行时间,il.lock_id 锁的唯一标识符,il.lock_mode 锁的模式,il.lock_type 锁的类型,il.lock_table 被锁定的表,il.lock_index 被锁定的索引,il.lock_space 被锁定的表空间,il.lock_page 被锁定的页,il.lock_rec 被锁定的记录
FROMinformation_schema.INNODB_TRX trxLEFT JOIN information_schema.PROCESSLIST pl ON trx.trx_mysql_thread_id = pl.IdLEFT JOIN information_schema.INNODB_LOCKS il ON trx.trx_id = il.lock_trx_idLEFT JOIN PERFORMANCE_SCHEMA.threads t ON t.processlist_id =  pl.idLEFT JOIN PERFORMANCE_SCHEMA.events_statements_current es ON es.THREAD_ID  = t.thread_id

查询mysql大量的长事务和锁等待,事务执行时间太长,这个是明显能查到的问题,应该是事务长时间未提交导致,即着手先解决长事务问题.

四.代码模拟

通过对事务不提交操作,模拟长事务

数据库出现长时间的事务未提交,锁类型:表锁和行锁,锁模式:IX:表级别意向排他锁,X:行级别排他锁,REC_NOT_GAP: 记录锁(不包括间隙,确保锁定的是精确的行记录,避免幻读),InnoDB存储引擎使用多种锁模式来实现事务隔离和一致性

再执行一次方法,出现锁等待,

五.错误原因分析

可能长事务存在时间超过了druid连接池的生存时间,连接被连接池回收关闭,程序报错,并且大量的长事务造成锁等待或者死锁,消耗资源.

1.MySQL参数优化

可以缩短mysql的wait_timeout一个连接在服务器端闲置多长时间后会被自动关闭,默认是8小时,比如600秒

2.代码优化

1.缩小事务控制范围,比如,只有在更新数据库时,再开启事务,对于查询等这类逻辑操作无需开启事务.

2.发生异常时,捕捉异常,进行事务回滚.

3.逻辑判断需要提前结束方法时.对于已经开启的事务记得关闭.

六.总结

问题为何偶发,并且系统自上线的这几年来只有近期才出现问题.

        可能是在近期MySQL提升了隔离级别,由读已提交(Read Committed)改为可重复读(Repeatable Read),为保证数据的一致性,数据库的锁竞争会变的激烈,并发事务对同一资源(如表或行)的访问需求较高,导致锁(行锁或者表锁)争用严重,并且造成死锁,虽然 InnoDB 通常会自动检测和处理死锁,但在某些复杂情况下,可能会导致事务超时。较高的事务隔离级别(如 SERIALIZABLE)可能会导致更多的锁竞争和等待超时。之前适合RC级别的代码写法已经不适用RR级别.

        近期又是系统使用高发期,使用人数较多,业务牵扯的范围较广,但代码优化的覆盖面却很窄,导致问题暴漏,功能阻塞,后续将继续做好监测.        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/30038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CAD二次开发(11)-在用C#进行CAD开发SQLite和SqlSugar的使用

1. System.Data.SQLite的使用 1.1 包的引入 利用 Nuget引入其相关包 1.2 App.config配置引入到CAD 因为我们当前的项目是类库项目,需要依托于宿主程序才可以运行,所以我们就得需要将SQLite自动生成的App.config里面的部分配置移植到CAD的配置文件中…

DC/AC电源模块:为医疗设备提供安全可靠的电力转换

BOSHIDA DC/AC电源模块:为医疗设备提供安全可靠的电力转换 DC/AC电源模块是一种用于将直流电源转换为交流电源的设备,广泛应用于各种医疗设备中。它们的主要功能是为医疗设备提供安全可靠的电力转换,以确保这些设备在工作过程中提供稳定的电…

硬盘格式化NTFS好还是exFAT好 U盘存储文件用哪个格式好? 硬盘用exfat还是ntfs mac不能读取移动硬盘怎么解决

在计算机世界中,文件系统是数据管理的基石,而NTFS和exFAT无疑是这块基石上的两大巨头。它们各自拥有独特的特点和优势,并在不同的使用场景中发挥着重要作用。 什么是文件系统 文件系统提供了组织驱动器的方法。它规定了如何在驱动器上存储数…

android中的JNI的DEMO

一:源代码 native-lib.cpp #include "native-lib.h"JNIEXPORT jint JNICALL Java_com_example_jnidemo_MainActivity_add(JNIEnv* env, jobject, jint a, jint b) {return a b; }JNIEXPORT jint JNICALL Java_com_example_jnidemo_MainActivity_subtra…

当 DolphinDB 遇上方程式赛车:捕捉极速赛场上的时间印记

在风驰电掣的赛车场上,每一毫秒都蕴藏着无限的可能。在这里,数据不再是冰冷的数字序列,而是跳动的脉搏,每一次跃动都精准地回应着赛车的每一次呼吸,敏锐感知着赛车的动态。随着物联网和遥测技术的发展,实时…

六西格玛培训新选择,老字号品质有保障!

在追求企业卓越与完美的道路上,六西格玛管理无疑是一个被广泛认可与采纳的方法论。六西格玛不仅仅是一种管理策略,更是一种文化和哲学,它强调通过数据驱动和持续改进来减少流程中的缺陷,提升客户满意度,并最终实现企业…

【ARM Coresight Debug 系列 -- ARMv8/v9 软件实现断点地址设置】

请阅读【嵌入式开发学习必备专栏 】 文章目录 ARMv8/v9 软件设置断点地址断点地址软件配置流程代码实现 ARMv8/v9 软件设置断点地址 在ARMv8/9架构中,可以通过寄存器 DBGBVR0_EL1 设置断点。这个寄存器是一系列调试断点值寄存器中的第一个DBGBVRn_EL1,其…

jpg图片怎么压缩大小?图片压缩,3个方法

在日常生活中,我们经常会面临着需要在网络上传送、分享或存储的图片文件过大的问题,而JPG格式的图片由于其普遍性,也常常成为我们处理的对象。为了解决这一常见的挑战,学会如何压缩JPG图片的大小是非常实用的技能。 在这篇文章中…

「51媒体」电视台媒体邀约采访报道怎么做?

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 电视台作为地方主流媒体,对于新闻报道有着严格的选题标准和报道流程。如果您希望电视台对某个会议或活动进行报道,可以按这样的方法来做: 1.明确活动信…

鼠情自动监测系统

TH-SH1在农业生产中,鼠害问题一直是困扰农民的一大难题。传统的鼠害防治方法往往依赖于大规模施药或布置捕鼠器等方式,这些方法不仅效率低下,而且容易对环境造成污染。随着科技的不断发展,鼠情自动监测系统应运而生,为…

LabVIEW Windows与RT系统的比较与选择

LabVIEW是一种系统设计和开发环境,广泛应用于各类工程和科学应用中。LabVIEW Windows和LabVIEW RT(Real-Time)是LabVIEW的两个主要版本,分别适用于不同的应用场景。以下从多个角度详细分析两者的区别,并提供选择建议。…

云计算 | (七)特殊云机制

文章目录 📚自动伸缩监听器📚负载均衡器📚SLA监控器📚按使用付费监控器📚审计监控器📚故障转移系统📚虚拟机监控器📚资源集群📚多设备代理📚状态管理数据库📚自动伸缩监听器 自动伸缩监听器 (Automated scaling listener)是一个服务代理,它监控和追踪…

JavaFX 下拉框

组合框允许用户选择几个选项之一。用户可以滚动到下拉列表。组合框可以是可编辑和不可编辑的。 创建组合框 以下代码将选项列表包装到ObservableList中&#xff0c;然后使用observable列表实例化ComboBox类。 ObservableList<String> options FXCollections.observab…

机器学习课程复习——朴素贝叶斯

1. 定义 是一种基于贝叶斯定理与特征条件独立假设的生成式分类方法。 2. 公式 原版公式 简化版公式 由于上述公式无法计算&#xff0c;引入条件独立假设 条件独立版公式 3. 贝叶斯分类器 由上述公式可得贝叶斯分类器 化简为 4. 参数估计 4.1. 极大似然估计 4.2. 学习与分…

【规格说明】软件需求规格说明书实际项目案例模板(doc原件套用)

1 范围 1.1 系统概述 1.2 文档概述 1.3 术语及缩略语 2 引用文档 3 需求 3.1 要求的状态和方式 3.2 系统能力需求 3.3 系统外部接口需求 3.3.1 管理接口 3.3.2 业务接口 3.4 系统内部接口需求 3.5 系统内部数据需求 3.6 适应性需求 3.7 安全性需求 3.8 保密性需求 3.9 环境需求…

【Nginx系列】反向代理在现代网络架构中的重要性

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

C# 利用XejeN框架源码,编写一个在 Winform 界面上的语法高亮的编辑器,使用 Monaco 编辑器

析锦基于Monaco技术实现的Winform语法高亮编辑器 winform中&#xff0c;我们有时需要高亮显示基于某种语言的语法编辑器。 目前比较强大且UI现代化的&#xff0c;无疑是宇宙最强IDE的兄弟&#xff1a;VS Code。 类似 VS Code 的体验&#xff0c;可以考虑使用 Monaco Editor&a…

vue3-父子通信

一个简单的vue3子组件调用父组件方法的demo <template> <div> <h2>Parent Component父组件</h2> <ChildComponent notify-parent"handleParentMethod" /> </div> </template> <script> import { ref } fr…

LVGL开发教程-objects对象

知不足而奋进 望远山而前行 目录 知不足而奋进 望远山而前行​ 文章目录 前言 1.图层 2.objects 2.1 位置 2.2 尺寸 2.3 align 2.4 样式 总结 前言 在嵌入式 GUI 开发中&#xff0c;LVGL&#xff08;Light and Versatile Graphics Library&#xff09;是一个强大的工…

电脑丢失dll文件一键修复的方法有哪些?分析dll文件修复的多种策略

我们经常会遇到各种各样的问题&#xff0c;其中之一就是DLL文件的丢失。DLL文件&#xff08;动态链接库&#xff09;是操作系统和应用程序正常运行所必需的文件&#xff0c;当这些文件丢失或损坏时&#xff0c;可能会导致软件无法正常启动&#xff0c;甚至影响系统的稳定性。对…