SQL Server传输层间歇性错误:诊断与日志排查技术问询
间歇性SQL Server传输层错误排查问题
在使用SQL Server Management Studio (SSMS) 19.0.2版本执行以下T-SQL查询时,出现间歇性传输层错误:
set nocount on BEGIN TRY select SD.OBSVALUE 'ServiceDate' ,year(SD.OBSVALUE) 'SD_Year' ,month(SD.OBSVALUE) 'SD_Month' ,SD.SDID ,SD.USRID ,SD.PID from OBS SD left join DOCUMENT D on SD.SDID=D.SDID where SD.HDID = 1000086 and SD.USRID not in (select Id from cusKnoxExcludeRecords where IdType = 'UsrId') and SD.PID not in (select Id from cusKnoxExcludeRecords where IdType = 'PId') END TRY BEGIN CATCH print N'An error has occurred.' SELECT SUSER_SNAME(), ERROR_NUMBER(), ERROR_STATE(), ERROR_SEVERITY(), ERROR_LINE(), ERROR_PROCEDURE(), ERROR_MESSAGE(), GETDATE() END CATCH
该错误呈间歇性,同一查询有时正常运行,有时触发传输层错误,且CATCH块从未捕获到该错误,错误信息如下:
Msg 1236, Level 20, State 0, Line 0 A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The network connection was aborted by the local system.)
目前已排查SQL Server错误日志(路径:C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\LOG\)、事件查看器、SQL动态管理视图、SQL Server管理报告,但均未找到相关错误记录;已通过Ping、Ping Plotter排查网络,更换网线并检查网卡,未发现明显问题。
技术问题
- 是否有现成流程可精准定位传输层错误(或连接问题)的原因?
- 服务器或工作站上是否有记录间歇性传输层错误的有效数据?
- 能否在.NET应用中捕获并记录传输层错误?
问题解答
1. 精准定位传输层错误的现成流程
- 隔离测试排查:
- 在SQL Server本地执行查询,排除客户端侧网络问题;用
sqlcmd等轻量工具替代SSMS执行,排除SSMS自身的兼容性或资源占用问题。 - 限制查询结果集大小(比如加
TOP 1000),验证错误是否与大结果集传输相关。
- 在SQL Server本地执行查询,排除客户端侧网络问题;用
- 抓包分析:
- 用Wireshark在客户端和服务器同时抓TCP包,过滤SQL Server默认端口1433的流量,错误触发时分析包的丢失、RST重置或异常断开情况,定位是客户端主动断开还是服务器端、中间网络设备的问题。
- 驱动与版本验证:
- 检查SSMS使用的SQL Server驱动版本,尝试更新到最新版;测试不同驱动(ODBC/OLEDB)的连接效果。
2. 记录间歇性传输层错误的有效数据
- 客户端侧:
- 启用ODBC驱动跟踪:在ODBC数据源管理器中,为目标SQL Server数据源开启跟踪,记录驱动与服务器通信的全流程日志,包括连接建立、查询执行、结果传输的每一步细节。
- 检查Windows系统日志:在“事件查看器-系统日志”中,筛选来源为
TCPIP的事件,查找Event ID 4227(TCP连接数超出限制)、4199(TCP端口耗尽)等与连接中断相关的底层错误。
- 服务器侧:
- 开启SQL Server连接审核:在SQL Server管理控制台的“安全性-审核”中,创建审核规则记录所有连接的建立与断开事件,包括异常断开的时间和会话信息。
- 性能计数器监控:用Windows性能监视器跟踪
SQL Server:General Statistics\User Connections、TCPIP:Segments Retransmitted/sec、SQL Server:Network Bytes Sent/sec等计数器,观察错误出现时的指标波动。
3. .NET应用中捕获并记录传输层错误
可以捕获,这类错误属于SqlException,错误号通常为1236,需在数据库操作的全流程中加入try-catch逻辑:
try { using (SqlConnection conn = new SqlConnection("你的连接字符串(需脱敏)")) { conn.Open(); using (SqlCommand cmd = new SqlCommand("目标查询语句", conn)) { using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { // 处理查询结果 } } } } } catch (SqlException ex) { if (ex.Number == 1236) { // 记录错误详情:错误信息、发生时间、会话标识等 // 示例日志记录逻辑 File.AppendAllText("sql_transport_errors.log", $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 传输层错误:{ex.Message},错误号:{ex.Number}\r\n"); } else { // 抛出其他SQL错误或做对应处理 throw; } }
注意:这类错误可能在ExecuteReader、ExecuteNonQuery或读取数据的reader.Read()阶段触发,需确保所有数据库操作都被try-catch覆盖。
内容的提问来源于stack exchange,提问作者Doug Kimzey
相关产品推荐
相关产品推荐

