实战例子:用strace分析数据库连接问题

上一篇博文讲了很多系统调用函数,这些知识再加上经验积累,可用于在实际工作中分析和解决问题。


问题:香港机房的一台linux服务器,上面安装的sqlplus无法连接到深圳公司机房的oracle server,执行sqlplus xxxx/xxxx@rwdb的时候直接没反应,经过2分钟左右,报:

SQL*Plus: Release 11.2.0.1.0 Production on Tue Apr 21 15:44:04 2015

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

ERROR:
ORA-12547: TNS:lost contact


环境:

客户端机器地址为:172.17.5.13(redhat5.8+oracle11g client)
服务端机器地址为:192.168.1.48(solaris9+oracle10g server)


经过测试:

1、tnsping rwdb正常,这说明客户端tnsnames配置没有问题

2、在其它环境下测试redhat5.8+oracle 11g client连接solaris9+oracle 10g server,成功,无兼容性问题。


那么,如何继续排查问题呢?这个时候strace就派上用场了。

在客户端机器上执行:

#strace -o strace.log sqlplus xxxx/xxxx@rwdb

卡住的时候,strace.log显示:

brk(0x9196000)                          = 0x9196000
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 9
fcntl(9, F_SETFL, O_RDONLY|O_NONBLOCK)  = 0
connect(9, {sa_family=AF_INET, sin_port=htons(1521), sin_addr=inet_addr("192.168.1.48")}, 16) = -1 EINPROGRESS (Operation now in progress)
times({tms_utime=1, tms_stime=1, tms_cutime=0, tms_cstime=0}) = 2186561939
mmap(NULL, 528384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae433057000
poll([{fd=9, events=POLLOUT}], 1, 60000) = 1 ([{fd=9, revents=POLLOUT}])
getsockopt(9, SOL_SOCKET, SO_ERROR, [-132438043876392960], [4]) = 0
fcntl(9, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(9, F_SETFL, O_RDWR)               = 0
getsockname(9, {sa_family=AF_INET, sin_port=htons(53136), sin_addr=inet_addr("172.17.5.13")}, [549755813904]) = 0
getsockopt(9, SOL_SOCKET, SO_SNDBUF, [366915001648168960], [4]) = 0
getsockopt(9, SOL_SOCKET, SO_RCVBUF, [366915001648239956], [4]) = 0
setsockopt(9, SOL_TCP, TCP_NODELAY, [1], 4) = 0
fcntl(9, F_SETFD, FD_CLOEXEC)           = 0
rt_sigaction(SIGPIPE, {0x1, ~[ILL ABRT BUS FPE SEGV USR2 XCPU XFSZ SYS RTMIN RT_1], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x35a240ebe0}, {SIG_DFL, [], 0}, 8) = 0
write(9, "\0\324\0\0\1\0\0\0\1:\1,\fA \0\177\377\177\10\0\0\1\0\0\232\0:\0\0\10\0"..., 212) = 212
read(9,


分析:

这里的fd9是一个客户端连接服务端(192.168.1.48)1521端口的socket,这个socket的建立是正常的,但是当write发出第一个消息出去后就卡顿了。这里我们有理由开始怀疑网络问题,是否网络不稳定导致了sqlplus的异常。


果然,通过测试,发现香港到深圳的这个vpn网络环境不稳定,存在丢包:

#ping -s 172.17.5.13 1024 >ping.log

14%的丢包率:
530 packets transmitted, 455 packets received, 14% packet loss
round-trip (ms)  min/avg/max = 11/11/17


联系网络管理员,将路由从vpn切换至另外一个专线通道后问题解决,sqlplus连接成功。这个case也说明,sqlplus对网络环境是要求很高的,之前一直以为即使有丢包也应该能连上,但事实并非如此。


小结:

通过对strace的分析,可能未必能一次性解决问题,还得考虑其它因素。这个case,即使不分析strace,通过测试网络,最终也能发现问题,但strace可以很好地提供一个证据和参考,这里socket通信有问题就是证据,否则凭什么说是网络引起的问题呢?







本文出自 “记忆碎片” 博客,谢绝转载!

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。