注意:我已用示例替换了 IP 地址、数据库名称和服务器用户。这不会影响任何事情。
设置
我已经安装了 unixODBC ( yum install unixODBC
) 和 IBM 的官方 iSeries ODBC 驱动程序 ( yum install ibm-iaccess-1.1.0.5-1.0.x86_64.rpm
,从 IBM 登录区域下载的 RPM)。安装已成功将驱动程序添加到/etc/odbcinst.ini
:
[IBM i Access ODBC Driver]
Description = IBM i Access for Linux ODBC Driver
Driver = /opt/ibm/iaccess/lib/libcwbodbc.so
Setup = /opt/ibm/iaccess/lib/libcwbodbcs.so
Driver64 = /opt/ibm/iaccess/lib64/libcwbodbc.so
Setup64 = /opt/ibm/iaccess/lib64/libcwbodbcs.so
Threading = 0
DontDLClose = 1
UsageCount = 1
[IBM i Access ODBC Driver 64-bit]
Description = IBM i Access for Linux 64-bit ODBC Driver
Driver = /opt/ibm/iaccess/lib64/libcwbodbc.so
Setup = /opt/ibm/iaccess/lib64/libcwbodbcs.so
Threading = 0
DontDLClose = 1
UsageCount = 1
引用的库文件确实存在,并且它们被正确链接(通过检查ldd
,没有缺失的链接)。
我的~/.odbc.ini
文件如下所示:
[Foo]
Driver = IBM i Access ODBC Driver
DATABASE = FooDB
SYSTEM = 123.45.67.8
HOSTNAME = 123.45.67.8
PORT = 446
PROTOCOL = TCPIP
问题
当我运行时isql Foo USER PASSWORD -v
,大约一分钟后我得到了这个输出:
[email protected] [~]# isql FooDB USER PASSWORD -v
[08S01][unixODBC]
[ISQL]ERROR: Could not SQLConnect
故障排除
听起来好像已经超时了,对吗?
ping 123.45.67.8
返回:
[email protected] [~]# ping 123.45.67.8
PING 123.45.67.8 (123.45.67.8) 56(84) bytes of data.
64 bytes from 123.45.67.8: icmp_seq=1 ttl=63 time=29.8 ms
64 bytes from 123.45.67.8: icmp_seq=2 ttl=63 time=29.8 ms
64 bytes from 123.45.67.8: icmp_seq=3 ttl=63 time=29.8 ms
64 bytes from 123.45.67.8: icmp_seq=4 ttl=63 time=31.0 ms
64 bytes from 123.45.67.8: icmp_seq=5 ttl=63 time=29.9 ms
telnet 123.45.67.8 446
返回:
[email protected] [~]# telnet 123.45.67.8 446
Trying 123.45.67.8...
Connected to 123.45.67.8.
Escape character is '^]'.
foobar
^]
telnet> quit
Connection closed.
Trace
使用和启用 ODBC 日志TraceFile
会/etc/odbcinst.ini
产生如下输出:
[ODBC][22093][1454628360.104274][__handles.c][450]
Exit:[SQL_SUCCESS]
Environment = 0x13a4750
[ODBC][22093][1454628360.104316][SQLAllocHandle.c][364]
Entry:
Handle Type = 2
Input Handle = 0x13a4750
[ODBC][22093][1454628360.104339][SQLAllocHandle.c][482]
Exit:[SQL_SUCCESS]
Output Handle = 0x13a5080
[ODBC][22093][1454628360.104363][SQLConnect.c][3614]
Entry:
Connection = 0x13a5080
Server Name = [FooDB][length = 4 (SQL_NTS)]
User Name = [USER][length = 7 (SQL_NTS)]
Authentication = [*******][length = 7 (SQL_NTS)]
UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'
DIAG [08S01]
[ODBC][22093][1454628423.118602][SQLConnect.c][3982]
Exit:[SQL_ERROR]
[ODBC][22093][1454628423.118628][SQLError.c][430]
Entry:
Connection = 0x13a5080
SQLState = 0x7fff9a5bd7b0
Native = 0x7fff9a5bd5a8
Message Text = 0x7fff9a5bd5b0
Buffer Length = 500
Text Len Ptr = 0x7fff9a5bd5ae
[ODBC][22093][1454628423.118656][SQLError.c][467]
Exit:[SQL_SUCCESS]
SQLState = 08S01
Native = 0x7fff9a5bd5a8 -> 10060
Message Text = [[unixODBC]]
[ODBC][22093][1454628423.118685][SQLError.c][430]
Entry:
Connection = 0x13a5080
SQLState = 0x7fff9a5bd7b0
Native = 0x7fff9a5bd5a8
Message Text = 0x7fff9a5bd5b0
Buffer Length = 500
Text Len Ptr = 0x7fff9a5bd5ae
[ODBC][22093][1454628423.118704][SQLError.c][467]
Exit:[SQL_NO_DATA]
[ODBC][22093][1454628423.118722][SQLError.c][510]
Entry:
Environment = 0x13a4750
SQLState = 0x7fff9a5bd7b0
Native = 0x7fff9a5bd5a8
Message Text = 0x7fff9a5bd5b0
Buffer Length = 500
Text Len Ptr = 0x7fff9a5bd5ae
[ODBC][22093][1454628423.118739][SQLError.c][547]
Exit:[SQL_NO_DATA]
[ODBC][22093][1454628423.118765][SQLFreeHandle.c][279]
Entry:
Handle Type = 2
Input Handle = 0x13a5080
[ODBC][22093][1454628423.118784][SQLFreeHandle.c][330]
Exit:[SQL_SUCCESS]
[ODBC][22093][1454628423.118827][SQLFreeHandle.c][212]
Entry:
Handle Type = 1
Input Handle = 0x13a4750
它成功分配了一个句柄,然后尝试连接到数据库,因通用 SQL_ERROR 而失败,尝试处理错误(不确定是什么?),然后释放该句柄。
我最后的办法是直接检查网络流量。这是初始测试,使用telnet
:
[root@host /opt/ibm/iaccess]# tshark -i tun0 -x
Running as user "root" and group "root". This could be dangerous.
Capturing on tun0
0.000000000 10.10.1.10 -> 123.45.67.8 TCP 60 42054 > ddm-rdb [SYN] Seq=0 Win=13660 Len=0 MSS=1366 SACK_PERM=1 TSval=1992917110 TSecr=0 WS=128
...PACKETS...
2.316931937 10.10.1.10 -> 123.45.67.8 TCP 60 42054 > ddm-rdb [PSH, ACK] Seq=1 Ack=1 Win=13696 Len=8 TSval=1992919427 TSecr=4147650000
0000 45 10 00 3c f1 b3 40 00 40 06 73 d2 0a 0a 01 0a E..<..@[email protected].....
0010 ac 10 1e 02 a4 46 01 be e0 f5 71 c8 1d a8 3b 71 .....F....q...;q
0020 80 18 00 6b f5 9b 00 00 01 01 08 0a 76 c9 89 83 ...k........v...
0030 f7 38 1d d0 66 6f 6f 62 61 72 0d 0a .8..foobar..
...PACKETS...
我们看到一些 TCP 数据包,其中一个包含foobar
,正如我们预期的那样。
现在,进行以下测试isql
:
[root@host /opt/ibm/iaccess]# tshark -i tun0 -x
Running as user "root" and group "root". This could be dangerous.
Capturing on tun0
^C0 packets captured
没有交通!?
说实话,我有点不知所措。不知道下一步该怎么做。您觉得哪里出了问题,或者如何解决这个困难的情况?
请注意,服务器设置本身没有问题。我能够使用 IBM 的 iSeries ODBC 驱动程序(适用于 Windows)毫无问题地进行连接。
答案1
好吧,终于搞明白了。真是太神奇了。
首先,请帮自己一个忙,获取 IBM 较旧的 iSeries 驱动程序之一,而不是较新的 iAccess 驱动程序。登录后,转到IBM Software > Downloads > No-charge products, tools, and toolkits
,然后搜索odbc
。您应该会看到类似 的驱动程序IBM i Access for Linux (V7R1)
。获取其中一个。
现在,使用这些较旧的驱动程序,您会收到正确的错误消息:
[08S01][unixODBC][IBM][System i Access ODBC Driver]Communication link failure. comm rc=10060 - CWBCO1048 - A firewall blockage or time-out occurred trying to connect to the IBM i
太棒了!至少现在我们可以绝对、肯定、120% 地确定问题出在某种堵塞上。
但是堵塞是什么呢?IBM 组织良好的文档索引可以解决这个问题:http://www-01.ibm.com/support/docview.wss?uid=nas8N1012436
此处复制的文章中的表格:
PC Function Port (non-SSL) SSL Port
Server Mapper 449 449
License Management (see Note) 8470 9470
RPC/DPC (Remote Command) 8475 9475
Sign-On Verification 8476 9476
Database Access 8471 9471
我们解除了端口8471
(“数据库访问”) 的阻塞,然后一切就开始正常工作了!
2016 年 3 月 8 日更新:出于某种原因,Windows 需要比 Linux 开放更多端口。为了在 Windows 上实现此功能,我们还需要Server Mapper
和Sign-On Verification
端口。
附注:这是文章中的另一个重要段落:
这些端口号(服务器映射器除外)可以配置,虽然上面列出了默认值,但系统上的实际值可能会有所不同。端口是从服务表中检索的。使用相关系统上的 WRKSRVTBLE 命令确定这些端口,以确定端口是否已从默认值修改。