当压力测试mod_perl数据库连接正在消失时,我遇到了一个问题。我怀疑进程正在共享数据库连接,从而导致问题。
但是我已经遵循了Apache::D BI的所有说明,并且无法弄清楚这一点。
我是在子进程中建立联系,而不是在 startup.pl 中建立联系。但是当我检查每个孩子从DBI->connnect返回的$dbh时,每个httpd进程的地址都是相同的。首先,如果这工作正常并为每个进程重新连接,则 DBI->connect 返回的地址是否应该为每个子进程不同?我已经假设是这样,但据我所知,DBI (dbih_setup_handle( 中的核心 C 代码正在管理它并返回相同的地址。所以也许我不明白在孩子身上重新建立联系意味着什么。
如果$dbh句柄相同,我是否可以正确重新连接?
您正在启动配置的<perl>...</perl>
部分中或在启动时加载的模块中建立数据库连接,并保留它,直到分叉进程尝试使用它。
不幸的是,您无法逃脱此。 您需要以某种方式确保新流程获得新连接。
我对这个问题的解决方案是一个中心函数,用于获取一个 dbh,该 dbh 跟踪建立连接时$$
(当前进程 ID(是什么。 如果在移交连接时,函数发现$$
已更改,它将在不关闭连接的情况下处理任何现有连接,并创建一个新连接:
my $_dbh;
my $pid;
sub dbh {
if($pid != $$) {
$_dbh = DBI->connect(...);
$pid = $$;
}
return $_dbh;
}
任何想要使用数据库的代码都会首先调用dbh()
以获取数据库句柄,并在必要时让它创建一个新句柄,或者交出以前建立的连接(如果可以使用(。