最近的项目中,发现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
数据库
的例子。您可以根据自己的需求进行更改和扩展。