无法通过PDO_ODBC连接DB2:为何始终尝试端口8471?
已在odbc.ini中配置了指向本地DB2 Community Edition v11.5.7数据库的DSN,数据库运行在25010端口,且已通过telnet localhost 25010验证端口连通性,PDO_ODBC扩展也已安装启用。
但通过远程客户端使用PHP的PDO_ODBC连接时出现错误:
Fatal error: Uncaught PDOException: SQLSTATE[08004] SQLDriverConnect:
10061 [unixODBC][IBM][System i Access ODBC Driver]Communication link
failure. comm rc=10061 - CWBCO1049 - The IBM i server application is
not started, or the connection was blocked by a firewall
执行tcpdump后发现,连接始终尝试使用8471端口。
PHP代码如下:
<?php $conn = new PDO('odbc:DSN=SAMPLE;NAM=1;UID=db2inst1;PWD=password'); $sql = "select * from SAMPLE.EMPLOYEE"; $query = $conn->prepare($sql); $query->execute(); $rows = $query->fetchAll(); print_r($rows);
使用isql客户端测试也得到完全相同的错误:
isql localhost SAMPLE
环境信息:PHP 7.4(ZendServer 2021),操作系统为Redhat Enterprise 7.9。
odbc.ini配置如下:
[SAMPLE] Description = IBM i Access ODBC Driver Driver = IBM i Access ODBC Driver System = localhost Port = 25010 ServiceName = db2c_db2inst1 #Trace=Yes #TraceFile=/tmp/sql.log UserID = DB2INST1 Password = password Naming = 0 Database = SAMPLE CommitMode = 1
请问为何连接始终尝试错误的8471端口?该如何解决?
原因
你使用的IBM i Access ODBC Driver是专为连接IBM i(原AS/400)系统设计的,默认会调用IBM i的默认服务端口8471,该驱动并不适配普通的DB2 LUW(Linux/Unix/Windows)社区版数据库——这就是即便你配置了Port参数,驱动依然尝试连接8471端口的核心原因。
解决方案
1. 替换为DB2 LUW专用ODBC驱动
安装并使用针对DB2 LUW的官方ODBC驱动(属于DB2客户端组件的一部分):
- 下载对应RHEL 7.9版本的DB2客户端组件
- 安装完成后,修改
odbc.ini中的Driver参数,指向DB2 LUW驱动文件,示例路径:
具体路径需根据你的DB2客户端实际安装位置调整。Driver = /opt/ibm/db2/V11.5/lib64/libdb2o.so
2. 修正DSN配置
调整odbc.ini配置,适配DB2 LUW驱动:
[SAMPLE] Description = DB2 LUW ODBC Driver for SAMPLE DB Driver = /opt/ibm/db2/V11.5/lib64/libdb2o.so Database = SAMPLE Protocol = TCPIP Hostname = localhost Port = 25010 UID = db2inst1 PWD = password Naming = 0 CommitMode = 1
- 移除
System参数,改用Hostname和Protocol明确指定TCP/IP连接方式 - 确保
Driver指向正确的DB2 LUW驱动文件
3. 验证连接
使用isql测试新配置的DSN:
isql -v SAMPLE db2inst1 password
连接成功后,再运行PHP代码即可正常访问数据库。
额外注意事项
- 确保加载DB2客户端环境变量,可执行DB2安装目录
bin下的db2profile脚本 - 检查SELinux或系统防火墙规则,确认允许25010端口的双向通信
内容的提问来源于stack exchange,提问作者devXen

