gpt4 book ai didi

linux - 从Linux到MS SQL Server 2008的JDBC连接在40秒后超时

转载 作者:IT王子 更新时间:2023-10-29 01:17:36 26 4
gpt4 key购买 nike

[查看底部的更新]

我正在使用JDBC从运行带有2.6.32-32-server内核的Ubuntu 10.04 LTS的计算机上的Windows 2008 R2计算机上的SQL Server 2008 R2运行语句。我正在使用适用于Ubuntu的当前Sun Java 6构建版(sun-java6-jdk 6.24-1build0.10.04.1)和MS的当前JDBC 3.0驱动程序(sqljdbc_3.0.1301.101_enu)。

当一条语句完成的时间超过40秒且不返回ResultSet时(例如'stmt.executeUpdate(“SELECT * INTO BAR FROM FOO”)'),程序将通过连接重置终止:

Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1352)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1339)
at com.microsoft.sqlserver.jdbc.TDSChannel.read(IOBuffer.java:1654)
at com.microsoft.sqlserver.jdbc.TDSReader.readPacket(IOBuffer.java:3694)
at com.microsoft.sqlserver.jdbc.TDSCommand.startResponse(IOBuffer.java:5022)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(SQLServerStatement.java:773)
at com.microsoft.sqlserver.jdbc.SQLServerStatement$StmtExecCmd.doExecute(SQLServerStatement.java:676)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4575)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1400)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:179)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:154)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeUpdate(SQLServerStatement.java:633)
at TestTimeout.main(TestTimeout.java:42)

如果我的陈述式确实传回ResultSet(例如'ResultSet res = stmt.executeQuery(“SELECT * FROM FOO”)'),则连线不会超时。

当我在Win2003R2上运行相同的语句而不针对SQL2005中的数据库副本返回ResultSet时,该语句完成且未在40秒时重置连接。

我启用了日志记录功能,并比较了未完成的SQL2005语句和未完成的SQL2005语句的日志,它们与2008年查询中的连接重置消息一样,逐行等效;看到在12:54:47 PM的那一行:
Jun 6, 2011 12:54:07 PM com.microsoft.sqlserver.jdbc.TDSCommand onRequestComplete
FINEST: TDSCommand@7ac2b2f6 (SQLServerStatement:1 executeXXX): request complete
Jun 6, 2011 12:54:07 PM com.microsoft.sqlserver.jdbc.TDSCommand startResponse
FINEST: TDSCommand@7ac2b2f6 (SQLServerStatement:1 executeXXX): Reading response...
Jun 6, 2011 12:54:47 PM com.microsoft.sqlserver.jdbc.TDSChannel read
FINE: TDSChannel (ConnectionID:1) read failed:Connection reset
Jun 6, 2011 12:54:47 PM com.microsoft.sqlserver.jdbc.SQLServerException logException
FINE: *** SQLException:ConnectionID:1 com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset Connection reset
Jun 6, 2011 12:54:47 PM com.microsoft.sqlserver.jdbc.SQLServerException logException
FINE: com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1352)com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1339)com.microsoft.sqlserver.jdbc.TDSChannel.read(IOBuffer.java:1654)com.microsoft.sqlserver.jdbc.TDSReader.readPacket(IOBuffer.java:3694)com.microsoft.sqlserver.jdbc.TDSCommand.startResponse(IOBuffer.java:5022)com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(SQLServerStatement.java:773)com.microsoft.sqlserver.jdbc.SQLServerStatement$StmtExecCmd.doExecute(SQLServerStatement.java:676)com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4575)com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1400)com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:179)com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:154)com.microsoft.sqlserver.jdbc.SQLServerStatement.executeUpdate(SQLServerStatement.java:633)TestTimeout.main(TestTimeout.java:42)
[...]

以下是针对2005数据库的语句中对应的行:
Jun 6, 2011 2:02:20 PM com.microsoft.sqlserver.jdbc.TDSCommand onRequestComplete
FINEST: TDSCommand@4737371 (SQLServerStatement:1 executeXXX): request complete
Jun 6, 2011 2:02:20 PM com.microsoft.sqlserver.jdbc.TDSCommand startResponse
FINEST: TDSCommand@4737371 (SQLServerStatement:1 executeXXX): Reading response...
Jun 6, 2011 2:02:57 PM com.microsoft.sqlserver.jdbc.TDSChannel logPacket
FINEST: /XXX.XXX.XXX.XXX:60091 SPID:73 TDSReader@6 (ConnectionID:1) received Packet:1 (13 bytes)
XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX .....I..........
XX XX XX XX XX .....
Jun 6, 2011 2:02:57 PM com.microsoft.sqlserver.jdbc.TDSCommand onResponseEOM
FINEST: TDSCommand@4737371 (SQLServerStatement:1 executeXXX): disabling interrupts
Jun 6, 2011 2:02:57 PM com.microsoft.sqlserver.jdbc.TDSReader nextPacket
FINEST: TDSReader@6 (ConnectionID:1) Moving to next packet -- unlinking consumed packet
Jun 6, 2011 2:02:57 PM com.microsoft.sqlserver.jdbc.TDSParser parse
FINEST: TDSReader@6 (ConnectionID:1): getNextResult: Processing TDS_DONE (0xFD)
[...]

我使用tcpdump捕获了SQL Server主机和Linux主机之间的所有流量以及所有ICMP流量,并且我注意到,在语句开始执行30秒后,2008和2005服务器都向Linux发送了一个TCP keep-alive数据包。 Linux主机使用ACK确认来自2005服务器的保持事件状态,但在连接到2008服务器时,Linux主机不发送ACK,并且2008服务器在重设保持事件状态之前重传9次(每秒一次)。连接(因此需要40秒的时间直到超时)。现在,我注意到Win2003/SQL2005和Win2008R2/SQL2008R2主机传输的保持事件数据包之间存在差异:较新的OS使用窗口大小为66560的TCP窗口缩放。所以现在我想知道TCP窗口大小是否大于65535导致Linux机器上的iptables或tcp/ip堆栈静默忽略该数据包。但是随后连接中的其他数据包也具有缩放的窗口大小66560,并且Linux服务器会确认它们。日志文件中没有任何内容指示这些数据包被丢弃或引起任何类型的问题。

最后一点:在解决这个问题的过程中,由于更新,我们不得不重启Linux服务器几次,而且两次连接都没有一两天超时地运行。

所以我很困惑,希望你们中的一个可能对我有所帮助。

更新

我发现可以通过在Linux服务器上禁用tcp时间戳来消除连接超时。禁用窗口缩放对这个问题没有影响。追求禁用tcp时间戳的含义对于serverfault.com来说似乎是一个问题,因此,我将看到有关在此迁移该问题的信息。

更新2

比较有效的连接(Win2003/SQL2003)和无效的连接(Win2008R2/SQL2008R2)的数据包跟踪,我注意到Win2003连接的keepalive没有选项(即使它在较早的数据包中使用tcp时间戳记) ,并且断开的连接的keepalive(除非禁用了时间戳)在keepalive中确实具有tcp选项,即时间戳。因此,现在看来,Ubuntu机器对不带tcp选项的keepalive响应,而忽略了带tcp选项的keeplives。这实际上是有关两台主机上的tcp/ip问题的问题。

最终更新
我在Linux网络开发人员列表上提出了这个问题,现在我确信该问题是由于Windows错误导致具有tcp时间戳的tcp keepalive生成错误的校验和(但显然没有其他数据包) 。 See the thread on the netdev list。这个问题应该结束。

最佳答案

事实证明,Win2008发送的带有tcp时间戳记的tcp keepalive带有错误的tcp校验和,这导致Linux主机正确地忽略了它们。这个问题几乎可以肯定是Windows错误,而不是编程或Linux内核问题。参见this thread on the Linux networking dev list

关于linux - 从Linux到MS SQL Server 2008的JDBC连接在40秒后超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6258184/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com