上一篇博文讲了很多系统调用函数,这些知识再加上经验积累,可用于在实际工作中分析和解决问题。
问题:香港机房的一台linux服务器,上面安装的sqlplus无法连接到深圳公司机房的oracle server,执行sqlplus xxxx/[email protected]的时候直接没反应,经过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/[email protected]
卡住的时候,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通信有问题就是证据,否则凭什么说是网络引起的问题呢?