Je rencontre un comportement étrange. J'ai un programme Java qui écrit en permanence des données dans une table MySQL en utilisant des instructions préparées et des insertions par lots. Si un autre processus émet un LOCK TABLES t WRITE
sur la même table et le libère peu après (après quelques minutes), le programme Java continue comme prévu. Cependant, lorsque le verrouillage dure plus longtemps (plus de 30 minutes), le programme Java perd la connexion et ne continue pas. Après 2 heures, il échoue avec un échec de liaison de communication. L'instruction d'insertion en attente pendant le verrouillage de la table est exécutée après la libération du verrou, mais la connexion a été supprimée par la suite.Échec de la liaison de communication vers MySQL pendant les longs LOCK TABLES
Voici les détails:
- il arrive sur les deux 5.0.51a MySQL et 5.1.66
- J'utilise le plus récent pilote JDBC mysql-connector-5.1.25-bin.jar
- le
wait_timeout
est réglé à 28800 (8 heures) - la trace de pile de la défaillance de la liaison de communication et le programme Java sont donnés ci-
Est-ce que quelqu'un sait ce qui se passe ici? Y a-t-il des délais d'attente que je dois définir/augmenter?
L'exception levée au bout de deux heures:
Exception in thread "main" java.sql.BatchUpdateException: Communications link failure
The last packet successfully received from the server was 7.260.436 milliseconds ago. The last packet sent successfully to the server was 7.210.431 milliseconds ago.
at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1836)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1456)
at com.mysql.jdbc.CallableStatement.executeBatch(CallableStatement.java:2499)
at main.LockTest.main(LockTest.java:26)
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 7.260.436 milliseconds ago. The last packet sent successfully to the server was 7.210.431 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1121)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3670)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3559)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4110)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1792)
... 3 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114)
at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161)
at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189)
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3116)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3570)
... 13 more
Le programme complet de Java:
package main;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
public class LockTest {
private static final String CONNECTION_PATTERN = "jdbc:mysql://%s/?user=%s&password=%s"
+ "&autoReconnect=true&rewriteBatchedStatements=true&characterEncoding=utf8";
private static final String QUERY = "INSERT INTO test.lock_test (random_text) VALUES (?)";
public static void main(String[] args) throws SQLException, InterruptedException {
Connection con = DriverManager.getConnection(String.format(CONNECTION_PATTERN, "host", "user", "pw"));
PreparedStatement ps = con.prepareCall(QUERY);
int i = 0;
while (true) {
i++;
ps.setString(1, Long.toString(System.currentTimeMillis()));
ps.addBatch();
if (i % 10 == 0) {
ps.executeBatch();
System.out.println(new Date() + ": inserting 10 rows");
}
Thread.sleep(5000);
}
}
}
Je ne peux pas modifier le contenu de mon fichier keep_current 'tcp_keepalive_time "E667: Fsynch a échoué' en utilisant' vi' Je devais le faire comme ceci: 'root @ sd-53310:/home/ocatelin # echo 60 | sudo dd de =/proc/sys/net/ipv4/tcp_keepalive_time 0 + 1 enregistrements lus 0 + 1 enregistrements écrits 3 octets (3 B) copiés, 2,4948e-05 s, 120 kB/s root @ sd -53310:/home/ocatelin # cat/proc/sys/net/ipv4/tcp_keepalive_time 60' – Stephane