我遇到了一些奇怪的行爲。我有一個Java程序,它使用預處理語句和批量插入將數據永久寫入MySQL表。如果其他進程在同一個表上發出LOCK TABLES t WRITE
,並在此後不久(幾分鐘後)釋放它,Java程序會按預期繼續。但是,當鎖定持續較長時間(超過30分鐘)時,Java程序失去連接並且不會繼續。 2小時後,它會因通信鏈路故障而失敗。在表鎖定期間掛起的插入語句在鎖釋放後執行,但之後連接消失。在長時間鎖定表中通信鏈接失敗到MySQL
下面是詳細信息:
- 它的MySQL都和5.0.51a 66年5月1日
- 情況我使用的是最新的JDBC驅動程序使用mysql-connector-5.1.25-bin.jar
- 的
wait_timeout
被設置爲28800(8小時) - 通訊鏈路故障和Java程序的堆棧跟蹤下面給出
有人知道這裏發生了什麼嗎?是否有任何超時需要設置/增加?
兩小時後拋出的異常:
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
完整的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);
}
}
}
我不能使用'vi'來更改我的保存文件'tcp_keepalive_time「E667:Fsynch失敗的內容,我必須這樣做:'root @ sd-53310:/ home/ocatelin#echo 60 | sudo dd =/proc/sys/net/ipv4/tcp_keepalive_time 0 + 1註冊lus 0 + 1註冊表編輯 3字節(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