首页 / 资讯中心 / 文章详情

达梦数据库通信异常排查全流程实操指南

达梦数据库通信异常排查全流程实操指南 ★ FEATURED ARTICLE
达梦数据库通信异常排查实操总结从现象到根因再到恢复1. 通信异常到底在说什么先说个扎心的结论达梦数据库的“通信异常”是运维和开发最容易吵架的报错之一。业务方报过来一句“连接数据库报错通信异常”DBA的第一反应通常是“网络又出问题了”但实际排查下来十个通信异常里有五个根本不是网络的问题。作为常年跟达梦打交道的工程师我接到这类工单的第一动作永远是先把错误码和报错场景拿到手再谈其他。达梦数据库是老牌国产关系型数据库默认端口是 5236客户端通过 TCP/IP 与数据库服务端通信。通信过程大致分三个阶段TCP 建连、服务端认证握手、会话建立与数据交互。“通信异常”这个描述性报错贯穿三个阶段都可能出现所以它的定位非常模糊。模糊意味着排查范围大排查范围大意味着容易走弯路。我见过有人对着达梦数据库客户端工具 DIsql 反复重试也见过有人直接重启服务器最后发现是防火墙策略把端口拦了。这种低级问题之所以反复出现是因为大家习惯性地把“通信异常”当作一个独立故障而不是一串需要逐层定位的链路问题。真正有效的思路是把通信异常当成一条链从客户端到服务端逐段拆解先确认是哪一段断了再动手处理。另外还要提醒一点达梦的版本差异会影响报错文本和错误码编号。同一个故障V7 和 V8以及 DM8 的小版本给出的提示可能不同排错时不要死记某个错误码的绝对含义要结合当前版本的官方手册确认。2. 先按顺序排除基础网络问题2.1 从 Ping 和 Telnet 开始不要跳步接到通信异常工单后我习惯按一个固定顺序走先 ping 数据库服务器 IP再 telnet 数据库端口最后再尝试用 DIsql 实际连接。这个顺序看起来简单但很多人会跳步。有人上来就改用 DIsql 重试结果同样报错还是不知道问题在哪一层。Ping 通说明主机层可达Ping 不通要考虑跨网段、禁 ping 策略、服务器掉线等。Telnet 端口通则说明 TCP 层建连成功Telnet 不通则问题大概率在网络层或服务监听层。实际操作时在客户端机器执行ping 192.168.1.100 telnet 192.168.1.100 5236如果 ping 通但 telnet 不通继续在数据库服务器本机执行netstat -an | grep 5236看看 5236 端口是否有 LISTEN 状态。如果没有监听要么实例没起来要么配置的端口不是默认端口。达梦允许在 dm.ini 里把端口改成其他数值有客户曾经为了“安全”把端口改成 15236结果应用连接串还是 5236折腾了一下午。提示telnet 验证很直观但有些 Linux 发行版默认不装 telnet 客户端。可以用nc -vz 192.168.1.100 5236替代效果一样。2.2 防火墙和安全组是重灾区网络链路确认过之后接下来重点看防火墙。Linux 的 iptables/firewalld、云平台的 security group、数据库服务器本机的防护软件任何一个环节都有可能拦掉 5236 端口。我这里有一个印象极深的案例客户的开发和测试环境都正常一到生产环境就报通信异常而且是间歇性的。排查到最后发现是安全组规则只允许了应用服务器网段访问而运维人员在跳板机上想直连数据库自然连不上被误判成数据库故障。检查防火墙时除了看端口是否放通还要看服务端到客户端的回包是否被拦。数据库通信是双向的某些防火墙策略只放行了 SYN 请求却拦掉了回包会导致连接超时。这个比较隐蔽用 tcpdump 抓包能看出来tcpdump -i eth0 host 192.168.1.100 and port 5236抓包后如果看到大量的 SYN 发送但没有 SYN-ACK 回应基本可以确定是防火墙丢包或策略问题。2.3 不要忘记检查 keepalive 和超时参数网络层还有一个容易被忽略的点TCP keepalive。应用和数据库之间的长连接如果长时间没有数据交互中间的网络设备尤其是负载均衡、防火墙可能会把空闲连接断开。此时应用再次发 SQL表现就是“连接已断开”“通信异常”。Linux 默认的 tcp_keepalive_time 是 7200 秒也就是两个小时很多防火墙的空闲会话超时却只有 15 到 30 分钟。这个时间差就是长连接被莫名断开的常见原因。遇到这种场景建议在服务器和客户端上同时调小 keepalive 间隔sysctl -w net.ipv4.tcp_keepalive_time300 sysctl -w net.ipv4.tcp_keepalive_intvl30 sysctl -w net.ipv4.tcp_keepalive_probes5如果是云环境还要检查负载均衡器的连接空闲超时设置很多云产品默认只有几分钟。这里补充一点达梦服务端的COM_TIME_OUT参数控制服务端对通信空闲时间的容忍度我后面会细讲。3. 服务端通信相关配置不要只盯网络3.1 先理解达梦的通信架构网络层排除干净之后再往数据库内部走。达梦的通信架构其实不复杂服务端启动一个监听线程监听配置的端口客户端发起连接后监听线程接收连接完成身份认证然后分配一个会话SESSION处理后续交互。这个过程中任何一环出问题客户端都可能收到通信类报错。比如监听线程异常退出、会话数打满、认证超时、密码错误被拒绝等。关键是有些问题从错误码上看起来像“通信异常”实际却是权限或配置问题。举个例子达梦默认有一个 SYSTEM 级参数叫LOGIN_NUM或类似机制表示允许同时登录的最大会话数。到达上限后新连接会被拒绝。很多人在生产环境遇到“通信异常”时根本想不到去查会话数因为在 Oracle 里这个报错通常是 ORA-00020明明白白告诉你 processes 超了但在达梦这里报错了可能更泛化。3.2 dm.ini 里那些与通信相关的参数达梦数据库的核心配置文件是 dm.ini位于数据目录下。和通信异常相关的关键参数主要有PORT_NUM服务端监听端口默认 5236。COM_TIME_OUT通信超时时间单位是秒默认可能是 60 或更高。SESS_NUM最大会话数受数据库许可证限制。MAX_SESSION_STAT会话状态数。DROP_CONNECT是否允许会话空闲超时断开。这里重点讲COM_TIME_OUT。它控制的是通信空闲超时即一个连接建立后如果长时间没有来往数据包服务端会主动断开。这个参数如果设置得太小应用端稍微有点延迟就会被断开报错就是“通信异常”。我遇到过一套系统应用经常在凌晨报通信异常查下来就是COM_TIME_OUT设置成了 30 秒而应用层连接池的空闲时间设置成了 5 分钟。连接池空置超过 30 秒后服务端主动断开连接池在下次取连接时不知道连接已死直接发给服务端就报错。调整参数需要在 dm.ini 里修改然后重启数据库实例才能生效。实际操作vi $DM_HOME/data/DMSERVER/dm.ini找到COM_TIME_OUT改成合理的值比如 300 或 600再重启 DmServicesystemctl restart DmServiceDMSERVER注意修改 dm.ini 一定要先备份。不同版本参数名和默认值可能有差异修改前用disql执行SELECT * FROM V$PARAMETER WHERE NAME LIKE %TIME_OUT%确认参数名别凭记忆乱改。3.3 连接数打满的排查思路连接数打满导致的通信异常在业务高峰期特别常见。排查方法比较简单用 disql 连接数据库后执行SELECT COUNT(*) FROM V$SESSIONS; SELECT LICENSE_NUM FROM V$LICENSE;如果当前会话数接近许可证上限基本就能确认是这个原因。应急方案有两个一是让业务侧缩减连接池大小二是申请扩展许可证。在 V8 里还可以查V$SESSION的STATE字段定位哪些会话是 idle 状态考虑杀掉空闲连接释放资源。我建议业务侧做连接池配置时把最小空闲连接数调低不要一启动就创建几十上百个连接趴在那里又不用还占着会话数。很多应用默认连接池初始连接数设置得非常高跟数据库的性能完全不匹配这是高峰期通信异常的一个隐藏推手。4. 客户端连接配置与驱动选型4.1 连接串怎么写才不容易出问题达梦 JDBC 连接串的常见格式如下jdbc:dm://192.168.1.100:5236?compatibleModeoracleconnectTimeout3000socketTimeout30000参数connectTimeout控制 TCP 建连超时socketTimeout控制读取数据超时。很多人在连接串里把这两个值都设成 0表示不超时结果应用在数据库故障时表现为长时间卡死线程池被耗尽业务方还以为数据库“通信异常”了。其实不是数据库异常是客户端不会快速失败把故障拖成了雪崩。我建议连接串里显式设置超时时间比如 connectTimeout 设 3 到 5 秒socketTimeout 设 30 到 60 秒具体看业务 SQL 的耗时特点。这样数据库不可用时应用能快速报错不会把所有请求都堵在连接等待上。4.2 驱动版本与数据库版本要匹配达梦的 JDBC 驱动DmJdbcDriver放在安装目录的 drivers/jdbc 下。不同大版本之间驱动不能乱换DM7 的驱动连 DM8 通常没问题但反过来有时会踩坑。我遇到过一种诡异的现象应用用的驱动是几年前发布的旧版本数据库已经升级到 DM8 的小版本平时一切正常但只要 SQL 里带有某些新特性语法就报“通信异常”。抓了两次包才发现是旧驱动在解析新版本返回的字段信息时出错直接断开了连接。这类问题从外表看是通信问题根子却是驱动和数据库版本不兼容。所以建议应用升级时顺便同步升级数据库驱动别觉得“能连上就没问题”。连接正常不代表访问正常驱动解析协议的能力差异会在特定场景下才暴露。4.3 认证与权限问题不要误判成通信问题还有一种容易被误判的场景用户名或密码错误。达梦在认证失败时有的版本会返回明确的账号错误提示有的版本因为安全配置会把错误包装成“通信异常”。遇到这种含糊报错第一件事是检查连接串里的用户名、密码、schema 是否拼写正确。尤其是改了数据库密码但没同步改应用配置的情况特别常见。另外还有一个点达梦默认有LOGIN_ENCRYPT或密码加密相关的参数如果服务端要求加密登录而客户端驱动不支持该加密算法也会表现为连接失败或通信异常。我建议在排查通信异常时顺手在服务端查看系统日志路径通常在$DM_HOME/log/log_****.log或者安装目录下的 log 文件里。服务端日志里会记录详细的连接拒绝原因比客户端报错靠谱得多。5. 实战案例四次典型的通信异常排查过程5.1 案例一主备集群通信中断其实是心跳超时一套达梦主备集群某天监控告警主备状态异常备机一直处于“连接断开”状态。数据库本身能正常访问但从主机到备机的复制通道断了报通信异常。当时第一反应是主备之间的内网有问题但 ping 和 telnet 都正常。查看监控日志发现主备之间的心跳包发送正常可是备机在某个时间点后就不再回包。进一步查 dmwatcher 和 dmmonitor 的日志发现备机日志里有一条“接收到无效的心跳数据包”记录紧接着通信超时。排查到最后问题出在一台交换机上主备机之间的二层链路出现了偶发的高延迟导致心跳包超时被丢弃。数据库服务端的通信超时参数设置过短无法容忍这种毫秒级的瞬时延迟。这个案例给我们的教训是主备集群的心跳网络要跟业务网络隔离并且通信超时的配置要适当放宽否则网络只要抖动几秒集群就认为对方故障触发切换。而且切换后往往还会因为网络残留问题导致双主或脑裂风险这类故障最危险。5.2 案例二端口能 telnet 通应用却连不上接了个工单业务方说“telnet 端口是通的但应用就是连不上报通信异常”。听着很奇怪端口都通了怎么还会失败到现场复现后我直接用 DIsql 连接也报错。再仔细看 telnet 的返回值发现连接立刻被关闭了而不是等在那里不动。这个区别很关键如果服务端监听正常telnet 应该保持连接状态如果立刻断开说明有东西在端口上做了“握手拦截”。后来排查发现这台数据库服务器上跑了安全审计软件它监听在 5236 端口上做代理转发先拦住流量做安全检查再转发给真正的数据库端口。结果是这个软件的逻辑有问题导致转发失败应用端表现就是连接被重置。这种案例提醒大家端口能连通不代表连的就是数据库进程可能是中间有透明代理或安全组件。遇到端口通但连接失败用lsof -i :5236或ss -lntp看看到底是哪个进程在监听确认它是达梦的 dmserver 进程而不是别的干扰进程。5.3 案例三连接数打满后的“假死”数据库看着活着一套报表系统每天早上八点半批量跑数隔三差五出现“通信异常”重启应用就好了但第二天又犯。起初以为是数据库挂了检查后发现数据库进程还活着端口也在监听数据库负载也不高。查到最后才发现是连接数达到上限。报表系统用了连接池初始连接数设了 100最大连接数设了 300但整个数据库的许可会话数上限只有 200。连接池在启动时快速占满连接后续请求全部排队等连接等待时间超过应用侧 socketTimeout 后直接报通信异常。这个案例的解决办法很直接把连接池最大连接数降到 150同时把初始连接数调到 20空闲连接定期回收。调完之后问题再没出现过。特别想强调的一点是连接数问题引发的故障经常被误报成“数据库通信异常”。业务方看到连接失败就归因网络导致排查方向跑偏。DBA 拿到报错时最好多问一句“报错时间点和并发量如何”这个信息能帮我们快速定位是否是资源类问题。5.4 案例四驱动版本太老SQL 执行到一半断连一家长时间稳定运行的系统在升级了达梦数据库小版本之后突然出现偶发“通信异常”。具体表现为一条复杂的分组查询 SQL执行到一半就报连接断开重试后有时能成功有时不能。抓包后发现连接在网络层没有异常断开是数据库主动发了 FIN 包然后在应用侧报错。进一步分析数据库日志发现里面有一条“不支持的协议特性”提示。定位到根因JDBC 驱动版本过旧对新的查询计划信息解析失败触发服务端主动断开连接。解决办法就是升级驱动到与数据库匹配的版本并重新打包部署。之后问题彻底消失。这个案例的教训是升级数据库时驱动升级要同步做。很多团队把升级数据库当成 DBA 的事应用侧不配合升级驱动导致新老版本兼容问题在低峰期不显现一到特定 SQL 或高峰期就爆发。6. 通用排查命令与错误码速查表6.1 一套标准的排查命令走查以下是我在面对通信异常时常用的命令清单按顺序执行基本能定位 90% 的问题层级命令作用预期结果客户端ping 服务器IP验证主机连通性有响应或明确得知禁 ping客户端telnet 服务器IP 5236验证端口连通连接保持不退出客户端nc -vz 服务器IP 5236telnet 替代方案提示 open服务端netstat -an | grep 5236确认监听状态LISTEN服务端lsof -i :5236确认监听进程dmserver 进程服务端ss -lntp查看监听与进程关联dmserver数据库SELECT * FROM V$INSTANCE;确认实例状态OPEN数据库SELECT COUNT(*) FROM V$SESSIONS;确认会话数未达上限数据库SELECT * FROM V$PARAMETER WHERE NAME LIKE %TIME_OUT%;确认通信超时参数参数值合理在实际操作中我会把这些命令整理成一个 shell 脚本接到报错后直接跑一遍能省很多力气。脚本逻辑很简单先测网络连通性再查端口状态最后连数据库查会话数任一环节失败会高亮显示。6.2 常见报错信息与处理建议以下是我在工作中经常遇到的报错提示和对应的处理方向。特别说明达梦版本不同错误码可能存在差异这里只是提供排查方向不是绝对的错误码字典。报错信息常见原因优先排查方向连接失败 / Connection refused服务端未启动或端口错误netstat 查监听Connection reset防火墙拦截或安全组件切断抓包、查防火墙规则通信超时 / timeout网络延迟大、服务端超时参数过小调大COM_TIME_OUT连接被断开 / connection is closed连接池空闲连接被服务端回收调整连接池与超时参数会话数已达上限许可证限制或 SESS_NUM 配置过小查会话数、缩减连接池认证失败密码错误或加密算法不匹配检查连接串、驱动版本这里多提醒一句报错信息里的“用户”和“密码”如果出现身份验证失败字样别一头扎进网络排查。我见过有人对着一个密码错误的问题查了两天防火墙就因为在错误堆栈里看到了“连接”两个字。7. 关于达梦通信异常我的几点实操总结排查达梦数据库通信异常这些年我最大的感受是这类问题不是单一技术点而是横跨网络、操作系统、数据库参数、应用配置的综合性故障。谁技术上最全能、谁能沉住气从底层一层层查起谁就能最快定位问题。我的建议是先建立“链路思维”而不是“报错思维”。看到“通信异常”四个字不要急着想“这是达梦的 bug”而是把问题拆成三层能不能连上、连上后能不能认证、认证后能不能稳定执行。每一层都有对应的检查点逐层排查效率最高。另外做好细节记录非常关键。排查过程中遇到的每次报错、每个时间点、每条命令的输出都可能成为最后定位根因的钥匙。我习惯在排查时开一个新的日志文件把每一步命令和输出都记录下来一是避免反复重复操作二是换班交接时能直接给同事看省得重新讲一遍。最后分享一个小技巧凡是应用层报“通信异常”先让业务方把完整的异常堆栈发过来重点看里面有没有“Caused by”部分。很多时候真正的原因藏在堆栈深处比如java.net.SocketTimeoutException其实是读超时而不是连接被拒。拿不到完整的堆栈就盲目操作很容易把简单问题复杂化。达梦数据库的通信问题说到底是个“熟能生巧”的领域。多排查几次建立一个属于自己团队的排查手册把每种现象的典型根因记下来后续再遇到同类问题基本上十分钟以内就能给出方向。这也是我从一次次凌晨三点爬起来处理故障到现在能从容应对各类通信异常的原因。
阅读完成 · 觉得有帮助?
咨询建站