Создание новых дескрипторов базы данных с помощью mod_perl

При стресс-тестировании mod_perl я столкнулся с проблемой, что соединения с базой данных исчезают. Я подозреваю, что процессы совместно используют соединения с базой данных, вызывая проблему.

Но я следовал всем инструкциям для Apache::DBI и не могу понять это.

Я делаю соединения в дочернем процессе, а не в startup.pl. Но когда я проверяю $dbh, возвращаемый каждым дочерним элементом из DBI->connnect, адрес одинаков для каждого процесса httpd. Во-первых, если это работает правильно и переподключается для каждого процесса, должен ли адрес, возвращаемый DBI->connect, отличаться для каждого дочернего процесса? Я предположил, но, насколько я могу судить, основной C-код в DBI (dbih_setup_handle) управляет этим и возвращает тот же адрес. Поэтому, возможно, я не понимаю, что значит воссоединиться с ребенком.

Правильно ли я подключаюсь, если идентификаторы $dbh одинаковые?

1 ответ

Похоже, вы устанавливаете соединение с базой данных в <perl>...</perl> в разделе конфигурации запуска или в модуле, загруженном при запуске, и храните его до тех пор, пока разветвленные процессы не попытаются его использовать.

К сожалению, вам не сойти с рук. Вам нужно как-то убедиться, что новые процессы получают новые соединения.

Мое решение этой проблемы было центральной функцией для получения dbh, который отслеживал, что $$ (текущий идентификатор процесса) был, когда было установлено соединение. Если при передаче соединения функция обнаружила, что $$ изменился, он удалит все существующие соединения, не закрывая их, и создаст новое:

my $_dbh;
my $pid;

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

Любой код, который хотел использовать базу данных, сначала вызвал бы dbh() чтобы получить дескриптор базы данных, и позволить ему создать новый, если необходимо, или передать ранее установленное соединение, если оно может быть использовано.

Другие вопросы по тегам