У меня есть веб-приложение, которое выходит из строя при перезапуске базы данных и пытается использовать старые соединения. Запуск его под 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'
Это ведет себя правильно, сообщая мне, почему запрос не удался.
Что меня ставит в тупик, так это то, что это segfault, чего не следует делать. Поскольку это происходит только тогда, когда все приложение работает (которое использует DBIx :: Класс), трудно свести его к тесту.
С чего мне начать, чтобы отладить это? Кто-нибудь еще видел это?
ОБНОВИТЬ: дальнейшие исследования показали, что использование mod_perl было отвлекающим маневром. Сведя его до простого тестового сценария, я разместил его в Список рассылки DBI. Спасибо за ответы.






Это, вероятно, означает, что есть разница между вашей средой mod_perl и той, которую вы тестировали с помощью своего скрипта. Что нужно проверить:
Был ли ваш mod_perl скомпилирован с той же версией Perl?
@ INC одинаковы для обоих
Вы используете потоки в своей настройке mod_perl? Я не верю, что DBD :: mysql полностью потокобезопасен.
Я видел эту проблему, но не уверен, что у нее та же причина, что и у вас. Вы случайно не используете какой-то модуль для отправки писем (забыл имя, извините) из своего приложения? Когда у нас возникла проблема в проекте, после нескольких дней отладки мы обнаружили, что этот почтовый модуль делал странные вещи с открытыми файловыми дескрипторами, а затем отключил другой процесс, который вызвал консольный инструмент sendmail, который снова делал странные вещи с файловыми дескрипторами. Я предполагаю, что один из файловых дескрипторов, с которыми он столкнулся, был соединением с базой данных, но я все еще не уверен в этом. Проблема исчезла, когда мы перешли на другой модуль для отправки писем. Может быть, вам тоже стоит поискать.
Если вы получаете segfault, у вас есть файл ядра? Если нет, проверьте ulimit -c. Если это вернет 0, ваша система не будет создавать файлы ядра, и вам придется это изменить. Если у вас есть файл ядра, вы можете использовать gdb или аналогичные инструменты для его отладки. Это не особо веселье, но возможно. Начало команды будет выглядеть примерно так:
gbd /usr/bin/httpd core
В сети разбросано множество руководств по отладка файлов ядра.
Обновление: только что нашел ссылку на обеспечение получения дампа ядра из mod_perl. Это должно помочь.
Спасибо за указатели - в итоге я сократил его до небольшого тестового сценария и отправил в список рассылки DBI (см. Вопрос для ссылки).
Это известная проблема в старом DBD :: mysql. Обновите его (4.008 - это последняя версия нет).
К https://rt.cpan.org/Public/Bug/Display.html?id=37027 прикреплен простой тестовый скрипт это вызовет эту ошибку.
нет - похоже, это проблема либо с DBD :: mysql, либо с двоичными файлами клиента mysql. Спасибо хоть :)