Seite 1 von 1
MySql Speicherüberlastung/Absturz
Verfasst: Mi, 30. Jul 2014 15:39
von Fischkopp
Hallo,
habe nach Georg`s Tips (gute Einführung =D> ) die direkte Sql-Anbindung statt ODBC getestet, geht gut, aber:
Irgenwie kommt es nach intensiver Benutzung zu Speicherproblemen und einem Absturz. ( Dies Problem habe ich auch reporduzierbar mit der 2.0/CTP-Instalation und ODBC)
Um das zu testen, habe ich auf einem Rechner 1.9 installiert und das folgende Progrämmchen geschrieben:
- sqStress.prg
- Stresstest für MySql
- (2.57 KiB) 381-mal heruntergeladen
Lässt man den Taskmanager parallel zum Programm laufen, läuft der Arbeitspseicher hoch bis zum Absturz mit der anhängenden Fehlermeldung.
Hat jemand ne Idee, was da falsch läuft, resp. ich falsch mache?
Gruß
Reiner
Re: MySql Speicherüberlastung/Absturz
Verfasst: Mi, 30. Jul 2014 16:03
von georg
Hallo, Reiner -
zu jedem :openRecord() gehört ein :close(). Wenn Du das einfügst, vermute ich, dass die Speicherauslastung dramatisch zurückgeht.
Ausserdem öffnest Du nur die Verbindung, liest aber keine Sätze (:Skip()).
Re: MySql Speicherüberlastung/Absturz
Verfasst: Mi, 30. Jul 2014 17:04
von Fischkopp
Hallo, Georg
ja klar, lesen tu ich nicht, war mir hier nicht wichtig...
Meinst du :
oTbl:Close() ?
oder die ganze connection?
Danke
Reiner
Re: MySql Speicherüberlastung/Absturz
Verfasst: Mi, 30. Jul 2014 18:56
von georg
Hallo, Reiner -
die oCon regelt den ganzen Datenverkehr zwischen Deinem Programm und dem MySQL-Server, basierend auf Benutzername und Kennwort, sowie der angeforderten Datenbank. Über die oCon kannst Du z.B. mittels :query() oder :realQuery() SQL-Befehle direkt ausführen, deren Ergebnis Dich nur im Sinne von "hat funktioniert" bzw. "hat nicht funktioniert" interessiert, wie z.B. ein DELETE, ein INSERT oder auch ein CREATE TABLE oder ALTER TABLE, um nur einige zu nennen. Auch ein UPDATE fällt in diese Kategorie.
Das MyResult() basiert auf oCon, da es die oCon zugrunde liegende Rechte nutzt, und ein Result Set zurückliefert, mit dem Dein Programm arbeitet. Wenn die Aufgabe des Result Set beendet ist, wird es geschlossen, analog zu einer DBF-Datei, die Du öffnest, liest, verarbeitest und danach schliesst. Also wäre ein oTbl:close() erforderlich. Ich vermute, dass der MySQL-Server irgendwann ein Resourcen-Problem bekommt und "Quatsch" zurückliefert, der dann zum Abbruch in Deinem Programm führt.
Ich habe normalerweise einen Browser, der auf einem MyResult() basiert, und wenn Sätze bearbeitet werden sollen, mache ich jedesmal (in einem eigenen Thread) ein MyResult() auf, um den Satz zu bearbeiten. Da habe ich selbst bei stundenlangen Sitzungen keine Probleme gehabt, aber, wie schon geschrieben, ich schliesse das MyResult()-Objekt jedesmal, wenn ich damit fertig bin.
Am Ende des Programms sollte man dann auch das oCon schliessen.
Re: MySql Speicherüberlastung/Absturz
Verfasst: Mi, 30. Jul 2014 23:31
von Fischkopp
Hallo, Georg
es mag unrealistisch erscheinen, aber ich habe dieses Problem tatsächlich in einer Anwendung, die ich mit 2.0 , aktuellem CTP und ODBC erstellt habe.
Dort gibt es diverse Menupunkte, die nacheinander abgearbeitet werden müssen. Irgenwann taucht der Fehler auf
, nach einem Neustart geht`s
wieder, die ersten Änderungen sind ja schon geschrieben.
In einem ähnlichen Testlauf wie dem hier beschriebenen kriege ich das Problem weg, wenn ich die connection lösche und neu aufbaue.
Deshalb mein Test mit dieser Methode, würde ja gern auf Hector`s class umsteigen, aber ich krieg`s nicht hin, egal, was wo vor dem :Close() steht
Im Grunde heißt das für mich, so kring ich z.B. kein Programm hin, das in einer Endlosschleife in definierten Zeitintervallen eine SQL-Abfrage startet und Ergebnisse zwischenspeichert, weil irgendwann der Absturz kommt
Naja, egal, es ist spät, morgen auch noch ein Tag und überhaupt
vielen Dank für die Hilfe bisher
Ciao
Reiner
Re: MySql Speicherüberlastung/Absturz
Verfasst: Do, 31. Jul 2014 2:00
von AUGE_OHR
hi Reiner,
vielleicht ist es ein Cl*pper geleitetes Procedure Denken statt OOP.
wie Georg ja darstellte ist oCon deine Verbindung zum SQL Server. Diese wird nur am Ende geschlossen.
mittels o:exec() schickst du nun ein SQL Statement ab und bekommst ein Resultset als Object zurück.
wenn du eine Resultset direkt in ein Array schaufelst dann kannst du danach das Resultset schliessen -> o:Close()
Code: Alles auswählen
...
// Verbindung zu SQL Server
IF !oCon:Connect(cHost,cUser,cPassword,cDbName )
oCon:close
return nil
endif
// Abfrage mit SELECT Statement
if !oCon:Exec(cTable)
oCon:close
return nil
endif
// Resultset Object
oTbl := oCon:result
// umschaufeln in ein Array
oTbl:close()
...
oCon:close()
RETURN
Wenn Hector, für das Resultset Object, statt dem Method Namen o:Close() -> o:Destroy() genommen hätte wäre es eindeutiger.
Wenn man "native" direkt mit der API arbeitet muss man alles manuell machen und selbst "aufräumen" weil sonst die Ressourcen zur Neige gehen.
Re: MySql Speicherüberlastung/Absturz
Verfasst: Do, 31. Jul 2014 7:35
von georg
Guten Morgen,
dann kommentieren wir's mal:
Code: Alles auswählen
oCon:= MySql():New()
IF !oCon:RealConnect(cHost,cUser,cPwd )
MsgBox("keine Verbindung zu " + cHost)
ELSE
IF !oCon:ExisteDb( cDb )
MsgBox("Die Datenbank " + cDb + " existiert nicht !" )
ELSE
start=seconds()
Den :selectDB() würde ich VOR die Schleife legen, da Du ja immer auf die gleiche Datenbank zugreifst.
Code: Alles auswählen
oCon:SelectDb( cDb )
DO WHILE x<viel
oTbl := MyResult():New(oCon,,cTable)
IF oTbl:OpenRecord()
IF oTbl:RecCount()=NIL
MsgBox("Keine Datensätze gefunden: " )
ELSE
xrec=xrec + (oTbl:RecCount())
ENDIF
x=x+1
ENDIF
Und ein oTbl:close() eingefügt, um die mit dem Result Set verbundenen Resourcen wieder freizugeben:
Code: Alles auswählen
oTbl:close()
ENDDO
msgbox("sqStress.prg: "+alltrim(str(viel))+"x `"+cTable+"` gelesen, insgesamt "+alltrim(str(xrec))+" Datens„tze." + chr(13) + chr(10) + "Dauer: " + rwDauer(start) )
ENDIF
oCon:Close()
ENDIF
Damit kann ich das Ganze 200 * durchlaufen und bekomme dieses Ergebnis:
Auch 500 Durchläufe sind machbar:
Und hier die Speicherauslastung:
Auch hat sich die Speicherauslastung nicht bewegt, sie stand die ganze Zeit bei 38%. Versuch es bitte selbst mal!
Re: MySql Speicherüberlastung/Absturz
Verfasst: Do, 31. Jul 2014 9:56
von Fischkopp
Guten Morgen
ja, so habe ich das auch schon gemacht, der Effekt ist der gleiche!
Ich habe das auf Win7 32Bit laufen ( auf XP ist`s das selbe). Verfolgt habe ich das im Taskmanager\Prozesse, da wird der Arbeitsspeicher zum jeweiligen Prozess angezeigt, und der läuft hoch bis zum bitteren Ende. Prozessor-Auslastung und physikal. Speicher sind im grünen Bereich. Ich habe allerdings von dem Win-System zuwenig Ahnung, um das brauchbar interpretieren zu können....
Das verrückte ist ja, wenn man die Schleife 2 mal hintereinander baut mit ` oCon:Close() ` dazwischen, kann man die Abfragen so dosieren, das die 1. Schleife durchläuft und die 2. abstürzt!
Sebst `oCon:Close()` hilft da also nicht !
@Georg
Dein Rechner zeigt `etwas`
mehr Arbeitsspeicher an, als ich hier habe, der Stress kommt natürlich erst bei entsprechend viel Daten/Zugriffen, aber er kommt
@Jimmy
ja, das Grundprinzip habe ich schon verstanden, denke ich, kriege ja bisher alles zum laufen, was ich brauche, mir geht`s um Stabilität....
Wenn ein Programm im Einsatz irgendwann wegen sowas Fehler produziert, und die habe ich definitiv, dann ist das Programm eigentlich für die Tonne
Was meine `Denke`angeht, ist die natürlich nicht wirklich OOP-gemäß, aber so langsam komme ich dahinter, habe ja auch schon Methoden eingebunden und überlagert mit eigenem Senf, geht schon. Mit der Speicherverwaltung hadere ich noch, saubere Variblen-Deklaration ist in xBase wohl essentiell, aber `private` macht oft Zicken und die sind oft in Unterprozeduren (jaja, OOP ist das dann nicht) nicht zu finden, da laß ich im Moment die Finger von.
Re: MySql Speicherüberlastung/Absturz
Verfasst: Do, 31. Jul 2014 10:04
von georg
Hallo, Reiner -
dann sage doch mal was zu Deinem MySQL-Server:
Lokal?
Version?
Dann: öffne mal die MySQL Console und gebe den Befehl
ein, und dann lass mal das Programm laufen und wiederhole den Befehl (zum Kopieren: Cursor nach oben) in der MySQL Console. Vielleicht hilft Dir das beim Lokalisieren der Ursache.
Re: MySql Speicherüberlastung/Absturz
Verfasst: Do, 31. Jul 2014 11:37
von brandelh
wobei GEORG nicht die Connection (oCon) sondern oTbl:close() (den Cursor(), das Ergebnis) geschlossen hat.
oCon erst am Ende des Programmes.