Fatal error: Maximum execution ...

Hi

Zu Beginn hatte ich bei Usereingaben Diese direkt abgearbeitet, wofür ich den Script für weitere Eintragungen für die Zeit der Verarbeitung sperrte.
Mit stetig wachsender DB wurde die Verarbeitungszeit aber extrem verschlechtert, wobei ich mit einer Eingabe den Script für 2 Minuten sperren konnte.

Die User können 20 Eingaben auf ein Mal absenden ... macht das auch nicht schneller.

Die Sperrung machte ich, da die Verarbeitung der nächsten Eingabe erst NACH der vorherigen Verarbeitung anfangen darf.

Bei Test's mit der DB, wo ich versuchte, den Script mehrfach parallel aufzurufen, verarbeiteten leider alle Scripte genau den gleichen Datensatz, obwohl ich diesen direkt zu Anfang auf der entsprechenden Tabelle lösche ... trotzdem war er noch drin.
Erst, wenn der Verarbeiter abgeschlossen wurde, scheint der gelöschte Eintrag wirklich weg zu sein.

Momentan probiere ich mit JavaScript den Script sich selber in einem PopUp aufrufen zu lassen und den aktiven Script (also sich selbst) zu beenden ...

Soll heißen, ich rufe den Script auf (nennen wir ihn A) ... der arbeitet etwas, ruft sich selbst im PopUp auf (B) und beendet sich (A).
Somit hätte ich immer nur 1 Script aktiv am Laufen und durch den Neustart des Script erhoffe ich mir einen Reset der 60 Sekunden.

MfG
Posti
 
Posti hat gesagt.:
Zu Beginn hatte ich bei Usereingaben Diese direkt abgearbeitet, wofür ich den Script für weitere Eintragungen für die Zeit der Verarbeitung sperrte.
Mit stetig wachsender DB wurde die Verarbeitungszeit aber extrem verschlechtert, wobei ich mit einer Eingabe den Script für 2 Minuten sperren konnte.
Warum arbeitest Du nicht mit Transaktionen und Tabellensperren?
Ich kann mir vorstellen, dass die in MySQL eingebauten Mechanismen schneller und sicherer sind, als selbstgeschriebene Sperren.


Posti hat gesagt.:
Die User können 20 Eingaben auf ein Mal absenden ... macht das auch nicht schneller.

Die Sperrung machte ich, da die Verarbeitung der nächsten Eingabe erst NACH der vorherigen Verarbeitung anfangen darf.

Bei Test's mit der DB, wo ich versuchte, den Script mehrfach parallel aufzurufen, verarbeiteten leider alle Scripte genau den gleichen Datensatz, obwohl ich diesen direkt zu Anfang auf der entsprechenden Tabelle lösche ... trotzdem war er noch drin.
Erst, wenn der Verarbeiter abgeschlossen wurde, scheint der gelöschte Eintrag wirklich weg zu sein.
Warum wird bei verschiedenen Eingaben auf demselben Datensatz gearbeitet? Schildere doch mal Dein Konzept (Daten und Ablauf). Mir erscheint das etwas suspekt, da ich nicht ganz verstehe, wozu das nötig ist.

Posti hat gesagt.:
Momentan probiere ich mit JavaScript den Script sich selber in einem PopUp aufrufen zu lassen und den aktiven Script (also sich selbst) zu beenden ...

Soll heißen, ich rufe den Script auf (nennen wir ihn A) ... der arbeitet etwas, ruft sich selbst im PopUp auf (B) und beendet sich (A).
Somit hätte ich immer nur 1 Script aktiv am Laufen und durch den Neustart des Script erhoffe ich mir einen Reset der 60 Sekunden.
Ich habe das Gefühl, Du bist im Moment auf etwas fixiert und schreibst einen Workaround nach dem anderen.

Was schreibst Du denn da in die Datenbank, dass es so lange dauert? An sich sind 20 Datensätze nicht besonders viel.

Gruß hpvw
 
Hehe

Es geht um einen Lose-Script (Klamm-Lose).
Die User zahlen Lose ein, diese werden wild in Konten-Tabelle verteilt, und irgendwann wieder rausgehauen.

Auf Deutsch: Nen Lose-Doppler .... aber kein 0-8-15 Teil

Die User können bis zu 20 Konten am Stück erstellen (also pro Aufruf, am Stück gehen mehr ... mehrere Aufrufe direkt nacheinander).

Diese 'Lose' müssen dann, nach Vorgabe der User, in der Kontenliste verteilt werden und, wenn's soweit ist, werden die auch ausgezahlt (und dabei in einer anderen Liste eingetragen).

Ich denke, daß am meisten Rechenzeit dabei draufgeht, das gerade zu Füllende Konto ausfindig zu machen, obwohl die DB-Anfrage mit zunehmender DB-Größe auch spürbar langsamer werden.

Der User-Eintrag sagt dem Script, wieviele Lose nach welcher Methode verteilt werden sollen, und nach dieser Methode richtet sich der Script.

Da mehrere User gleichzeitig, oder wenige User in kurzem Abstand direkt hintereinander einzahlen können, brauche ich die Zwischenspeicherung, da ansonsten der Script bei der Verteilung gesperrt wäre *denk*.
Momentan sperre ich den Script, indem ich in einer Tabelle einen Merker auf 1 setze (bzw. um 1 erhöhe). Wenn der Merker > 1 ist, bricht der Script direkt ab (da der parallele Lauf nicht funktioniert).
Beim beenden des Script (momentan nach 2 Min) wird der Merker wieder um 1 vermindert, der nächste Aufruf kann kommen.

Momentan, mit knapp 600.000 Konten, bekomme ich 20 Eintragungen abgearbeitet ... also in den 2 Minuten (mit den ganzen Sleep's im Script).

Vorhin kam mir die Idee, beim rumsuchen im Forum, daß ich beim Beenden des Script den Script auch selber wieder in einem PopUp aufrufen könnte ... nur macht er mir noch kein PopUp auf :-/ .... naja, irgendwas ist ja immer *g*

Ok, ist jetzt keine Doktor-arbeit reife Erklärung, war aber halbwegs verständlich .... oda?

MfG
Posti
 
Posti hat gesagt.:
Ok, ist jetzt keine Doktor-arbeit reife Erklärung, war aber halbwegs verständlich .... oda?
Halbwegs :D
Ich versuche mal zu meinem Verständnis ein paar Behauptungen aufzustellen (bitte bestätigen oder verneinen):

Behauptung 1:
Es handelt sich um Lose dieser über Google gefundenen Firma (kannte ich vorher gar nicht).

Behauptung 2:
Der User entscheidet nicht direkt in einem Formular über die Konten, in die seine Lose eingetragen werden sollen, sondern wählt Strategien, nach denen die Konten ermittelt werden.

Behauptung 3:
Es sind einige SELECTs nötig, um die Konten zu ermitteln.

Behauptung 4:
Die Veränderung der Konten hat Einfluss auf die Verteilung der Lose anderer User.

Und dann noch Fragen:
Wann "ist es soweit" (, dass ausgezahlt wird)? Wie ermittelst Du das? Wo ermittelst Du das? Wann ermittelst Du das?

Gruß hpvw
 
hpvw hat gesagt.:
Halbwegs :D
Ich versuche mal zu meinem Verständnis ein paar Behauptungen aufzustellen (bitte bestätigen oder verneinen):

Behauptung 1:
Es handelt sich um Lose dieser über Google gefundenen Firma (kannte ich vorher gar nicht).
Jupp
Behauptung 2:
Der User entscheidet nicht direkt in einem Formular über die Konten, in die seine Lose eingetragen werden sollen, sondern wählt Strategien, nach denen die Konten ermittelt werden.
Stimmt auch.
Die User können wählen, ob die Lose prozentual, komplett oder in Happen auf/ab dem vordersten Konto, einem beliebigem Konto, einem zufälligen Konto ..... jo, nicht ganz einfach ...
Behauptung 3:
Es sind einige SELECTs nötig, um die Konten zu ermitteln.
Joha ... ne ganze Menge
Behauptung 4:
Die Veränderung der Konten hat Einfluss auf die Verteilung der Lose anderer User.
Auch, aber nur soweit, wenn ein Konto herausfällt
Und dann noch Fragen:
Wann "ist es soweit" (, dass ausgezahlt wird)? Wie ermittelst Du das? Wo ermittelst Du das? Wann ermittelst Du das?
Sobald die Konten mindestens den Doppelten Kontostand des eingezahlten Betrag aufweisen ... daher der Name Doppler.

**EDIT**
Wie: Ist Kontostand >= Einsatzx2 -> auszahlen
Wo: Im Verteilerscript (der mit dem Fehler)
Wann: Alle 2 Minuten *g* ... bei jedem Verteiler-Durchlauf.
Sobald beim Verteilen ein Konto auszahlungsreif wird, wird ein weiterer Block ausgeführt, der die Auszahlung und umschreibung in die andere Liste, die 'Ausgezahlt' Liste vornimmt.
Weiter wird noch ein LOG geführt ... auch ne Tabelle, die ich auch für eine Art Kontoauszug nutze.
**EDIT ENDE**


:p
10 von 10 Punkte .... Glückwunsch

Anders als bei einem herkömmlichem Doppler kann der USer entscheiden, wie die Lose verteilt werden sollen.
Wesendlich mehr Aufwand (für mich), aber meiner Meining nach wesendlich gerechter, da so auch User, die gerade erst eingezahlt haben, Ihre Lose wieder herausbekommen können.

Wenn der erste User ein Konto anlegt, wird er wohl alle seine Lose (also der Einsatz) auf sein Konto gutgeschrieben bekommen.
Wenn der 2.te User nun seine Lose auf das erste Konto einzahlt, steigt nur der Kontostand des ersten Konto.
Je nach gewählter Methode werden die Lose weit in der Kontenliste gestreut und auch in der Mitte (oder am Ende) können Konten herausfallen.

Bei einem 'normalem' Lose-Doppler bleiben die User irgendwann auf der Strecke, was ich dadurch unterbinden will, da ich Zinsen ins System mit einzahle.
Der Ablauf ist genau so, nur, daß ich (als Turbo-Einzahler) für die Einzahlung kein Konto bekomme, ist also eine Art Spende an die User.


Darf ich hier ne URL posten? (vom alten deaktivierten Script)
Ist ja nen eigener Script ... daher *lieb frag*

MfG
Posti


PS:Ihr seit ganz schön auf Trapp ... dabei wollte ich doch gar nicht so viel verraten *gg* ... meine Klamm-ID wird wohl nun kein größeres Problem sein *denk*
 
Zuletzt bearbeitet:
Sorry für Doppelpost ... hatte in diesem Post einiges überlesen *schäm*

hpvw hat gesagt.:
Wenn ich das richtig interpretiere, geht es bei Dir hauptsächlich um INSERTs oder UPDATEs. Da wird es schwierig. Bei SELECTs hilft z.B. Query-Cache, Abfragen vermeiden (durch JOINs, statt mehrfacher Abfragen), Felder explizit angeben, statt mit * zu arbeiten.

Wieviele Eingaben macht der User denn auf einen Streich, dass das so langsam wird?
Im normalen Script-Lauf maximal 20 Konten am Stück (bis zu 30000 Lose)

Der Query-Cache wird mir glaube nicht viel helfen, da ich bei jedem Durchlauf in so ziemlich jeder Tabelle was ändere.
Aber sonst habe ich einen einheitlichen Schreibstyle für meine Anfragen, alles mySQL-mäßige wird GROSS, alles andere klein geschrieben, keine unnötigen Leerzeichen ect, damit die Anfragen übereinstimmen können.

Wenn ein User allerdings 100x 20 Konten a 30000 Lose nach einer Häppchen Methode (100er Lose-Happen) einzahlt, sind einige Anfragen nötig, um diese Lose zu verteilen und zu prüfen, ob ein Konto auszahlungsreif ist.
Kann ich beim Updaten direkt den neuen Stand abfragen?

Also eine Kombination aus Update und Select?

Mir fehlt eindeutig nen mySQL-Buch .... HTML, JavaScript und PHP hab ich schon *ganz stolz drauf bin*

MfG
Posti
 
So, ich versuche mal etwas strukturiert zu schreiben, aber ich vermute mal das wird schief gehen:

Bei meiner Behauptung 3 würde ich mit der Optimierung ansetzen:
Hast Du Querys die in der Abfrage-Schleife eines anderen Querys ausgeführt werden?
Dann solltest Du JOINs oder LEFT JOINs verwenden.

Machst Du im PHP-Code noch mehrere Abfragen und Berechnungen mit den erhaltenen Werten?
Dann solltest Du diese Berechnungen evtl. von MySQL machen lassen und Alias-Felder verwenden, um direkt im WHERE das Ergebnis zu begrenzen.
Gegebenenfalls kannst Du mit GROUP BY und Subselects arbeiten.

Kurz: Tue alles, um erstens Querys zu vermeiden und zweitens die in PHP zu verarbeitenden Ergebniszeilen zu begrenzen.

Posti hat gesagt.:
Wie: Ist Kontostand >= Einsatzx2 -> auszahlen
Wo: Im Verteilerscript (der mit dem Fehler)
Wann: Alle 2 Minuten *g* ... bei jedem Verteiler-Durchlauf.
Sobald beim Verteilen ein Konto auszahlungsreif wird, wird ein weiterer Block ausgeführt, der die Auszahlung und umschreibung in die andere Liste, die 'Ausgezahlt' Liste vornimmt.
Weiter wird noch ein LOG geführt ... auch ne Tabelle, die ich auch für eine Art Kontoauszug nutze.
Das generiert natürlich eine Menge Serverlast und bremst damit sämtliche Prozesse auf dem Server. Da sollte man mal herausfinden, wie z.B. Banken ihre Konten fortführen. Ich glaube nicht, dass dies in einem durchgehenden Prozess geschieht.
Dazu eine Idee:
Immer wenn Du ein Konto "anfassen" willst, also wenn jemand den Kontostand abruft oder Änderungen an dem Konto vorgenommen werden sollen, wird (nur) dieses aktualisiert und ggf. Zwischenwerte berechnet. Bei 600.000 Konten werden ja nicht immer alle auf einmal abgefragt.

Posti hat gesagt.:
10 von 10 Punkte .... Glückwunsch
Danke

Posti hat gesagt.:
Anders als bei einem herkömmlichem Doppler kann der USer entscheiden, wie die Lose verteilt werden sollen.
So genau kenne ich mich mit diesen Systemen nicht aus, daher Versuche ich aus dem, was ich jetzt darüber gelernt habe, nur Ideen für Konzepte zu nennen, die das Skript schneller machen können.

Posti hat gesagt.:
Wesendlich mehr Aufwand (für mich), aber meiner Meining nach wesendlich gerechter, da so auch User, die gerade erst eingezahlt haben, Ihre Lose wieder herausbekommen können.
Dein Aufwand spielt keine Rolle, Gerechtigkeit spielt keine Rolle, nur die Performance und damit die Serverlast ist wichtig :D :p

Posti hat gesagt.:
Darf ich hier ne URL posten? (vom alten deaktivierten Script)
Ist ja nen eigener Script ... daher *lieb frag*
Weiss ich nicht, schreib doch mal einen Mod des Forums per PN an.

Posti hat gesagt.:
Im normalen Script-Lauf maximal 20 Konten am Stück (bis zu 30000 Lose)
Du bildest doch nicht jedes Los einzeln ab!? Als Anregung eine (vereinfachte) Darstellung meiner Idee:
Tabelle konten: id, ...
Tabelle user: id, name, ...
Tabelle lose: id, userID, kontoID, anzahl
Ich hoffe, ich schätze Dich richtig ein, dass Du mit der knappen Darstellung etwas anfangen kannst.

Posti hat gesagt.:
Der Query-Cache wird mir glaube nicht viel helfen, da ich bei jedem Durchlauf in so ziemlich jeder Tabelle was ändere.
Ja, da hast du recht.

Posti hat gesagt.:
Aber sonst habe ich einen einheitlichen Schreibstyle für meine Anfragen, alles mySQL-mäßige wird GROSS, alles andere klein geschrieben, keine unnötigen Leerzeichen ect, damit die Anfragen übereinstimmen können.
So ähnlich mache ich das auch, Unterschiede bei den Bezeichnern s.o., ist von Java so drin, kann ich nichts gegen machen.

Posti hat gesagt.:
Wenn ein User allerdings 100x 20 Konten a 30000 Lose nach einer Häppchen Methode (100er Lose-Happen) einzahlt, sind einige Anfragen nötig, um diese Lose zu verteilen und zu prüfen, ob ein Konto auszahlungsreif ist.
Jein.
Deine DB-Struktur sollte es ermöglichen, in einem einzigen Query alle auszahlungsreifen Konten zu ermitteln. Sonst solltest Du die Struktur der DB noch mal überdenken.
Die Umbuchungen sind evtl. auch in ein oder zwei UPDATEs mit Subquery als Entscheider im WHERE zu lösen. Aber wenn ich mir darüber jetzt genauere Gedanken mache, dann explodiert mein Kopf, es raucht schon.

Posti hat gesagt.:
Kann ich beim Updaten direkt den neuen Stand abfragen?

Also eine Kombination aus Update und Select?
Meines Wissens nicht. Du kannst höchstens wie eben angedeutet mehrere UPDATEs zusammenfassen, indem Du ein SELECT i.V.m. dem Schlüsselwort IN als Bedingung für ein UPDATE nutzt.
Dann musst Du nicht viele einzelne UPDATEs ausführen. Das wäre wieder ein Punkt, wo man eine Schleife in PHP sparen kann.

Bei der oben beschriebenen Struktur würde ich beim Eintragen von neuen Usereinzahlungen auch nicht mit UPDATE, sondern nur mit INSERT arbeiten. Sonst wäre jedesmal eine Prüfung nötig, um dann ein UPDATE oder einen INSERT zu machen. Das stünde Zusammenfassungen evtl. im Weg. Du könntest statt dessen eine negative Anzahl zulassen. In Abfragen könntest Du mit GROUP BY nach userID und kontoID und der Funktion SUM arbeiten.

Das waren jetzt einige Ideen. Du musst mal schauen, was davon auf Dein Konzept anwendbar ist.

Die Sperre würde ich trotzdem nicht über eine eigene Tabelle, sondern über die schon angesprochenen MySQL-Funktion machen.

Gruß hpvw
 
... und da sagst DU, Dir raucht der Kopf :rolleyes:

Bei User-kontoanlegungen werden die Datensätze klar mit INSERT angehangen, ist ja jedesmal ein eigenes Konto.
UPDATE wird genutzt, um den Kontostand der einzelnen Konten anzuheben, bzw. REF-Verdienst (von User, der über einen Werber-Link zum Script kam) oder den Kontostand des internen Lose-Konto zu bearbeiten.

Mit Group Join und so'n Kram ... hab ich schon Mal irgendwo gesehen, aber nicht sondelrich verstanden *schäm*

Ob ein Konto auszahlungsreif ist, muß ich nach JEDER Einzahlung prüfen, da ansonsten bei einer Multi-Einzahlung (mehr als 1 Konto am Stück erstellen) ein Konto überfüttert werden kann, und mit dem vielfachem Einsatz erst ausgeworfen.

Da mir aufgefallen ist, daß bei entsprechend großer Konten-Liste die Query's länger dauern (ehrlich ), habe ich im neuesten Script die Konten-Liste aufgeteilt.
Um nicht nach jeder Verteilung JEDE Kontenliste auf 'reife' Konten abfragen zu müssen, merke ich mir, wo's ein Konto zum Rauswerfen gab.

Gibt's irgendwo nen deutsches (ist wirklich wichtig ... also deutsch) Tut zum Thema mySQL ?
Gerade mit Join, Group, Leave, Alias und so'nem Zeugs. Wenn's ne Erklärung bei gibt, auch nicht übel *g*

Ach ja ... ohne großartig nen Link zu Posten, der oben gepostete Link der Firma (Klamm) ... die haben auch nen Forum ... und bei 'Externe Loseseiten' hab ich kurz vor Jahreswechsel nen Thread erstellt ... da gibt's weit über 1000 Seiten Höhen und Tiefen meines Script ... auch mit bisher einem Doofheits-Tiefschlag (klicke NIE 'ok' im Confixx ... kommt nicht wirklich gut *g*)

Wenn ich den Verteiler nach einer Minute ein PopUp öffnen lasse, in dem der Verteiler erneut gestartet wird, bekomme ich den Fehler nicht mehr ... nur muß der Verteiler in einem Browser laufen, da dem Cronjob das PopUp wirklich wurscht ist.

MfG
Posti
 
Posti hat gesagt.:
... und da sagst DU, Dir raucht der Kopf :rolleyes:
Vor allem, weil ich mir im Geiste eine Modellierung überlegt habe und darauf ein Query gedanklich laufen ließ. Aber es macht wenig Sinn, da Du ja sicher eine andere Datenbank hast.

Posti hat gesagt.:
Mit Group Join und so'n Kram ... hab ich schon Mal irgendwo gesehen, aber nicht sondelrich verstanden *schäm*
...
Gibt's irgendwo nen deutsches (ist wirklich wichtig ... also deutsch) Tut zum Thema mySQL ?
Gerade mit Join, Group, Leave, Alias und so'nem Zeugs. Wenn's ne Erklärung bei gibt, auch nicht übel *g*
So schwer ist das gar nicht. Grundlage von relationalen Datenbanken sind mathematische Relationen. Wenn man sich zumindest ein wenig mit der Theorie dahinter (z.B. kartesisches Produkt, welches dem JOIN entspricht) beschäftigt hat, fällt es wesentlich leichter.
Als Referenz kann natürlich die Doku von MySQL dienen, allerdings ist die englische Version umfassender.
Das MySQL Datenbankhandbuch von Guido Stepken finde ich auch nicht schlecht. Er hat auch ein paar kurze Tutorials für Einsteiger. Vor allem das Tutorial "Kleine und größere, typische Probleme beim Verständnis von JOINS" könnte Dich interessieren oder auch "Wie finde ich heraus, warum manche Befehle so langsam sind ?".

Posti hat gesagt.:
Wenn ich den Verteiler nach einer Minute ein PopUp öffnen lasse, in dem der Verteiler erneut gestartet wird, bekomme ich den Fehler nicht mehr ... nur muß der Verteiler in einem Browser laufen, da dem Cronjob das PopUp wirklich wurscht ist.
Linux und Cron-Job ist zwar nicht so mein Thema, aber kann man nicht auch einen regelmäßig (z.B. alle zwei Minuten ;)) wiederkehrenden Cron-Job einrichten?

Gruß hpvw
 
hpvw hat gesagt.:
...
Linux und Cron-Job ist zwar nicht so mein Thema, aber kann man nicht auch einen regelmäßig (z.B. alle zwei Minuten ;)) wiederkehrenden Cron-Job einrichten?
...

Meine Möglichkeiten in Sachen Cron-Job sind Serverseitig glaube auf 3x am Tag (bissle wenig) oder über CRONJOB.de, da geht's alle 5 Min.
Ok, es wird direkt gesagt, daß die Cron-Jobs nicht zu 100% genau dann ausgeführt, wann sie geplant wurden, aber mit einem leichten Versatz kann ich durchaus leben ... dafür sind die Job's ja gratis :)


Die mySQL-Links werde ich mal im Laufe der Zeit durchklickern, erhoffe mir dadurch einige Stunden Lesespass *froi* (<-- freu) und vll nen bischen mehr Verständniss zum Thema Anfragen.

Mal schaun, was sich nun noch alles ergibt, mit den 60 Sekunden muß ich wohl leben ... naja, irgendwas ist ja immer *hehe*

MfG
Posti
 
Zurück