Не удалось создать соединение с сервером базы данных после нескольких успешных соединений - PullRequest
0 голосов
/ 22 июня 2019

Мне нужно проанализировать записи в таблице MySQL и обновить их в соответствии с соответствующим результатом.
Для этого я написал программу на Java, которая просматривает список идентификаторов, запрашивает базу данных, анализирует возвращенные строки и затем записывает в файл команду Update sql.

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 ..."); 
}

Это работает для ~ 45000 идентификаторов. Затем происходит сбой программы со следующим исключением

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.

Учитывая, что он работал для всех идентификаторов, прежде чем я не понимаю, почему он не может создать соединение. Если я изменю свой код так, чтобы он начинался со списка незадолго до идентификатора, в котором произошел сбой, он снова сделает около 40000-50000 записей и завершится с той же ошибкой.
Поиск возможен только в тех случаях, когда соединение вообще не может быть установлено, что здесь не так.
ОС: Ubuntu 16.04
MySQL: 5.7.26
Драйвер JDBC: 8.0.16


После перемещения объекта Connection и Statement за пределы функции произошла следующая ошибка примерно после того же числа идентификаторов

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.

1 Ответ

0 голосов
/ 25 июня 2019

Проблема, похоже, связана с количеством созданных мною объектов.Насколько я могу судить, так как я создал новый объект Connection и Statement для каждого идентификатора, я потратил слишком много памяти, и GC пришлось работать дольше, используя много ЦП и останавливая мою программу при ее выполнении.Кажется, это вызывает эти ошибки соединения.
После изменения моей программы, чтобы она использовала только одно Соединение / Оператор, через который она прошла без проблем.Кроме того, я использовал c3p0 сейчас как менеджер пула, но это, вероятно, не было необходимости.

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 ..."); 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...