数据库超时排查

news2024/9/20 12:32:31

背景:

项目是用的springboot,连接池用的是hikaricp,且数据库连接做了LB配置,之前就是经常会有数据库出现问题,专家给到的解决方案。

数据连接io超时报错,排查了当时数据库各项指标都无显示异常,且也没有获取到当时的queryId,给出的解决方案是增加重试机制 ,但是成本太高,故自己根据日期排查下问题,日志如下

错误信息:

org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.<MSG>Read timed out

这条日志信息表明在与PostgreSQL数据库通信时发生了I/O错误,具体是读操作超时 (Read timed out)。

详细调用栈跟踪:

at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:383)

这个调用来自PostgreSQL JDBC 驱动程序,具体是在执行查询的时候抛出的异常。

at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:496)

位于 PgStatement 类,该类负责执行SQL语句。

at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:413)

这个方法负责执行普通的SQL语句。

at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:190)

表示这是通过PreparedStatement执行的SQL语句。

at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:152)

具体执行的是更新操作(executeUpdate 表示是INSERT、UPDATE或DELETE等更新操作)。

        JDBC4的isValid方法来测试连接是否可用,是通过向数据库服务器发送一个ping请求来实现的。这个ping请求的实现方式可能因数据库厂商而异,但通常包括向数据库服务器发送一个简单的网络数据包,以测试连接是否正常。

        JDBC4的isValid方法的原理是基于底层网络连接的有效性进行检测,它使用了底层协议的心跳机制来检测连接的有效性。当调用isValid方法时,JDBC驱动程序会发送一个心跳包到数据库服务器,等待数据库服务器的响应。如果在指定的超时时间内收到了响应,则认为连接是有效的,否则认为连接已经失效。 

at org.postgresql.jdbc.PgConnection.isValid(PgConnection.java:1465)

这里可以看到驱动程序在检查连接是否有效。(到这里就可以定位是校验获取的连接有效性出了问题,也就可以理解了当时为什么查不到queryId了)

at com.zaxxer.hikari.pool.PoolBase.isConnectionAlive(PoolBase.java:161)

HikariCP连接池在检查某个连接是否仍然活跃。

at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:186)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:162)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:100)

HikariCP连接池尝试获取一个连接。这个连接可能因为前述错误而失败。

at com.baomidou.dynamic.datasource.ds.ItemDataSource.getConnection(ItemDataSource.java:56)
at com.baomidou.dynamic.datasource.ds.AbstractRoutingDataSource.getConnection(AbstractRoutingDataSource.java:48)

显示使用的是动态数据源管理工具(例如MyBatis-Plus Dynamic Datasource),尝试从HikariCP连接池获取连接。

at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:159)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:117)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)

Spring JDBC 工具类尝试获取连接,从而对数据库进行操作。

at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80)
at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67)

MyBatis在Spring管理的事务中打开一个连接。同样反映出当前使用了Spring事务管理。

at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:345)
at com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.prepareStatement(MybatisSimpleExecutor.java:93)

MyBatis执行器获取连接并准备执行SQL语句。

at com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.doQuery(MybatisSimpleExecutor.java:68)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:333)

MyBatis执行查询操作,并从数据库中获取结果。

总结

从上述日志信息中,我们可以看到操作流程如下:

  1. 应用程序使用 MyBatis 和 Spring 获取数据库连接。
  2. 使用 HikariCP 作为连接池管理数据库连接。
  3. 在 HikariCP 中检查连接是否有效时,发生了 I/O 错误(读超时)。
  4. 这导致 PostgreSQL 驱动程序抛出 PSQLException 异常。

这通常表示网络问题、数据库配置问题或者客户端配置问题。需要进一步检查网络连接、数据库以及连接池的相关配置来排查具体原因。

具体的原因没定位出来,但是目前可以通过配置提升用户体感


hikari:

        # 数据库连接有效性校验超时时间(ms)  默认是5秒

        validation-timeout: 500


HikariCP 是怎么检查连接是否有效

HikariCP 是一个高性能的 JDBC 连接池,在管理数据库连接的过程中,它提供了一些机制来检查连接是否有效,以保证连接的可用性和稳定性。下面将详细介绍 HikariCP 如何检查连接是否有效:

1. Connection Test Options

HikariCP 提供了几个参数来配置连接的检测和验证,这些配置项帮助确保连接池中的连接是可用的:

  • connectionTestQuery    测试语句,不推荐配置  
  • validationTimeout      默认5秒   验证是否有效的超时时间
    • 最小设置为1秒毫秒数据会转为秒
    • final int validationSeconds = (int) Math.max(1000L, validationTimeout) / 1000;
  • idleTimeout       默认10分钟
    • 这个属性控制连接池中空闲连接的最大空闲时间,只有当连接池中连接数量大于最小连接数量(minimumIdle)时会生效
       
  • maxLifetime        默认30分钟
    • 这个属性控制连接池中一个连接的最大生存时间,当一个连接的生存时间大于这个值且没有正在被使用时,将会被关掉

      与idleTimeout区别

      max-lifetime控制连接的总的生命周期,无论当前连接数是否大于最小连接数量,都会关掉生命周期完结的连接,idle-timeout只控制空闲且大于最小连接数量的那部分连接

  • connectionTimeout    默认30秒   
    • 此属性控制客户端等待来自连接池的连接的最大毫秒数。如果超过这个时间而没有连接可用,将抛出SQLException。最低可接受的连接超时时间是250毫秒。默认值:30000(30秒)

  • leakDetectionThreshold      默认0  不开启连接泄露检测 

2. 无需显式配置的默认行为

HikariCP 默认情况下使用 JDBC 驱动程序提供的 isValid 方法来验证连接的有效性。isValid 方法通过尝试与数据库进行简单的通信验证连接是否有效。

3. 配置 connectionTestQuery

在某些情况下,具体的 JDBC 驱动程序可能不支持 isValid 方法,或者你想使用自定义的查询语句来验证连接。这时可以使用 connectionTestQuery 参数。

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://localhost:5432/yourdb");
config.setUsername("yourusername");
config.setPassword("yourpassword");
config.setConnectionTestQuery("SELECT 1");
HikariDataSource dataSource = new HikariDataSource(config);

4. 工作方式

当 HikariCP 需要验证连接时,它会执行以下步骤:

  1. 默认使用 isValid 方法

    boolean isValid = connection.isValid(validationTimeout);
    

    这个方法会使用数据库驱动提供的 isValid 方法,可以设置 validationTimeout 来指定超时。如果连接在规定时间内响应,那么这个连接被认为是有效的。

  2. 使用自定义 connectionTestQuery

    如果配置了 connectionTestQuery,HikariCP 会执行该查询来验证连接。这个查询应该是快速并且无副作用的,例如 SELECT 1。如果执行成功,这个连接被认为是有效的。具体代码逻辑如下:

    try (Statement statement = connection.createStatement()) {
        statement.executeQuery(connectionTestQuery);
        // If the query executes successfully, the connection is valid
    } catch (SQLException e) {
        // If query execution fails, the connection is considered invalid
    }
    

5. 使用 validationTimeout

HikariCP 提供了 validationTimeout 参数来配置连接验证的超时时间:

config.setValidationTimeout(5000);  // 设置验证超时时间为5秒

6. 连接池中的连接检查周期

HikariCP 在以下情况会进行连接检查:

  • 获取新连接:当应用请求新连接时,先检查当前连接是否有效。
  • 闲置连接:使用 idleTimeout 配置检查闲置连接是否应该被移除。
  • 最大连接生命周期:使用 maxLifetime 配置确保连接在规定的生命周期内使用,超过时间一律关闭,以避免潜在的资源泄漏或者某些数据库的限制。
config.setIdleTimeout(600000);      // 闲置10分钟后移除连接
config.setMaxLifetime(1800000);     // 连接最大生命周期为30分钟
config.setConnectionTimeout(30000); // 连接超时设置为30秒

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

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

相关文章

基于SA-BP模拟退火算法优化BP神经网络实现数据预测Python实现

在数据分析和机器学习领域&#xff0c;时间序列预测和多输入单输出系统的预测是重要且复杂的问题。传统的BP&#xff08;反向传播&#xff09;神经网络虽然具有强大的非线性函数逼近能力&#xff0c;但在处理这些问题时容易陷入局部极小值、训练速度慢以及过拟合等问题。为了克…

【读书笔记-《30天自制操作系统》-15】Day16

本篇内容继续多任务的讲解。上一篇中实现了两个任务之间的自动切换&#xff0c;但还不够通用&#xff0c;这里将其优化为多个任务之间的切换。接着引入了任务休眠的概念与休眠的程序实现。最后介绍了任务的优先级&#xff0c;一种用切换时间的长短来衡量&#xff0c;一种用Task…

【Qt】文件对话框QFileDialog

文件对话框QFileDialog ⽂件对话框⽤于应⽤程序中需要打开⼀个外部⽂件或需要将当前内容存储到指定的外部⽂件。 通过QFileDialog 可以选择一个文件&#xff0c;能够获取到这个文件的路径&#xff0c;打开文件/保存文件。 常⽤⽅法介绍&#xff1a; 1、打开⽂件&#xff08;⼀…

【高中生讲机器学习】17. 讲人话的主成分分析,它来了!(上篇)

创建时间&#xff1a;2024-08-13 首发时间&#xff1a;2024-09-05 最后编辑时间&#xff1a;2024-09-05 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名准高一学生&#xff0c;热爱…

Redis 集群高可用详解及配置

关型数据库 关系型数据库&#xff1a; 是建立在关系模型基础上的数据库&#xff0c;其借助于集合代数等数学概念和方法来处理数据库中的数据 主流的 MySQL、Oracle、MS SQL Server 和 DB2 都属于这类传统数据库 关型数据库的优缺点 特点&#xff1a; 1、数据关系模型基于关系…

Redis使用——Redis的redis.conf配置注释详解(三)

Redis使用——Redis的redis.conf配置注释详解&#xff08;三&#xff09; 背景 日常我们开发时&#xff0c;我们会遇到各种各样的奇奇怪怪的问题&#xff08;踩坑o(╯□╰)o&#xff09;&#xff0c;这个常见问题系列就是我日常遇到的一些问题的记录文章系列&#xff0c;这里整…

鸿蒙轻内核M核源码分析系列四 中断Hwi

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 持续更新中…… 在鸿蒙轻内核源码分析系列前几篇文章中&#xff0c;剖析了重要的数据结构。本文&#xff0c;我们讲述一下中断&#xff0c;会给读者介绍中…

Ubuntu固定USB串口名(包括1拖N的USB串口)

在运行Ubuntu系统的开发板上,如果使用可插拔的USB串口,有时候程序正在运行时,如果突然连接传感器的USB串口设备被插拔了一下,这时,会发现系统中的USB串口名发生了改变。例如,插拔之前是/dev/ttyUSB0,插拔之后变成了/dev/ttyUSB3。发生这种情况的时候,有时候会导致程序无…

Windows I/O系统

硬件存储体系 寄存器 处理器内部定义的存储体&#xff0c;它们除了存储功能&#xff0c;往往还兼有其他的能力&#xff0c;比如参与运算&#xff0c;地址解析&#xff0c;指示处理器的状态&#xff0c;等等。寄存器是由处理器内部专门的触发器电路实现的&#xff0c;处理器往…

jupyter里怎么设置代理下载模型

使用如下方式: %env http_proxyhttp://10.110.146.100:7890 %env https_proxyhttp://10.110.146.100:7890

【SLAM】GNSS的定义,信号原理以及RTK在多传感器融合中的使用方法

【SLAM】GNSS的定义&#xff0c;信号原理以及在多传感器融合中的使用方法 1. GNSS的定义2. GNSS信号原理3. RTK - Real Time Kinematic4。 如何使用RTK做融合和优化 1. GNSS的定义 GPS&#xff08;Global Positioning System&#xff09;和GNSS&#xff08;Global Navigation …

Ubuntu22.04安装colmap

首先上这里查看自己电脑GPU的CMAKE_CUDA_ARCHITECTURES 终端输入以下内容安装预先的前置依赖 sudo apt-get install \git cmake ninja-build build-essential \libboost-program-options-dev libboost-filesystem-dev \libboost-graph-dev libboost-system-dev libboost-tes…

【操作系统存储篇】操作系统的设备管理

目录 一、广义的IO设备 分类 按使用特性分类 按信息交换的单位分类 按设备的共享属性分类 按传输速率分类 二、IO设备的缓冲区 三、SPOOLing技术 一、广义的IO设备 输入设备&#xff1a;对CPU而言&#xff0c;凡是对CPU进行数据输入的。 输出设备&#xff1a;对CPU而…

深度解析:基于离线开发的数据仓库转型落地案例

在当今这个数据驱动的时代&#xff0c;各行各业都正经历着前所未有的变革。伴随技术的飞速发展&#xff0c;数据仓库作为企业数据管理与分析的核心&#xff0c;如何更好地发挥作用&#xff0c;助力企业保持业务的敏捷性与成本效益&#xff0c;成为大家关心的焦点问题。本文将通…

vue使用html2Canvas导出图片 input文字向上偏移

vue使用html2Canvas导出图片 input文字向上偏移 图中 用的是element的输入框 行高 32px,经常测试 你使用原生的input 还是会出现偏移。 解决方法&#xff1a;修改css样式 1.怎么实现导出 网上随便找很多 2.在第一步 获取你要导出的元素id 克隆后 修改他的样式或者 你直接在你需…

web渗透:SSRF漏洞

SSRF漏洞的原理 SSRF&#xff08;Server-Side Request Forgery&#xff0c;服务器端请求伪造&#xff09;是一种安全漏洞&#xff0c;它允许攻击者构造请求&#xff0c;由服务端发起&#xff0c;从而访问服务端无法直接访问的内部或外部资源。这种漏洞通常发生在应用程序允许用…

v$session_longops监控 PDB clone 进度

How to Monitor PDB Clone / Move On Create Pluggable Database with COPY Clause Statement Execution (Doc ID 2866302.1)​编辑To Bottom In this Document Goal Solution References APPLIES TO: Oracle Database - Enterprise Edition - Version 19.14.1.0.0 and later…

leetcode:908. 最小差值 I(python3解法)

难度&#xff1a;简单 给你一个整数数组 nums&#xff0c;和一个整数 k 。 在一个操作中&#xff0c;您可以选择 0 < i < nums.length 的任何索引 i 。将 nums[i] 改为 nums[i] x &#xff0c;其中 x 是一个范围为 [-k, k] 的整数。对于每个索引 i &#xff0c;最多 只能…

【赛题已出】2024数学建模国赛A-E题已发布

2024年高教社杯全国大学生数学建模各题赛题已发布&#xff01; A题 B题 C题 D题 E题

Linux开源监控工具netdata

Netdata 是一个免费、开源、实时、专业的服务器监控工具&#xff0c;它以可视化的形式实时展现监控主机的性能变化&#xff0c;提供了一个交互式 Web 界面来查看您的服务器指标。它可以帮助我们了解监控主机的系统或应用程序中正在发生的事情以及刚刚发生的事情&#xff0c;并且…