[php+apache+mysql] Timeout/Loop probleem?

Pagina: 1
Acties:
  • 118 views sinds 30-01-2008
  • Reageer

  • Banpei
  • Registratie: Juli 2001
  • Laatst online: 21-08 13:52
Dit is dus geen probleem betreft de php set_time_limit/max_execution_time aangezien die zowiezo al op 3600 seconden staat en het script wel volledig uitgevoerd wordt.

Versies:
Apache: 1.3.20
PHP: 4.3.1
MySQL: 4.0.12

Ik heb een probleem met een verschrikkelijk zwaar script dat als cron gerunt wordt waarbij er informatie uit een stuk of 6 tabellen gekopieerd wordt tussen twee MySQL databases. Hierbij moeten er bij sommige nieuwe tabellen nieuwe auto_increments gemaakt worden en juist bij anderen niet (waar dus wel een autoincrement op staat, maar dat is een ander verhaal) dus wordt dit opgelost door dit te kopieeren via een php script waar verschillende klassen gebruikt worden (1 klasse per tabel) die cascading aangeroepen worden en dan dus de juiste handeling uitvoeren. Bij het initialiseren van het script en het afsluiten van het script komt er een stuk info uit waaraan ik kan zien wat het script allemaal gedaan heeft, en tussendoor komt er geen debug informatie uit.

Op zich werkt dit dus prima, mits het om kleine aantallen gaat (max. ongeveer 5000 records van de eerste tabel) en dit neemt op zich al zo'n 10 minuten in beslag.

Wat er dus mis gaat is dat ergens in een van die klassen dus een selectie gemaakt wordt van een rij objecten en dit in een while loop wordt doorlopen. Deze while loop wordt ergens na 5000 keer afgebroken, maar ik krijg dus wel de statistieken te zien van wat het script gedaan heeft die alleen aan het eind van het script worden weergegeven. Dat het bij deze fout gaat kan ik achterhalen door te kijken wat er wel en niet gedaan is in de database. De stap na de while loop wordt dus niet gedaan, maar het script sluit dus wel volledig af.

Nu is het rare dat ik wilde zien hoeveel records er precies gedaan worden en gaf een echo op het net nieuw geinserte id en tot mijn verbazig loopt het script dus wel de gehele kopie actie. Na dit enkele malen te hebben herhaald kan ik vaststellen dat het script dus alleen volledig doorlopen wordt indien ik dus in de while (of ergens in de klassen die cascaded er achteraan komen) output terug geef.

Ik heb het ook al geprobeerd op een oude versie van PHP (4.12) en daar is precies hetzelfde probleem. :(

Is er misschien iets bekend van een timeout van Apache of bescherming op een klasse in PHP als er voor lange tijd geen output door php terug wordt gegeven en dus maar alles afbreekt? De workaround is op dit moment dus duidelijk: ik geef nu dus wat output terug, maar ik zou toch graag willen achterhalen wat nu precies dit veroorzaakt.

Verwijderd

wat voor type is je autoincrement veld -> dat mag bij tinyints geloof ik niet groter zijn dan 128.
zet anders een paar "echo" s in je script om te zien welke waarden variabelen hebben of om te zien wat wel en niet gebeurt.
post anders wat code

  • Banpei
  • Registratie: Juli 2001
  • Laatst online: 21-08 13:52
Verwijderd schreef op 04 June 2003 @ 13:08:
wat voor type is je autoincrement veld -> dat mag bij tinyints geloof ik niet groter zijn dan 128.
zet anders een paar "echo" s in je script om te zien welke waarden variabelen hebben of om te zien wat wel en niet gebeurt.
post anders wat code
Ze zijn allemaal van het type int(11): loop dus door tot 4 miljard.

Zoals je kan lezen in de openingspost doet ie het dus wel als ik info echo, dus dat helpt ook niet.

Het is overigens ook niet een geheugen probleem: php mag 32MB gebruiken en het apache process gebruikt in het totaal max. 11MB.

[ Voor 4% gewijzigd door Banpei op 04-06-2003 13:19 ]


  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
ik heb geen idee hoe dat met die echo's zit, maar hoe voltrekt het proces zich eigenlijk? gaat die cron per record alles inlezen en vervolgens per record ook alles inserten in de tabellen op de andere server?

misschien dat het in dat geval wat efficienter is om de relevante informatie eerst in tijdelijke tabellen stoppen, daar een dump van te maken, die naar de andere server te gooien en daar een 'select insert into' te doen.

het is maar een suggestie...

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
doe je wel een UPDATE ... VALUES? ie 1 Select en 1 Update per copy? Of doe je het per record (wat absurd is)

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Ik snap niet zo goed hoe iets dat als cron gerunt wordt onderhevig zou kunnen zijn aan timeouts van Apache :? Hoe kom je daarbij?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
hobbit_be schreef op 04 juni 2003 @ 18:20:
doe je wel een UPDATE ... VALUES? ie 1 Select en 1 Update per copy? Of doe je het per record (wat absurd is)
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
SET col_name1=expr1, [col_name2=expr2, ...]
[WHERE where_definition]
[LIMIT #]
Update en values gaat niet samen.

  • Banpei
  • Registratie: Juli 2001
  • Laatst online: 21-08 13:52
drm schreef op 04 June 2003 @ 18:31:
Ik snap niet zo goed hoe iets dat als cron gerunt wordt onderhevig zou kunnen zijn aan timeouts van Apache :? Hoe kom je daarbij?
Omdat het via lynx gerunt wordt als in: lynx http:/bla/cron.php

De cron los aanroepen via een browser kan overigens geen kwaad aangezien de taken van de cron uit de database komen.

Maar het gaat van database naar database op dezelfde server, en allemaal record per record. Stuur zo nog wel even wat meer info als ik op mijn werk zit.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Banpei:
Omdat het via lynx gerunt wordt als in: lynx http:/bla/cron.php
Waarom niet gewoon via de shell? Heb je geen php binary geinstalleerd?
De cron los aanroepen via een browser kan overigens geen kwaad aangezien de taken van de cron uit de database komen.
IE heeft iig wel iets als een timeout. Als die voor 30 (?) seconden geen respons krijgt van de server (i.e; je php script geeft geen output), dan besluit IE dat het een "page cannot be displayed" is :)
Maar het gaat van database naar database op dezelfde server, en allemaal record per record. Stuur zo nog wel even wat meer info als ik op mijn werk zit.
Misschien is het wel handig eens te kijken naar mysqldump en de mogelijkheden daarvan?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Banpei
  • Registratie: Juli 2001
  • Laatst online: 21-08 13:52
drm schreef op 05 June 2003 @ 09:07:
Waarom niet gewoon via de shell? Heb je geen php binary geinstalleerd?
Nope. En op deze manier kunnen we dus van een site de cron uitzetten en vanaf afstand handmatig laten lopen door iemand zonder shell access.
IE heeft iig wel iets als een timeout. Als die voor 30 (?) seconden geen respons krijgt van de server (i.e; je php script geeft geen output), dan besluit IE dat het een "page cannot be displayed" is :)
Zoals ik al in de openingspost zeg: het script heeft zelf geen timeout. Die wordt volledig uitgevoerd aangezien alles wat voor en na de kopie-actie wordt gedaan ook output geeft en dat allemaal ook terug komt. Ergens in een van de klassen stopt ie midden in een while loop:
PHP:
1
2
3
4
5
6
while ($participant_row = $participants->fetch())
{
   $new_participant_id = $participant->copyParticipant($participant_row->{"PARTICIPANT_ID"}, $copyMode);
// Ugly workaround!!! :r :r :r
   echo $new_participant_id."<br>";
}

Hierboven staat overigens de workaround er al in verwerkt. Als ik de echo uitcomment stopt ie ergens in deze while. Deze while duurt ongeveer een 5 a 6 minuten om te doorlopen.
Misschien is het wel handig eens te kijken naar mysqldump en de mogelijkheden daarvan?
In de openingspost zei ik al dat dat dus geen optie is omdat het er niet om gaat dat het een 1 op 1 kopie is, maar een kopie van een z.g.n. template waarbij in sommige gevallen dus wel nieuwe id's moeten worden gegenereerd voor sommige tabellen en juist in enkele andere dezelfde. Maw: de klassen moeten dus cascaded aangeroepen worden met een copy-mode die dus weer bepaald in de onderliggende klasse of er wel of niet nieuwe id's gegenereerd moeten worden.

  • cybermans
  • Registratie: Maart 2001
  • Laatst online: 20-08 08:46
in de php.ini staat toch dat php een maxruntime heeft van 30 sec? Als je die eens op groter zet. Let er dan wel op dat een infinite loop wel zo langer blijft doorlopen.

Strava | Runkeeper | Endomondo (mijn leikr uploads)


  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
Banpei schreef op 05 June 2003 @ 09:29:
In de openingspost zei ik al dat dat dus geen optie is omdat het er niet om gaat dat het een 1 op 1 kopie is, maar een kopie van een z.g.n. template waarbij in sommige gevallen dus wel nieuwe id's moeten worden gegenereerd voor sommige tabellen en juist in enkele andere dezelfde. Maw: de klassen moeten dus cascaded aangeroepen worden met een copy-mode die dus weer bepaald in de onderliggende klasse of er wel of niet nieuwe id's gegenereerd moeten worden.
Je kunt toch twee verschillende dumps maken. 1 voor het inserten van nieuwe id's, en 1 waarbij de id's al kloppen
Pagina: 1