//可能需要的MySQL 账号命令 //8.0密码问题,可以设置配置: ALTER USER 'test'@'localhost' IDENTIFIED WITH mysql_native_password BY '123'; ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123';
mysql> \s -------------- mysql Ver 8.0.32 for Linux on x86_64 (Source distribution)
Connection id: 9 Current database: test Current user: root@127.0.0.1 SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 8.2.0 MySQL Community Server - GPL Protocol version: 10 Connection: 127.1 via TCP/IP Server characterset: utf8mb4 Db characterset: utf8mb4 Client characterset: utf8mb4 Conn. characterset: utf8mb4 TCP port: 3306 Binary data as: Hexadecimal Uptime: 15 hours 46 min 24 sec
Threads: 2 Questions: 34 Slow queries: 0 Opens: 176 Flush tables: 3 Open tables: 95 Queries per second avg: 0.000
#javac Test.java //编译,需要提前安装JDK //执行,需要下载jdbc jar驱动,见附录,还需要有一个数据库,随便建个表,或者查里面自带的库都可以 #java -cp .:./mysql-connector-java-5.1.45.jar Test "jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useServerPrepStmts=true&cachePrepStmts=true&connectTimeout=500&socketTimeout=1700" root 123 "select sleep(10), id from sbtest1 where id= ?" 100 //设置了1.7秒超时查询还不返回的话业务代码报错,堆栈如下: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure //连接异常
The last packet successfully received from the server was 1,701(1700ms) milliseconds ago. The last packet sent successfully to the server was 1,701 milliseconds ago. at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3559) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3459) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3900) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1283) at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:783) at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1966) at Test.main(Test.java:30) Caused by: java.net.SocketTimeoutException: Read timed out // 异常,JDBC Driver 会调 Socket.setSoTimeout 来设置超时时间给 timeRead使用 at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:284) //timedRead 函数可以设置读取超时(timeout) at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:310) at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:351) at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:802) at java.base/java.net.Socket$SocketInputStream.read(Socket.java:919) at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:101) at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:144) at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:174) at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3008) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3469) ... 7 more
java -cp .:./mysql-connector-java-5.1.45.jar Test "jdbc:mysql://gf1:3307/test?useSSL=false&useServerPrepStmts=true&cachePrepStmts=true&connectTimeout=500&socketTimeout=1500&netTimeoutForStreamingResults=0" root 123 "select *, id from streaming " 5000
timestamp:1734084150084 id:1 count:60798 timestamp:1734084150084 id:2 count:60799 timestamp:1734084151594 //读到 60799行后,MySQL 卡了,读卡了 1500ms 后报错 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Application was streaming results when the connection failed. Consider raising value of 'net_write_timeout' on the server. at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3559) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3459) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3900) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:873) at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1996) at com.mysql.jdbc.RowDataDynamic.nextRecord(RowDataDynamic.java:374) at com.mysql.jdbc.RowDataDynamic.next(RowDataDynamic.java:354) at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:6312) at Test.main(Test.java:38) Caused by: java.net.SocketTimeoutException: Read timed out at java.base/sun.nio.ch.NioSocketImpl.timedRead(NioSocketImpl.java:288) at java.base/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:314) at java.base/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:355) at java.base/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:808) at java.base/java.net.Socket$SocketInputStream.read(Socket.java:966) at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:101) at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:144) at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:174) at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3008) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3469) ... 8 more
"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f6a5c0db000 nid=0x109d8e in Object.wait() [0x00007f6a60a75000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000f6b08d90> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x00000000f6b08d90> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"main" #1 prio=5 os_prio=0 tid=0x00007f6a5c04b000 nid=0x109d8a runnable [0x00007f6a638e9000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:101) at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:144) at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:174) - locked <0x00000000f6b71370> (a com.mysql.jdbc.util.ReadAheadInputStream) at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3008) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3469) at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3459) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3900) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1283) - locked <0x00000000f6b0a228> (a com.mysql.jdbc.JDBC4Connection) at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:783) - locked <0x00000000f6b0a228> (a com.mysql.jdbc.JDBC4Connection) at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1966) - locked <0x00000000f6b0a228> (a com.mysql.jdbc.JDBC4Connection) at Test.main(Test.java:30)
# mysql -h127.1 -uroot -p123 Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select sleep(1.4); +------------+ | sleep(1.4) | +------------+ | 0 | +------------+ 1 row in set (1.40 sec)
为什么不用mysql client做这个SocketTimeout的实验:mysql似乎没有SocketTimeout这个参数: mysql --help |grep -i time and reconnecting may take a longer time. Disable with --connect-timeout=# Number of seconds before connection timeout. connect-timeout 0
# tshark -i lo -Y "tcp.port==59636" -T fields -e frame.number -e frame.time_delta -e tcp.srcport -e tcp.dstport -e _ws.col.Info -e mysql.query Running as user "root" and group "root". This could be dangerous. Capturing on 'Loopback' // 85 0.000042261 3306 59636 3306 → 59636 [FIN, ACK] Seq=1 Ack=1 Win=512 Len=0 TSval=478849322 TSecr=478831136 92 0.008106470 59636 3306 59636 → 3306 [FIN, ACK] Seq=1 Ack=2 Win=512 Len=0 TSval=478849333 TSecr=478849322 93 0.000008612 3306 59636 3306 → 59636 [ACK] Seq=2 Ack=2 Win=512 Len=0 TSval=478849333 TSecr=478849333
kill mysqld pid
1 2 3 4 5 6 7 8 9
]# tcpdump -i lo port 50436 dropped privs to tcpdump tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
JDBC客户端MySQL服务器初始化阶段建立数据库连接连接成功配置参数socketTimeout=1459msnetTimeoutForStreamingResults=1s设置流式查询setAutoCommit(false)setFetchSize(Integer.MIN_VALUE)执行查询: SELECT * FROM data_table开始准备结果集返回第一批数据开始处理第一条数据Thread.sleep(1500ms)net_write_timeout计时开始(1s)等待客户端处理...1秒后超时关闭连接仍在sleep(1500ms)尝试读取下一条数据连接已关闭抛出CommunicationsExceptionJDBC客户端MySQL服务器