【发布时间】:2013-12-21 05:19:12
【问题描述】:
这发生在我较旧的 Fedora 系统上。今天,我设置了一个新的 CentOS 6.5,安装了最新的 oracle 客户端(12.1.0.1.0),来自 cpan(1.68)的最新 DBD::Oracle,并且遇到了同样的问题:当我尝试连接到数据库。当我从命令行或 CGI 尝试相同的 perl 时,它可以工作;当我关闭 sqlnet.ora 文件中的 LDAP 名称解析器时,它也能正常工作。
从头开始:这是我的startup.pl:
$ENV{'NLS_LANG'}='AMERICAN_AMERICA.AL32UTF8';
$ENV{'ORACLE_HOME'}='/opt/oracle/OraHome1';
use DBI ();
use DBD::Oracle ();
这是我的测试程序:
#!/usr/bin/perl
require "startup.pl" unless defined $ENV{'ORACLE_HOME'};
use DBI;
use DBD::Oracle;
print "Content-type: text/plain\n\n";
print "connecting: \n";
my $dbh=DBI->connect("dbi:Oracle:mydb", 'username', 'password');
print "connected! \n";
从 shell 运行它效果很好。作为 CGI 脚本运行效果很好。从 mod_perl 运行它会使 apache 崩溃:
[Wed Dec 04 16:38:01 2013] [notice] Apache/2.2.15 (Unix) DAV/2 PHP/5.3.3 mod_wsgi/3.2 Python/2.6.6 mod_perl/2.0.4 Perl/v5.10.1 configured -- resuming normal operations
[Wed Dec 04 16:38:28 2013] [notice] child pid 25756 exit signal Segmentation fault (11)
对 httpd 进程进行 strace 显示如下:
connect(21, {sa_family=AF_INET, sin_port=htons(389), sin_addr=inet_addr("10.250.52.237")}, 16) = 0
write(21, "0\f\2\1\1`\7\2\1\2\4\0\200\0", 14) = 14
poll([{fd=21, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, -1) = 1 ([{fd=21, revents=POLLIN}])
read(21, "0\204\0\0\0\20\2\1", 8) = 8
read(21, "\1a\204\0\0\0\7\n\1\0\4\0\4\0", 14) = 14
write(21, "0\201\226\2\1\2c\201\220\0042cn=bpas_p,cn=OracleCo"..., 153) = 153
poll([{fd=21, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 10000) = 1 ([{fd=21, revents=POLLIN}])
read(21, "0\204\0\0\1{\2\1", 8) = 8
read(21, "\2d\204\0\0\1r\0040cn=bpas_p,cn=OracleCont"..., 377) = 377
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
因此,很明显,httpd 在与 10.250.52.237:389 通信时崩溃,这是 oracle 名称解析器的 ldap 端口。
我的标准sqlnet.ora是:
NAMES.DIRECTORY_PATH = (LDAP, ONAMES, TNSNAMES)
NAMES.DEFAULT_DOMAIN = xxx.yyyy.zzz
NAMES.PREFERRED_SERVERS =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = oranames01.yyyy.zzz)(PORT = 1501))
(ADDRESS = (PROTOCOL = TCP)(HOST = oranames02.yyyy.zzz)(PORT = 1502))
)
这是我的 ldap.ora:
DIRECTORY_SERVERS = (oranames01.yyyy.zzz:389:636, oranames02.yyyy.zzz:389:636)
DEFAULT_ADMIN_CONTEXT = "dc=xxx, dc=yyyy, dc=zzz"
DIRECTORY_SERVER_TYPE = OID
来自 strace 转储的地址 (10.250.52.237) 是 oranames01.yyyy.zzz 的 IP 地址。
现在,如果我从 sqlnet.ora 中删除 LDAP 适配器
NAMES.DIRECTORY_PATH = (ONAMES, TNSNAMES)
并将数据库连接字符串放入 tnsnames.ora
mydb.xxx.yyyy.zzz=(DESCRIPTION=(SOURCE_ROUTE=OFF)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=ivorapo01.xxx.yyyy.zzz)(PORT=15350)))(CONNECT_DATA=(SERVICE_NAME=mydb.xxx.yyyy.zzz)(FAILOVER_MODE =(TYPE = SELECT)(METHOD = BASIC)(RETRIES = 180)(DELAY = 1))))
一切正常 - 命令行、cgi perl 和 mod_perl。
因此,显然,mod_perl 和 LDAP 名称解析器的组合似乎存在一些问题。
这发生在我的 Fedora 14 系统上,首先是 apache 2.2.17 和 Oracle 客户端 10.2.0.1.0,今天是新安装的 CentOs 6.5、apache 2.2.15 和 oracle 客户端 12.1.0.1.0 .谷歌搜索 mod_perl 和 oracle 显示一些命中,指的是 ORACLE_HOME 设置得太晚(我也有这个,将它放入 startup.pl 解决了这个问题),但似乎没有什么适合我的问题。
谁能证实这一点?或者,任何人都可以确认 mod_perl + DBD::Oracle + oracle LDAP 名称解析在他们的站点上工作吗?现在,我可以通过不使用 LDAP 名称适配器来解决这个问题,但我希望在投入生产之前解决这个问题。
【问题讨论】:
标签: oracle perl apache mod-perl2