1

在对数据库连接消失的 mod_perl 进行压力测试时,我遇到了一个问题。我怀疑进程正在共享数据库连接,从而导致了问题。

但是我已经遵循了 Apache::DBI 的所有说明,但无法弄清楚这一点。

我在子进程中而不是在 startup.pl 中建立连接。但是当我检查每个子进程从 DBI->connnect 返回的 $dbh 时,每个 httpd 进程的地址都是相同的。首先,如果这工作正常并为每个进程重新连接,那么 DBI->connect 返回的地址对于每个子进程是否应该不同?我假设是这样,但据我所知,DBI 中的核心 C 代码(dbih_setup_handle)正在管理它并返回相同的地址。所以也许我不明白重新连接孩子意味着什么。

如果 $dbh 句柄相同,我是否可以正确重新连接?

4

1 回答 1

0

听起来您正在<perl>...</perl>启动配置中的某个部分或启动时加载的模块中建立数据库连接,并保留它直到分叉进程尝试使用它。

不幸的是,你无法摆脱这一点。您需要以某种方式确保新进程获得新连接。

我对这个问题的解决方案是获取一个 dbh 的中心函数,该函数跟踪$$建立连接时(当前进程 ID)是什么。如果在移交连接时,该函数发现$$发生了变化,它将处置任何现有的连接而不关闭它们,并创建一个新的:

my $_dbh;
my $pid;

sub dbh {
        if($pid != $$) {
                $_dbh = DBI->connect(...);
                $pid = $$;
        }
        return $_dbh;
}

任何想要使用数据库的代码都会首先调用dbh()以获取数据库句柄,并在必要时让它创建一个新的句柄,或者如果可以使用则交出先前建立的连接。

于 2012-05-20T00:14:22.197 回答