MySQL драйвер segfaulting под mod_perl - где искать проблему

У меня есть веб-приложение, которое segfaults при перезапуске базы данных, и он пытается использовать старые соединения. Запуск его под gdb --args apache -X приводит к следующему выводу:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1212868928 (LWP 16098)]
0xb7471c20 in mysql_send_query () from /usr/lib/libmysqlclient.so.15

Я проверил, что драйверы и база данных обновлены ( DBD:: mysql 4.0008, MySQL 5.0.32-Debian_7etch6-log).

Досадно, что я не могу воспроизвести это с помощью тривиального сценария:

use DBI;
use Test::More tests => 2;

my $dbh = DBI->connect( "dbi:mysql:test", 'root' );

sub test_db {
    my ($number) = $dbh->selectrow_array("select 1 ");
    return $number;
}

is test_db, 1, "connected to db";

warn "restart db now";
getc;

is test_db, 1, "connected to db";

Что дает следующее:

ok 1 - connected to db
restart db now at dbd-mysql-test.pl line 23.

DBD::mysql::db selectrow_array failed: MySQL server has gone away at dbd-mysql-test.pl line 17.
not ok 2 - connected to db
#   Failed test 'connected to db'
#   at dbd-mysql-test.pl line 26.
#          got: undef
#     expected: '1'

Это ведет себя правильно, сообщая мне, почему запрос не прошел.

Что меня озадачивает, так это то, что это segfaulting, чего не следует делать. Поскольку это происходит только во время работы всего приложения (которое использует DBIx:: Class), его трудно свести к тестовому случаю.

Где я должен начать искать, чтобы отладить это? Кто-нибудь еще видел это?

ОБНОВЛЕНИЕ: дальнейшее подталкивание показало, что находящееся под mod_perl было красной сельдью. Сокращая его до простого тестового сценария, я теперь разместил его в списке рассылки DBI. Спасибо за ваши ответы.

4 ответа

Решение

Это известная проблема в старом DBD::mysql. Обновите его (4.008 не обновлен).

К https://rt.cpan.org/Public/Bug/Display.html?id=37027 добавлен простой тестовый скрипт, который вызовет эту ошибку.

Вероятно, это означает, что есть разница между вашей средой mod_perl и той, которую вы тестировали с помощью своего скрипта. Некоторые вещи, чтобы проверить:

  • Был ли ваш mod_perl скомпилирован с той же версией Perl

  • Являются ли @INC одинаковыми для обоих

  • Используете ли вы темы в вашей настройке mod_perl? Я не верю, что DBD::mysql полностью поточно-ориентирован.

Я видел эту проблему, но я не уверен, что у нее была та же причина, что и у вас. Вы случайно не используете определенный модуль для отправки писем (забыл имя, извините) из своего приложения? Когда у нас возникла проблема в проекте, после нескольких дней отладки мы обнаружили, что этот почтовый модуль делал странные вещи с открытыми файловыми дескрипторами, а затем отключили другой процесс, который назывался консольным инструментом sendmail, который снова делал странные вещи с файловыми дескрипторами. Я предполагаю, что одним из файловых дескрипторов, с которыми он связывался, было соединение с базой данных, но я все еще не уверен в этом. Проблема исчезла, когда мы перешли на другой модуль для отправки почты. Может быть, стоит посмотреть и на тебя.

Если вы получаете segfault, у вас есть core-файл greated? Если нет, проверьте ulimit -c. Если это возвращает 0, ваша система не будет создавать файлы ядра, и вам придется это изменить. Если у вас есть файл ядра, вы можете использовать gdb или аналогичные инструменты для его отладки. Это не особенно весело, но возможно. Старт команды будет выглядеть примерно так:

gbd /usr/bin/httpd core

Существует множество руководств по отладке основных файлов, разбросанных по сети.

Обновление: только что нашел ссылку, чтобы убедиться, что вы получаете дампы ядра из mod_perl. Это должно помочь.

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