我的基于mod_perl2的intranet应用程序使用DBI->connect_cached()
,该应用程序应该被Apache::DBI
的相同版本覆盖。它通常运行得很好,但就在最近,我们的测试服务器上出现了一个问题,该服务器只有两个用户连接,因此,当我们试图重新加载一个连接到postgres 9.0后端的带有"致命错误:对不起,已经有太多客户端"的页面时,我们的应用程序有时会死亡,但并非总是如此,尽管如果我查看pgadmin3中的统计数据,所有客户端都是<IDLE>
。
后端与我们的开发和生产后端是分开的,但它们都是用max_connections = 100
配置的。同样,httpd服务都是独立的,但配置了
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 99
MaxClients 99
MaxRequestsPerChild 4000
....
PerlModule Apache::DBI
我一直认为,如果我想让数据库句柄从缓存中受益,就不应该对它们调用disconnect()
。我错了吗?如果没有,我想我会单独询问以上错误。只是想确定不是这个设置。。。
Apache::DBI的文档说:
加载DBI模块时(不要将其与Apache::DBI混淆模块),它检查环境变量"MOD_PERL"是否已设置以及模块Apache::DBI是否已加载。在这种情况下connect请求将被转发到Apache::DBI模块。。。。。没有必要从代码中删除disconnect语句。他们不会做任何事情,因为Apache::DBI模块重载了断开连接方法。
如果您正在开发严格用于mod_perl的新代码,您可以选择使用DBI->connect_cached(),但要考虑如上所述,在每个请求之后添加自动回滚。
因此,我想对于我的mod_perl2-专用应用程序,我不需要Apache::DBI,因为Apache::DBI的开发人员建议使用DBI->connect_cached。我不需要断开连接的语句。
但是DBI的文档说:
请注意,[connect_cached]的行为在几个方面有所不同由实现的持久连接的行为Apache::DBI。但是,如果加载了Apache::DBI,则connect_cached将使用它。
这听起来像是Apache::DBI实际上会影响connect_cached,因为当我调用它时,我不会得到DBI->connect_cached-behavior,而是得到Apache::DBI->connection behaviour。Apache::DBI的文档建议不要这样做。
更新:我已经将上面配置中的前5个参数全部设置为1,并且我的应用程序在访问页面时仍在使用越来越多的连接。这一点我完全不理解——它应该只有一个进程,而这个进程应该重新使用它的连接。
除非您计划放弃Apache::DBI,否则答案是肯定的否定,因为Apache::DBI的覆盖实际上什么都不做:
# overload disconnect
{
package Apache::DBI::db;
no strict;
@ISA=qw(DBI::db);
use strict;
sub disconnect {
my $prefix = "$$ Apache::DBI ";
Apache::DBI::debug(2, "$prefix disconnect (overloaded)");
1;
}
;
}