简体   繁体   中英

Could not create connection to database server after multiple successful connections

I need to analyze the entries in a mysql table and update them according to the respective result.
For this I have written a Java program that goes through a list of IDs, queries the database, analyzes the returned rows and then writes a Update sql-command in a file.

public static void main(String[] args) {
    Path inputFile, outFile;
    MysqlDataSource dataSource = new MysqlDataSource();
    dataSource.setPassword(pass);
    dataSource.setUser(user);
    dataSource.setServerName(server);
    dataSource.setDatabaseName(db);
    try {
        dataSource.setServerTimezone("UTC");
    } catch (SQLException e) {
        System.out.println("Error while setting timezone of server");
        System.out.println(e.getMessage());
        return;
    }
    try {
        dataSource.setAutoReconnect(true);
        dataSource.setAutoReconnectForPools(true);
    } catch (SQLException e) {
        System.out.println("Error while setting auoreconnect");
        System.out.println(e.getMessage());
        return;
    }
    List<String> IDList = readList(inputFile);
    try {
        PrintWriter pw = new PrintWriter(Files.newBufferedWriter(outFile));
        for(int i = 0; i < IDList.size(); i++) {
            try {
                findConsequences(IDList.get(i), dataSource, pw);
            } catch (IOException | SQLException e) {
                System.out.println("Error while executing query (find consequences for ID " + IDList.get(i) + ")");
                e.printStackTrace();                    
                System.out.println(e.getMessage());
                return;
            }
        }
        pw.close();
    }
    catch(IOException e) {
        System.out.println("Error while writing to file");
        System.out.println(e.getMessage());
        return;
    }
}
private static void findConsequences(String ID, MysqlDataSource dataSource, PrintWriter pw) throws IOException, SQLException{
    List<Result> resultList = new ArrayList<>();
    String query = "Select * from table_bla where Nr = '" + ID + "';";
    Connection conn;
    Statement stmt;
    ResultSet rs;
    ResultSetMetaData rsmd;
    conn = dataSource.getConnection();
    stmt = conn.createStatement();
    rs = stmt.executeQuery(query);
    rsmd = rs.getMetaData();
    int columnsNumber = rsmd.getColumnCount();
    String[] tmpArray = new String[columnsNumber];
    while (rs.next()) {
        for (int i = 1; i <= columnsNumber; i++) {
            tmpArray[i-1] = rs.getString(i) == null ? "" : rs.getString(i);
        }
        resultList.add(new Result(tmpArray));
    }
    rs.close();
    stmt.close();
    conn.close();
    //Analyze ....
    pw.println("Update table_bla set ..."); 
}

This works for about ~45000 IDs. Then the program crashes with the following exception

Error while executing query (find consequences for ID 1057599046)
java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
        at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:905)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:830)
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455)
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)
        at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:402)
        at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:125)
        at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:110)
        at project.AddConsequences.findConsequences(AddConsequences.java:142)
        at project.AddConsequences.main(AddConsequences.java:83)
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
        at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
        at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91)
        at com.mysql.cj.NativeSession.connect(NativeSession.java:152)
        at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:849)
        ... 9 more
Caused by: java.net.NoRouteToHostException: Die angeforderte Adresse kann nicht zugewiesen werden (Address not available)
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:589)
        at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155)
        at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65)
        ... 11 more
Could not create connection to database server. Attempted reconnect 3 times. Giving up.

Considering that it worked for all IDs before I don't understand why it suddenly can't create the connection. If I change my code so that it starts with the list shortly before the ID where it crashed it will again do about 40000-50000 entries and crash with the same error.
A search only brough results for cases where no connection at all could be established which is not the case here.
OS : Ubuntu 16.04
MySQL : 5.7.26
JDBC driver : 8.0.16


After moving the Connection and Statement object outside the function the following error occurred after about the same number of IDs

Error while executing query (find consequences for ID 1057626409)
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
        at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835)
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455)
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)
        at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:402)
        at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:125)
        at com.mysql.cj.jdbc.MysqlDataSource.getConnection(MysqlDataSource.java:110)
        at project.AddConsequences.main(AddConsequences.java:82)
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
        at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
        at com.mysql.cj.protocol.a.NativeProtocol.readMessage(NativeProtocol.java:562)
        at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:732)
        at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:709)
        at com.mysql.cj.protocol.a.NativeProtocol.checkErrorMessage(NativeProtocol.java:132)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:540)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:202)
        at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1452)
        at com.mysql.cj.NativeSession.connect(NativeSession.java:165)
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:955)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825)
        ... 7 more
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
        at com.mysql.cj.protocol.FullReadInputStream.readFully(FullReadInputStream.java:67)
        at com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:63)
        at com.mysql.cj.protocol.a.SimplePacketReader.readHeader(SimplePacketReader.java:45)
        at com.mysql.cj.protocol.a.NativeProtocol.readMessage(NativeProtocol.java:556)
        ... 16 more
Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.

The problem seemed to be related to the amount of objects I created. As far as I could tell since I created a new Connection and Statement object for each ID I wasted too much memory and the GC had to run for longer times using much CPU and stopping my program in its execution. That seems to cause those connection errors.
After changing my program so that it only uses one Connection/Statement it ran through without problems. Additionally I used c3p0 now as a pool manager but that was probably not necessary.

public static void main(String[] args) {
    Path inputFile, outFile;
    ComboPooledDataSource cpds = new ComboPooledDataSource();
    cpds.setJdbcUrl("jdbc:mysql://localhost/db?autoReconnect=true&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC");
    cpds.setUser(user);
    cpds.setPassword(pass);
    cpds.setInitialPoolSize(5);
    cpds.setMinPoolSize(5);
    cpds.setAcquireIncrement(5);
    cpds.setMaxPoolSize(20);
    List<String> IDList = readList(inputFile);
    try {
        Connection conn;
        conn = cpds.getConnection();
        PreparedStatement stmt = conn.prepareStatement("Select * from table_bla where Nr = ?;");
        PrintWriter pw = new PrintWriter(Files.newBufferedWriter(outFile));
        for(int i = 0; i < IDList.size(); i++) {
            try {
                stmt.setString(1, IDList.get(i));
                findConsequences(stmt, pw);
            } catch (IOException | SQLException e) {
                System.out.println("Error while executing query (find consequences for ID " + IDList.get(i) + ")");
                e.printStackTrace();                    
                System.out.println(e.getMessage());
                return;
            }
        }
        pw.close();
        stmt.close();
        conn.close();
    }
    catch(IOException | SQLException e) {
        System.out.println("Error while writing to file");
        System.out.println(e.getMessage());
        return;
    }
}
private static void findConsequences(PreparedStatement stmt, PrintWriter pw) throws IOException, SQLException{
    List<Result> resultList = new ArrayList<>();
    ResultSet rs;
    ResultSetMetaData rsmd;
    rs = stmt.executeQuery();
    rsmd = rs.getMetaData();
    int columnsNumber = rsmd.getColumnCount();
    String[] tmpArray = new String[columnsNumber];
    while (rs.next()) {
        for (int i = 1; i <= columnsNumber; i++) {
            tmpArray[i-1] = rs.getString(i) == null ? "" : rs.getString(i);
        }
        resultList.add(new Result(tmpArray));
    }
    rs.close();
    //Analyze ....
    pw.println("Update table_bla set ..."); 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM