为什么我直接访问mysql数据库时会出现这些随机超时错误

时间:2017-01-26 15:35:55

标签: mysql tomcat mysql-connector

我在同一台机器上安装了Tomcat和Mysql,它最近没有更新,所以我们在Linux上使用Tomcat 7.0.31和MySql 5.0.95。

当用户进行购买时,它由Paypal处理,然后他们联系我们的服务器,我们创建许可证并将其存储在数据库中,但不幸的是,它并不总是有效,如:

  

从服务器成功收到的最后一个数据包是44,533,707   几毫秒之前。成功发送到服务器的最后一个数据包是   44,533,707毫秒之前。比配置的服务器长   'wait_timeout'的值。你应该考虑到期和/或   在您的应用程序中使用前测试连接有效性,增加   服务器配置的客户端超时值,或使用   连接器/ J连接属性'autoReconnect = true'以避免这种情况   问题

但我不认为MySql已关闭,因为我从来没有遇到连接它的问题,错误大约有5%的时间是随机发生的。

Mysql包含两个数据库实例,在我的web.xml文件中有

<resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/jaikoz</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
  <description>DB Connection2</description>
  <res-ref-name>jdbc/songkong</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

并在context.xml中(我更改了用户名和密码)我有

<Context path="/store" privileged="true">
    <Resource name="jdbc/jaikoz" auth="Container" type="javax.sql.DataSource"
              maxActive="-1" maxIdle="-1" maxWait="10000"
              username="usrnm" password="pwd" driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/jaikoz?autoReconnect=true"/>
    <Resource name="jdbc/songkong" auth="Container" type="javax.sql.DataSource"
              maxActive="-1" maxIdle="-1" maxWait="10000"
              username="usernm" password="pwd" driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/songkong?autoReconnect=true"/>
</Context>

此配置也来自我的 Store Web应用程序,我还有一个 jaikoz 和一个 songkong Web应用程序,这些都定义了一个的联系。我不得不介绍“商店”,因为支付提供商需要一个网址才能发送所有成功的付款(无论是来自songkong还是jaikoz)

我想知道是否有两个数据库连接正在破坏或者有两个应用程序定义相同的连接正在打破事情,因为我不认为当我只有jaikoz应用程序时我遇到了这样的问题。

错误说我可以使用AutorReconnect = true,但我已经这样做了。

根据建议显示流程列表并获得以下内容:

mysql> show processlist
    -> ;
+--------+------+-----------------+----------+---------+-------+-------+------------------+
| Id     | User | Host            | db       | Command | Time  | State | Info             |
+--------+------+-----------------+----------+---------+-------+-------+------------------+
| 127681 | paul | localhost:40360 | jaikoz   | Sleep   |     5 |       | NULL             |
| 127682 | paul | localhost:40361 | jaikoz   | Sleep   |     7 |       | NULL             |
| 127683 | paul | localhost:40362 | jaikoz   | Sleep   |    11 |       | NULL             |
| 127684 | paul | localhost:40363 | jaikoz   | Sleep   |     2 |       | NULL             |
| 127685 | paul | localhost:40364 | jaikoz   | Sleep   |    17 |       | NULL             |
| 127754 | paul | localhost:40664 | jaikoz   | Sleep   |    20 |       | NULL             |
| 127755 | paul | localhost:40665 | jaikoz   | Sleep   |     8 |       | NULL             |
| 127756 | paul | localhost:40666 | jaikoz   | Sleep   |    25 |       | NULL             |
| 128444 | paul | localhost:41250 | jaikoz   | Sleep   |    14 |       | NULL             |
| 128445 | paul | localhost:41251 | jaikoz   | Sleep   |    10 |       | NULL             |
| 134807 | paul | localhost:56829 | jaikoz   | Sleep   |   226 |       | NULL             |
| 134849 | paul | localhost:38795 | songkong | Sleep   |   475 |       | NULL             |
| 143552 | paul | localhost:35811 | jaikoz   | Sleep   | 19338 |       | NULL             |
| 145211 | paul | localhost       | jaikoz   | Query   |     0 | NULL  | show processlist |
+--------+------+-----------------+----------+---------+-------+-------+------------------+
14 rows in set (0.00 sec)

也许不应该有那么多Jaikoz过程?

我如何解决这个问题?

已修改

与其他人交谈,因为它只是来自Store Web应用程序的连接失败,并且只在购买时做了任何事情,目前只有几天,这听起来像MySql正在超时连接本身没有告诉jdbc池,所以当尝试通过池使用连接时,我们得到了错误。

我在我的context.xml中添加了testWhileIdle="true"并删除了autoreconnect=true,希望这会在mysql放弃它们之前从池中删除连接。

不幸的是,偶尔会失败,但现在会给出稍微不同的错误消息

JDBC begin transaction failed

2 个答案:

答案 0 :(得分:1)

  • 关闭连接池。
  • 关闭自动重新连接
  • 确保您的代码捕获事务错误,并在必要时重播它们 - 特别是在死锁的情况下。

这些往往是与金融交易完整性有关的问题。

如果没有解决问题,请提供

  • 每秒查询数
  • SHOW VARIABLES LIKE'%timeout';`
  • 事务样本(SQL,请,不是Java)
  • SHOW CREATE TABLE

至于PROCESSLIST ......

  • 我看到一个连接(可能是池)在5秒前执行了一些SQL。
  • 我看到一个连接(可能是池)在19338秒前(5个小时以上)没有做任何事情。
  • 我猜您在过去5小时内不需要超过12个同步连接。
  • 该列表看起来“正常”。

答案 1 :(得分:0)

关键是我需要提供一个validationQuery,以便testForIdle完成验证,因为这样做没有问题。

 <Context path="/store" privileged="true">
            <Resource name="jdbc/myapp" auth="Container" type="javax.sql.DataSource"
                      maxActive="10" maxIdle="10" 
    testWhileIdle="true" validationQuery="select 1" validationQueryTimeout="5"
                      username="usrnm" password="pwd" 
driverClassName="com.mysql.jdbc.Driver" testOnBorrow="true"
                      url="jdbc:mysql://localhost:3306/myapp"/>

        </Context>