处于睡眠状态的mysql连接,但客户端从不接收数据并超时

时间:2014-02-03 12:54:57

标签: mysql

我们有一个用Java编写的重要程序,它与mysql数据库保持连接。从星期一开始,我们的许多客户在启动程序时报告问题,因为它首先从数据库加载一个长客户列表。让我们感到困惑的是,我们在某些计算机上得到了错误,但在其他计算机上却没有,即使在我们自己的办公室也是如此! 会发生什么,调用getCustomers方法。然后我可以在mysql控制台中看到select查询被处理状态为“写入网络”。然后连接在几秒钟后返回“睡眠”状态,通常为5-10-15,具体取决于行数。 在某些计算机上,现在一切正常,但在其他计算机上,即使连接在服务器上恢复到“睡眠”状态,客户端也没有任何反应,直到2分钟后,正常的2分钟超时中止加载并抛出以下异常:

java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:105)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:148)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:176)
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1899)
    at com.mysql.jdbc.MysqlIO.readPacket(MysqlIO.java:481)
    at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:1410)
    at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1133)
    at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:670)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1024)
at pos.LocalDBComm.getCustomers(LocalDBComm.java:4542)

我们已经尝试重新启动mysql服务,禁用avira实时模式等,但似乎没有任何帮助。我们真的陷入困境,并且会对这个错误刚开始发生的原因有所了解,以及为什么它只会影响某些计算机。由于我们在同一个办公室有2台计算机,第一台计算机每次都在工作,而第二台计算机从不工作,我想这也不是因为防火墙设置。只有长查询受到影响,小查询似乎与以前一样有效。

更新: 令人惊讶的是,在这个错误的半天之后,事情突然又开始起作用了。我很困惑,不知道它是如何突然重新开始工作的。 无论如何,第二天它不再工作了!查询只是像以前一样挂起。这真的很奇怪。如果没有人做任何事情,它就会从工作变为无效。

3 个答案:

答案 0 :(得分:0)

MySQL服务器超时可能由于多种原因而发生,但最常发生在通过已关闭的连接向MySQL发送命令时。由于空闲超时,MySQL服务器可能已关闭连接;但是,在大多数情况下,它是由应用程序错误,网络超时问题引起的。

我会查看以下内容

  1. 搜索日志以查看查询失败是否有任何迹象
  2. 检查服务器上的连接

    mysqladmin processlist | grep database-name

  3. 检查您的服务器配置

    的MySQL>显示变量;

  4. 检查数据源以确保连接数正确

    MAX-连接= “100” 分的连接=“5” 非活动超时= “200”

答案 1 :(得分:0)

我们现在已经发布了一种解决方法,它通过使用mysql LIMIT关键字来限制我们的大查询,因此我们一次只能读取5000行。这似乎有效。但是我们已经在无数台计算机上运行了这个程序大约8年,而且从未遇到过这种行为,并且由于使用LIMIT运行12个查询以获得60000行数据只需要大约15秒或更短时间,因此没有理由进行完整查询应该挂起,然后在2分钟后超时,特别是因为查询完成“写入网络”并在几秒钟后进入mysql控制台中的状态“sleep”。为什么它在以前的某些计算机上工作而不在其他计算机上?几乎似乎最合理的解释是,如果数据超过一定大小,查询数据会在某些受感染的计算机上的某些时间被某个小时的NSA或其他公司拦截“analyzis”...

答案 2 :(得分:0)

你可以托盘以保持连接,我找到了这段代码,希望这对你有帮助。

public static final String DATABASE_USER = "user";
public static final String DATABASE_PASSWORD = "password";
public static final String MYSQL_AUTO_RECONNECT = "autoReconnect";
public static final String MYSQL_MAX_RECONNECTS = "maxReconnects";

public static Connection getConnection() throws Exception {
     String driver = "org.gjt.mm.mysql.Driver";

     Class.forName(driver);
     String dbURL = "jdbc:mysql://localhost/tiger";
     String dbUsername = "root";
     String dbPassword = "root";

     java.util.Properties connProperties = new java.util.Properties();
     connProperties.put(DATABASE_USER, dbUsername);
     connProperties.put(DATABASE_PASSWORD, dbPassword);

     connProperties.put(MYSQL_AUTO_RECONNECT, "true");

     connProperties.put(MYSQL_MAX_RECONNECTS, "4");
     return DriverManager.getConnection(dbURL, connProperties);
}