添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
幸福的眼镜  ·  linux ...·  2 月前    · 

最近的项目中,发现Mysql数据库在8个小时内,没有请求时,会自动断开连接,这是MySQL服务器的问题。

原因: The last packet successfully received from the server was 1,836,166 milliseconds ago.  The last packet sent successfully to the server was 29,134 milliseconds ago.


MySQL服务器默认的“wait_timeout”是28800秒即8小时,意味着如果一个连接的空闲时间超过8个小时,MySQL将自动断开该连接,

而连接池却认为该连接还是有效的(因为并未校验连接的有效性),当应用申请使用该连接时,就会导致上面的报错。


解决方案:
数据库连接如果空闲时,进行有效性验证。(如果使用连接池,配置几个属性即可)

<!-- 解决数据库8小时内无请求自动断开,连接失败问题 -->
    <property name="testOnBorrow" value="true"></property>
    <property name="testOnReturn" value="true"></property>
    <property name="testWhileIdle" value="true"></property>
    <property name="validationQuery" value="SELECT 1 FROM DUAL"></property>

Oracle数据库:SELECT 1 FROM DUAL

SqlServer数据库:SELECT 1

下面以DBCP连接池举例——

(其他连接池应该也都有以下属性,可以查看文档或源码),下图是我的项目的连接池的源码举例:



在DBCP连接池中有以下几个属性:


testOnBorrow、testOnReturn、testWhileIdle ,他们的意思是当是取得连接、返回连接或连接空闲时是否进行有效性验证(即是否还和数据库连通的),默认都为false。所以当数据库连接因为某种原因断掉后,再从连接池中取得的连接,实际上可能是无效的连接了,所以,为了确保取得的连接是有效的,可以把把这些属性设为true。当进行校验时,需要另一个参数:validationQuery,对oracle来说,可以是:SELECT COUNT(*) FROM DUAL,实际上就是个简单的SQL语句,验证时,就是把这个SQL语句在数据库上跑一下而已,如果连接正常的,当然就有结果返回了。

然后 minEvictableIdleTimeMillis 配合 timeBetweenEvictionRunsMillis ,每过timeBetweenEvictionRunsMillis秒对连接池进行一次检测,将对象闲置时间超过minEvictableIdleTimeMillis秒的对象进行销毁,创建新的对象来取代。这样就能保证时刻都有正常的连接池对象存在。

还有其他的一些参数,可以参考源代码。
部分参数简要说明:
removeAbandoned :是否自动回收超时连接
removeAbandonedTimeout:超时时间(以秒数为单位)
removeAbandoned=true那么在getNumActive()快要到getMaxActive()的时候,系统会进行无效的Connection的回收,回收的Connection为removeAbandonedTimeout(默认300秒)中设置的秒数后没有使用的Connection
logAbandoned:logAbandoned=true的话,将会在回收事件后,在log中打印出回收Connection的错误信息,包括在哪个地方用了Connection却忘记关闭了,在调试的时候很有用。
maxWait:超时等待时间以毫秒为单位
maxIdle:最大空闲连接
minIdle:最小空闲连接
maxActive:最大连接数
testOnBorrow、testOnReturn、testWhileIdle、validationQuery:上面有介绍
另外很重要的一点是每次连接使用完了不要忘了调用connection.close()使连接返回到连接池

解决这个问题的办法有三种: 1. 增加 MySQL 的 wait_timeout 属性的值。 修改 /etc/ mysql /my.cnf文件,在 [ mysql d] 节中设置: # Set a connection to wait 8hours in idle status. wait_timeout =86400 相关参数,红色部分 mysql > show variables like ‘%timeout%’; +————————–+——-+ | Variable_name | Value | +————————–+——-+ | connect_timeout | 5 | | delayed_i
专家解答: MySQL 是一个小型关系型 数据库 管理系统,由于 MySQL 体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了 MySQL 作为网站 数据库 。   关于mysq
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:撤销:Ctrl/Command + Z 重做:Ctrl/Command + Y 加粗:Ctrl/Command + B 斜体:Ctrl/Command + I 标题:Ctrl/Command + S
最近做的一个JavaWeb项目,持久层用SpringJDBC+DBCP+ MySQL 。一开始只配置了DBCP的一些常用参数,没有注意对空闲 连接 的检查和回收。项目部署在tomcat后,刚开始使用没用问题。第二天再试图登录时,发生了报错: HTTP Status 500 - Request processing failed; nested exception is org.springfr...
mysql 在启动后,如果一段时间内没有活动,那么将 自动 关闭该 连接 。这段时间,默认为8 小时 。在spring+hibernate中解决该问题,应该使用proxool这个 连接 池来代替DBCP的 连接 池。因为DBCP 连接 池没有 自动 重连功能。修改applicationContext.xml: <bean id="dataSource" class="org.logicalco...
之前就遇到过这种 mysql 创建链接8 小时 未访问 断开 的问题。当时解决了,但是没有记录。结果今天部署一个自己的项目又出现了这种问题,所以这次记录下来,防止以后再遇到。 前提:后台使用的是jdbc进行的 连接 。 问题排查: 部署服务后,由于使用人数不多,所以 mysql 的访问比较少。经过了一晚上之后,在访问就提示如下的错误: com. mysql .jdbc.Communication***ception: Communications link failure due to underlying
要 连接 MySQL 数据库 ,您需要使用PHP的 MySQL 扩展程序。在PHP 8中, MySQL 扩展已经被移除了,取而代之的是 mysql i和PDO扩展。这里我们演示使用 mysql i扩展 连接 MySQL 数据库 的方法。 1. 首先,您需要安装并启动 MySQL 服务器,并创建一个 数据库 和一个用户,以便您可以在PHP中使用它们。 2. 在PHP中,您可以使用 mysql i扩展来 连接 MySQL 数据库 。以下是一个简单的示例: ```php // 数据库 连接 参数 $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "database_name"; // 创建 连接 $conn = new mysql i($servername, $username, $password, $dbname); // 检查 连接 是否成功 if ($conn->connect_error) { die(" 连接 失败: " . $conn->connect_error); } else { echo " 连接 成功!"; 在此示例中,我们使用了 mysql i构造函数来创建一个 连接 对象,并传递了 MySQL 服务器的 连接 参数。如果 连接 失败,我们使用die()函数打印错误信息并停止脚本的执行。否则,我们将打印“ 连接 成功!”消息。 3. 连接 成功后,您可以使用 mysql i对象的方法来执行各种操作,例如查询、插入、更新和删除数据。以下是一个简单的示例: ```php // 查询数据 $sql = "SELECT * FROM table_name"; $result = $conn->query($sql); // 输出查询结果 if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { echo "id: " . $row["id"]. " - Name: " . $row["name"]. "<br>"; } else { echo "0 结果"; // 关闭 连接 $conn->close(); 在此示例中,我们使用 mysql i的query()方法执行一个查询,并使用fetch_assoc()方法从结果集中获取每一行的数据。最后,我们关闭 连接 对象。 这是一个简单的PHP 8 连接 MySQL 数据库 的例子。您可以根据自己的需求进行更改和扩展。