DBD :: Informix连接问题

时间:2011-09-14 13:48:20

标签: perl informix dbi

我对DBD :: Informix有点奇怪的问题。如果我运行这样一个简单的脚本:

use DBI;
my $dbh = DBI->connect_cached('dbi:Informix:database', '', '');
my $sth = $dbh->prepare('select foo from bar');
...

它可以正常工作。但是,如果我尝试从测试脚本中完全相同,则会失败并显示以下消息:

SQL: -25588: The appl process cannot connect to the database server cms_ol.
ISAM: 22: Invalid argument

我看到的唯一区别是测试脚本在模块使用上非常繁重;它基于Test :: More并加载了许多要测试的子模块。

启用DBI跟踪并不提供任何有用的东西(至少对我而言)。简单的脚本运行得很好:

DBI 1.616-nothread default trace level set to 0x0/1 (pid 9685 pi 0) at test_ifx.pl line 6
Note: perl is running without the recommended perl -w option
-> DBI->connect(dbi:Informix:cms@cms_ol, , ****, HASH(0x13fad0))
-> DBI->install_driver(Informix) for solaris perl=5.008009 pid=9685 ruid=106 euid=106
   install_driver: DBD::Informix version 2011.0612 loaded from /cms/webdash/lib/arch/DBD/Informix.pm
<- install_driver= DBI::dr=HASH(0x1c8070)
!! warn: 0 CLEARED by call to connect method
    -->> DBD::Informix::dbd_ix_db_connect()
CONNECT TO 'cms@cms_ol' - no user info
    -->> DBD::Informix::dbd_ix_db_check_for_autocommit()

...我看到的有问题脚本跟踪的唯一区别就是它失败了:

DBI 1.616-nothread default trace level set to 0x0/1 (pid 9687 pi 0) at 22_report.t line 5 via 22_report.t line 6
Note: perl is running without the recommended perl -w option
-> DBI->connect_cached(dbi:Informix:cms, , ****)
-> DBI->install_driver(Informix) for solaris perl=5.008009 pid=9687 ruid=106 euid=106
   install_driver: DBD::Informix version 2011.0612 loaded from /cms/webdash/lib/arch/DBD/Informix.pm
<- install_driver= DBI::dr=HASH(0xb619bc)
!! warn: 0 CLEARED by call to connect_cached method
    -->> DBD::Informix::dbd_ix_db_connect()
CONNECT TO 'cms' - no user info
***ERROR***
SQL: -25588: The appl process cannot connect to the database server cms_ol.
ISAM: 22: Invalid argument
    <<-- dbd_ix_db_connect (**ERROR-1**)
    <<-- DBD::Informix::dbd_ix_db_connect()

我在Solaris 9中运行自定义Perl 5.8.9版本,使用最新的DBI和DBD :: Informix版本,针对Informix IDS 9.40UC。

更新:如果我试图成为一个智能手机并在重度测试脚本的顶部放置一个这样的块:

use DBI;
BEGIN { my $dbh = DBI->connect_cached( ... ); print "Connected!\n" if $dbh; }

......它的打印方式如下:

Connected!
Out of memory!
Callback called exit.
END failed--call queue aborted at t/22_report.t line 20.
Callback called exit at t/22_report.t line 20.
BEGIN failed--compilation aborted at t/22_report.t line 24.

我的猜测是DBD :: Informix与连接后加载的一些模块冲突。但是哪一个?那就是问题......

另一次更新:看来上面的伎俩做了一些笨重的事情。我尝试通过将'use Module'替换为'require Module'来明确加载所有模块;模块 - &GT;进口”。纯Perl模块是可以的,但每当使用XSLoader的XS模块出现时,Perl就会出现友好的“Out of memory”消息。如果我在模块初始化下移动Informix连接,它可以正常工作 - 除了DBD :: Informix失败并出现相同的-25588错误。布玛。我很茫然。 :(

另一个更新:我尝试使用DBI 1.601(最新的将使用Perl 5.6编译)和DBD :: Informix运行与Solaris 9附带的标准Perl 5.6.1相同的脚本2011.0612。同样的事情,所以不是自定义Perl给我带来麻烦。

我还可以添加有问题的测试模块使用DBD :: SQLite进行原型设计并完全正常工作。这是DBD :: Informix的最终测试失败......像往常一样。 :/

解决方法:在与Jonathan进行电子邮件讨论后,发现了一种解决方法:向Informix服务器添加基于流的“onipcstr”连接,允许DBD :: Informix进行连接。显然,一些XS模块会干扰默认的基于shmem的连接方法,尽管目前还不知道罪魁祸首。

1 个答案:

答案 0 :(得分:2)

进一步讨论

根据我的经验,定制的Perl比系统Perl更容易。我从不修改系统的Perl安装(我不想破坏它)所以我总是建立自己的。

您似乎有:

  • Solaris 9(SPARC?)
  • Perl 5.8.9
  • DBI 1.616
  • DBD :: Informix 2011.0612
  • ESQL / C(CSDK)2.81
  • Informix Dynamic Server 9.40

我们没有ESQL / C和IDS的详细子版本(2.81.UC2,9.40.UC5或其他)。有一个暗示您使用的是32位版本的IDS,因此可能一切都是32位。您可能已经意识到IBM不再支持9.40(事实上,它的后续版本10.00也不再支持)。然而,从表面上看,这些都不重要。失败的t91lvarchar.t不是一个大问题。

  • 您是否可以在工作和非工作模式下运行连接,并在环境中设置DBI_TRACE = 9。

如果连接操作的跟踪太大而不能更新问题,我们最好离线到DBD :: Informix支持频道(就是我,但是通过电子邮件)。

22的'ISAM'错误(无效参数)令人费解。我很好奇这个服务器的sqlhosts文件中的内容 - 具体是cms_ol的条目。我不确定它会显示任何内容,尤其是因为您说下面的示例ESQL / C(在“第一个假设”部分中)工作正常,有时Perl连接,有时它不连接。

我想知道共享库中的函数之间是否存在名称冲突?那种事情将会被追踪。

第一个假设

收到的进一步信息表明,这不是至关重要的区别。

差异似乎是:

  • 作品:CONNECT TO 'cms@cms_ol' - no user info
  • 失败:CONNECT TO 'cms' - no user info

要解释的棘手部分是为什么第二个失败,特别是当错误继续提及cms_ol时。

解决方法是在连接字符串中指定服务器名称:

  • DBI->connect(dbi:Informix:cms@cms_ol, , ****, HASH(0x13fad0))
  • DBI->connect_cached(dbi:Informix:cms, , ****)

ESQL / C级别的基础问题比其他Perl模块更容易发生。也就是说,如果您编译并执行了这个ESQL / C程序,它将在cms失败并处理cms@cms_ol

int main(int argc, char **argv)
{
    $ char *dbs = "cms";
    if (argc > 1)
        dbs = argv[1];
    $ whenever error stop;
    $ connect to :dbs;
    return 0;
}

您可以在没有显式数据库名称(或使用显式'cms')的情况下运行它,我希望它会失败。您可以使用'cms @ cms_ol'运行它,我希望它能通过。如果程序通过,程序将不会说什么;当它失败时会很明显(虽然消息不会很漂亮)。

有可能与connect_cached有关;这是DBI模块提供的服务,而不是DBD :: Informix模块提供的服务。总的来说,更有可能发生在ESQL / C级别的事情。