Как избежать разрыва соединения с MySQL при работе параллельных процессов?

SergeantPEPPER

Новичок
Как избежать разрыва соединения с MySQL при работе параллельных процессов?

У меня php-программа порождает несколько параллельных дочерних процессов, каждый из которых работает с MySQL базой данных.

Распараллеливание я делаю с помощью функции pcntl_fork.

Тот дочерний процесс, который первым закончил свою работу с MySQL обрывает соединение, тем самым лишая MySQL всех остальных процессов...

Подскажите пожалуйста, как можно не обрывать соединение в дочерних процессах.

ОГРОМНОЕ СПАСИБО всем, кто поможет.
 

Gas

может по одной?
соединение с mysql происходит до вызова pcntl_fork ?
 

Alexandre

PHPПенсионер
Распараллеливание я делаю с помощью функции pcntl_fork.
самоубийца.

вообще, я в таком случае все данные сбрасываю в лог в формате json или serialize
а потом по крону запускаю приложение, которое:
переименовывает лог
данные из переименованного лога кладет в БД.
уничтожает переименованный файл.

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

ИМХО - для использования многопроцессорности приложения - используйте соответствующие языки
 

SergeantPEPPER

Новичок
Автор оригинала: Gas
соединение с mysql происходит до вызова pcntl_fork ?
Да, соединение устанавливается в начале главного процесса до вызова fork().

Alexandre, не совсем понятно, что Вы имели в виду... Но пока что Ваш ответ самый полный и содержательный за два дня :)))

А о том, что можно открывать коннекцию в каждом дочернем процессе я уже думал, но что-то не очень хочется пользоваться этим методом (хотя в конечном счете им наверное и придется...)

Спасибо всем, кто помог!
 

nail

Новичок
Вообще, вопрос странный.
Потому что коннекты (tcp) бывают только внутри процессов, их нельзя передать из одного процесса другому.
И это само собой разумеется, что к базе надо коннектиться после форка.
 

Gas

может по одной?
SergeantPEPPER
самый полный и содержательный за два дня
может ты и не в курсе, но часто вопросы авторам топиков задаются не обы пальцы размять, а чтобы уточнить детали проблемы и на основе этой информации дать ответ, а не заниматься гаданием. Заметь, ответ на вопрос адресованный тебе ты дал почти через сутки.
 

SergeantPEPPER

Новичок
Да, нет я наоборот считаю, что уточнение - это пропорциональное улучшение конечного результата и в смысле времени, и в смысле качества... :)

А за длительную задержку извиняюсь, у меня не всегда бывает возможность быстро выйти в Интернет.

2Krishna: не, mysql_pconnect у меня почему то не работал (вообще тоже еще вопрос "почему" - у меня все равно соединение обрывалось, даже когда я делал mysq_pconnect в начале гланого процесса).
 

Gas

может по одной?
у меня все равно соединение обрывалось, даже когда я делал mysq_pconnect
Как был создан ресурс значения не имеет, он единожды умер и всё - null. Alexandre и nail сказали что нужно соединения создавать в child'ах.
 

Alexandre

PHPПенсионер
Alexandre, не совсем понятно, что Вы имели в виду...
то что, если хочешь многопроцессорность, надо использовать Си.
fork клонирует контексты только для файловых дескрипторов,
а при создании коннекции к БД, создается контекст соединения, при форканье - он копируется, а при закрытии - соответственно все соединения разрываются.

Как выход: можно создать пул соединений (открыть сразу 5-10 коннекций) и эти соединения раздавать процессам, не закрывая их. По окончанию процесса, по сигналу SIGCHLD пометить в пуле, что соединение освободилось и отдать его следующему порожденному процессу.
А освободить весь пул лишь по окончанию родительского процесса (если он устроен как демон). В принципе - это всего 20-40 строк кода.

-~{}~ 04.04.08 15:35:

а еще я предложил, в случае ввода данных в БД (а это в исходных условиях не значилось), его осуществлять вообще отдельным процессом из постоянно заполняющегося лога.
 

SergeantPEPPER

Новичок
2All: Я понимаю, что логичный выход это открывать соединения после форканья уже в дочрних процессах, но хотелось бы обойтись одним (тут уже дело скорее в спорт. интересе), а то, что php, как язык, не самый лучший вариант для реализации сего, я узнал в самую первую очередь :) . Но реализация на php в данном случае - обязательное условие.

2Gas: НЕ, то что когда ресурс умер - он умер и ВСЕ... - это я поимаю. Я имел в виду то, что при использовании mysql_pconnect соединение не должно умирать при окончании работы с ним (ну по крайней мере я так читал в описании данной функции), а у меня оно все равно умирало. Вот.

2Alexandre: Идея теоретически теперь ясна, однако я вот как раз и не понимаю как можно по освобождении соединения отдать его следующему процессу, а не убивать его.

Однако, все равно спасибо за проявленное внимание...
 

Alexandre

PHPПенсионер
однако я вот как раз и не понимаю как можно по освобождении соединения отдать его следующему процессу, а не убивать его.
1) создается массив соединений $pool[$i] = array( 'mysql'=> $mysql_connect , 'pid' = 0 );
2) при порождении процесса мы получаем его pid = pnctl_fork... и производим поиск по $i в массиве, где 'pid' == 0
3) используем $i элемент из массива коненкций, а в сам этот элемент записываем pid
4) соединение по окончании не убивается, а помечается аля-свободно..., т.е. pid=0
5) помечается соединение в главной процессе при обработке сигнала SIGCHL
6) по окончании главного процесса должны быть закрыты все соедимнения.
7) если есть "зацикливание" в случае демонизации, то заканчивание процесса организуется по синналу SIGHUB, SIGTERM или SIGUSR1

в общем где-то так.
 

Gas

может по одной?
SergeantPEPPER
Я имел в виду то, что при использовании mysql_pconnect соединение не должно умирать при окончании работы с ним (ну по крайней мере я так читал в описании данной функции), а у меня оно все равно умирало. Вот.
соединение с mysql и не умирает, php как бы теряет с ним связь. По твоей логике получается что, сделали один раз pconnect - создалось постоянное соединение, и при следующем запуске скрипта можно pconnect вообще не вызывать, так как ранее же оно было создано. А вызывать то всё равно нужно.
 

berkut

Новичок
Я имел в виду то, что при использовании mysql_pconnect соединение не должно умирать при окончании работы с ним (ну по крайней мере я так читал в описании данной функции), а у меня оно все равно умирало. Вот.
так оно, соединение, вроде как привязано к чайлду апача, нет?
 

Gas

может по одной?
berkut
pcntl ф-ции запускать под webserver'ом, ну-ну.

Хотя щас я подумал, возможно я делаю неправильные выводы относительно pconnect'а в данном случае, может теоритически и должно работать :)
 

berkut

Новичок
а чё ну-ну? вроде как пипец не отимально, но почему-бы и нет, если это вообще будет работать.
а если не из под сервера и пконнект вяжется к чайлду, то кто будет держать этот pconnect в случае отсутствия веб-сервера(запуск из консоли, пых как цги - фаст цги уже хз).
обычный цги-же вообще следов за собой не может оставлять, как и консоль - поэтому кому и где держать коннект?
прастите ламера за спор с аппологетами пыхпых и муси
 
Сверху