MYSQL: ein reconnect nach "Server is gone away" durchführen
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
Hi Michl
ja meine Testanordnung ist schon "brutal" ich klaue einfach den Boden, aber anders wüsste ich jetzt nicht wie ich den fehler erzeugen sollte.
denn ich sitze ja nicht direkt vor ort im netzwerk. es ist ja auch oft so das wenn man einen fehler haben will er nicht kommt.
aber der test zu hause kommt dem wie er im netzwerk auftritt ja sehr nahe.
die verbindung wird aus gewissen gründen irgendwie getrennt.
auch ein abziehen des netzwerksteckers könnte man mit Quellcode nicht aufhalten, und besagter "gone away"-error würde auftreten.
du meinstes irgendetwas wäre noch nicht richtig abgeschlossen daher kann der SQLConnector nicht richtig beendet werden oder will nochmal die verbindung haben um abschlussarbeiten durchzuführen (hoffe ich habe das so richtig verstanden).
was müsste ich da tun?
meine SQLQuery anfragen beginnen immer mit dem SqlQuery.Close.
Sollte man das am ende der abfrage nach dem man die Query verarbeitet, nochmal schliessen?
ein SQLTransaction.Commitretaining wird ebenfalls am ende durchgeführt damit die daten auch ordentlich in der DB landen.
LG
hubble
ja meine Testanordnung ist schon "brutal" ich klaue einfach den Boden, aber anders wüsste ich jetzt nicht wie ich den fehler erzeugen sollte.
denn ich sitze ja nicht direkt vor ort im netzwerk. es ist ja auch oft so das wenn man einen fehler haben will er nicht kommt.
aber der test zu hause kommt dem wie er im netzwerk auftritt ja sehr nahe.
die verbindung wird aus gewissen gründen irgendwie getrennt.
auch ein abziehen des netzwerksteckers könnte man mit Quellcode nicht aufhalten, und besagter "gone away"-error würde auftreten.
du meinstes irgendetwas wäre noch nicht richtig abgeschlossen daher kann der SQLConnector nicht richtig beendet werden oder will nochmal die verbindung haben um abschlussarbeiten durchzuführen (hoffe ich habe das so richtig verstanden).
was müsste ich da tun?
meine SQLQuery anfragen beginnen immer mit dem SqlQuery.Close.
Sollte man das am ende der abfrage nach dem man die Query verarbeitet, nochmal schliessen?
ein SQLTransaction.Commitretaining wird ebenfalls am ende durchgeführt damit die daten auch ordentlich in der DB landen.
LG
hubble
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
genausowenig wie einen Totalabsturz des Progs oder Rechners oder der Netzverbindung.hubblec4 hat geschrieben:auch ein abziehen des netzwerksteckers könnte man mit Quellcode nicht aufhalten
Zeos kennt zwar einen Reconnect, und macht den auch sauber, aber einen Datenverlust kannst du nur durch ein sauberes Transaction verhindern, Autocommit o.dgl. reicht da nicht.
Und für einen echten Non-stopp-betrieb brauchst du mehr Hardware.
hde
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
mir sagt Zeos leider noch gar nichts. Aber schön zu lesen das damit ein reconnect funktioniert.hde hat geschrieben: Zeos kennt zwar einen Reconnect, und macht den auch sauber, aber einen Datenverlust kannst du nur durch ein sauberes Transaction verhindern, Autocommit o.dgl. reicht da nicht.
hde
der datenverlust wäre in meinem fall sicher minimal bis gar nicht vorhanden, da ja im vorfeld die verbindung weg ist, können auch keine neuen daten in die DB gelangen.
Nur bei dem Fehler "Lost Connection during Query" da würde ich sagen müsste der datensatz kontrolliert werden.
@Michl
Was aber genau passiert denn wenn man den SQLConnector auf connected:=false setzen will und die verbindung vorher weg ist. wieso versucht er da noch irgendwas an der nicht-bestehenden verbindung rumzudoktorn? (macht es jetzt einen grossen unterschied das ich einen SQLConnector verwende und nicht wie du direkt eine MySQL5.6connection?)
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
Gott erhalte dir deinen jugendlichen Optimismushubblec4 hat geschrieben:der datenverlust wäre in meinem fall sicher minimal bis gar nicht vorhanden, da ja im vorfeld die verbindung weg ist, können auch keine neuen daten in die DB gelangen.

Aber fangen wir jetzt keine Diskussion an über Datenbanksicherheit und Konsistenz.
NB: Zeos ist Ersatz für die SQLdb-Module
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
Sorry, meine Feststellung bezog auf den damaligen Kenntnisstand, da bin ich noch davon ausgegangen, dass immer, wenn Du die Connection trennen willst, es zu diesem Fehler kommt. Ich finde es auch gut, dass eine Exception geworfen wird, da weiss man als User, dass etwas mit der Verbindung nicht mehr in Ordnung ist. Diese Exception kann man ja abfangen und auswerten (wie Du das ja auch machst).hubblec4 hat geschrieben:@Michl
Was aber genau passiert denn wenn man den SQLConnector auf connected:=false setzen will und die verbindung vorher weg ist. wieso versucht er da noch irgendwas an der nicht-bestehenden verbindung rumzudoktorn? (macht es jetzt einen grossen unterschied das ich einen SQLConnector verwende und nicht wie du direkt eine MySQL5.6connection?)
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
hde hat geschrieben:Gott erhalte dir deinen jugendlichen Optimismushubblec4 hat geschrieben:der datenverlust wäre in meinem fall sicher minimal bis gar nicht vorhanden, da ja im vorfeld die verbindung weg ist, können auch keine neuen daten in die DB gelangen.![]()
Aber fangen wir jetzt keine Diskussion an über Datenbanksicherheit und Konsistenz.
NB: Zeos ist Ersatz für die SQLdb-Module
Ja ich bin da Optimistisch...mag sicher daran liegen das ich noch keine sooo megaschlechten erfahrungen gemacht habe.(hoffe mal das es mir auch NIE passiert^^)
Zeos: muss ich da für Lazarus was einbinden/neukompilieren? oder ist es einfach so das ich Zeos in die Uses schreiben kann? (bin noch untergwegs uns kanns nicht gleich testen).
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
Nein der Fehler entsteht nicht bei der trennung sondern vorher schon, und leider weis ich nicht wieso(möglichkeiten wurden hier ja schon einige aufgezählt).Michl hat geschrieben:Sorry, meine Feststellung bezog auf den damaligen Kenntnisstand, da bin ich noch davon ausgegangen, dass immer, wenn Du die Connection trennen willst, es zu diesem Fehler kommt. Ich finde es auch gut, dass eine Exception geworfen wird, da weiss man als User, dass etwas mit der Verbindung nicht mehr in Ordnung ist. Diese Exception kann man ja abfangen und auswerten (wie Du das ja auch machst).
Allerdings bekommt man die Exception wenn man auf die DB zugreift..und dann ist es ja recht einfach. Abfangen, auswerten, verarbeiten.
zu meinem Workaround hätte ich nochmal eine frage.
Da ich ja den SQLConnector und die SQLTransaction jetzt als Globale Laufzeit variablen habe und diese bei einem Fehler immer neu erzeugt werden, und die alten variablen nicht zerstört/beendet werden...
wächst dann mein Programm im Speicher immer weiter an? also müssen dafür resourcen bereit gestellt werden?
sagen wir mal mein programm wird 12h genutzt und es kommt zu 100.000 Fehlern (also jetzt mal grob übertrieben)
dann würde mein prog jetzt 100.000 mal die SQL-Komponenten neu erzeugen.
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
Glückwunschhubblec4 hat geschrieben:dann würde mein prog jetzt 100.000 mal die SQL-Komponenten neu erzeugen.

Also wennn ein User den Netzstecker zieht oder im laufenden Betrieb von LAN auf WLAN umstellt, dann ist er's selber schuld und dann reicht eine Fehlermeldung.
Aber bei 2 Errors/Sec, da würd ich die Ursache suchen.
Übrigends bei Zeos reicht es meist, im BeforePost-Event einen Reconnect zu machen. Bleibt aber das Risiko zwischen before- und after-post. Oder wenn die DB ganz down bleibt.
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
Ich habe mal ein wenig debuggt. Der Fehler tritt auf, da die Verbindung weg ist, wird bei einem "Connection.Connected:=False" oder "Connection.Free" ein Rollback versucht, der nicht mehr funktioniert. Folgender häßlicher Hack funktioniert: Damit wäre eine Neuerstellung der Connection und Transaction nach einem TimeOut nicht mehr notwendig.
Oder Du verwendest Zeos, da ist das gleiche Resultat so möglich (funktioniert mit und ohne TimeOut!):
Weiss gar nicht, ob man das als Bug sehen könnte?!
Code: Alles auswählen
type
{ THackTransaction }
THackTransaction = Class(TSQLTransaction)
public
procedure CloseTrans;
end;
...
procedure THackTransaction.CloseTrans;
begin
inherited CloseTrans;
end;
...
procedure TForm1.Button2Click(Sender: TObject);
begin
try
MySQL56Connection1.Connected:=False;
MySQL56Connection1.Connected:=True;
Open;
except
on e: exception do begin
ShowMessage('TForm1.Button2Click.Fehler: '+e.Message);
Reconnect;
Open;
end;
end;
end;
procedure TForm1.Reconnect;
begin
try
THackTransaction(SQLTransaction1).CloseTrans;
MySQL56Connection1.Connected:=False;
MySQL56Connection1.Connected:=True;
except
on e: exception do
ShowMessage('TForm1.Reconnect.Fehler: '+e.Message);
end;
end;
Oder Du verwendest Zeos, da ist das gleiche Resultat so möglich (funktioniert mit und ohne TimeOut!):
Code: Alles auswählen
procedure TForm1.Button2Click(Sender: TObject);
begin
ZConnection1.Connected:=False;
ZConnection1.Reconnect;
ZQuery1.Open;
ZQuery2.Open;
end;
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
danke Michl für deine mühen.
deinen Quellcode werde ich versuchen umzusetzen.
Du erzeugst "nur" einen Transaction-Hack und das mit dem SQLConnector funktioniert dann... mmh schon seltsam wie alles zusammenhängt.
@hde
es gibt natürlich keine 100.000 abstürtze
deinen Quellcode werde ich versuchen umzusetzen.
Du erzeugst "nur" einen Transaction-Hack und das mit dem SQLConnector funktioniert dann... mmh schon seltsam wie alles zusammenhängt.
@hde
es gibt natürlich keine 100.000 abstürtze

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
@Michl, bei Zeos reicht es meist, im BeforePost-Event einen Reconnect zu machen, der Connect ist dann in jedem Falle, egal ob er weg war oder nicht, wieder da und die ZQueries noch offen, auch die Updates, und der Post kann stattfinden. Nur ein Reconnect wenn keine Verbindung besteht schlägt ffehl.
hde
hde
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
@hde: Anders herum, das Verhalten von Zeos ist i.O., ein Reconnect sollte nach einer verlorenen Verbindung möglich sein.
Das Problem in SQLdb ist nur, dass immer wieder ein Rollback versucht wird, wenn man die "verlorengegangene" Verbindung trenn will -> es wird immer wieder eine neue Exception geworfen, man hat somit keine Chance diese aufzulösen. Man braucht eigentlich nur zu testen, ob die Transaction beim Rollback (bei .Free bzw. .Connected:=False) überhaupt noch existiert:
Ich habe mal den Patch im Bugtracker hochgeladen: http://bugs.freepascal.org/view.php?id=26505
@hubblec4: Wenn Du willst, brauchst Du nur die Procedure "Rollback" in der Unit "SQLdb" entsprechend ersetzen, dann ist:eigentlich ohne weitere Exceptions/Hacks möglich!
Das Problem in SQLdb ist nur, dass immer wieder ein Rollback versucht wird, wenn man die "verlorengegangene" Verbindung trenn will -> es wird immer wieder eine neue Exception geworfen, man hat somit keine Chance diese aufzulösen. Man braucht eigentlich nur zu testen, ob die Transaction beim Rollback (bei .Free bzw. .Connected:=False) überhaupt noch existiert:
Code: Alles auswählen
procedure TSQLTransaction.Rollback;
begin
if Active then
begin
CloseDataSets;
If LogEvent(detRollback) then
Log(detRollback,SRollingBack);
if not Assigned(FTrans) then //Das hier ist neu
CloseTrans
else
if SQLConnection.RollBack(FTrans) then
begin
CloseTrans;
FreeAndNil(FTrans);
end;
end;
end;
@hubblec4: Wenn Du willst, brauchst Du nur die Procedure "Rollback" in der Unit "SQLdb" entsprechend ersetzen, dann ist:
Code: Alles auswählen
procedure TForm1.Button2Click(Sender: TObject);
begin
try
MySQL56Connection1.Connected:=False;
MySQL56Connection1.Connected:=True;
...
Code: Alles auswählen
type
TLiveSelection = (lsMoney, lsChilds, lsTime);
TLive = Array[0..1] of TLiveSelection;
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
@Michl, wenn du dich reinkniest machst du es gründlich und es kommt was gutes raus. Aber auch bei zeos gibt es noch ein kleines Prob; ein reconnect wenn die Verbindung fehlt ist abzufangen, aber wenn dann die Verbinbindung wiederkommt, gibts eine exception. Bin aber leider mit Arbeit völlig zugemüllt, das Prob muss etwas warten.
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
wow Michl
das hast du ja super rausgefunden. bin mal gespannt ob das Lazarus team das alles so umsetzen kann.
ein ganz klein wenig anders sieht meine "TSQLTransaction.Rollback" prozedure aus. (kann das an der anderen version von Lazarus liegen)
ich werde aber bei dem schönen wetter heute baden fahren und abends dann alles mal ausprobieren.
Auf jedenfall super rechtherzlichen dank das du dich meines problems sooo dolle angenommen hast.
Vll ändert ja das LazarusTeam die sache auch von haus aus gleich.
das hast du ja super rausgefunden. bin mal gespannt ob das Lazarus team das alles so umsetzen kann.
ein ganz klein wenig anders sieht meine "TSQLTransaction.Rollback" prozedure aus. (kann das an der anderen version von Lazarus liegen)
Code: Alles auswählen
procedure TSQLTransaction.Rollback;
begin
if active then
begin
closedatasets;
If LogEvent(detRollback) then
Log(detRollback,SRollingBack);
// und hier müsste ich dann dein "neuen" code einfügen.
if TSQLConnection(Database).RollBack(FTrans) then // die Zeile ist etwas anders als bei deinem beispiel
begin
CloseTrans;
FreeAndNil(FTrans);
end;
end;
end;
Auf jedenfall super rechtherzlichen dank das du dich meines problems sooo dolle angenommen hast.
Vll ändert ja das LazarusTeam die sache auch von haus aus gleich.
-
- Beiträge: 1582
- Registriert: Fr 10. Okt 2008, 23:54
- OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
- CPU-Target: 32/64Bit
Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh
Das ist ein guter Tipp, ich probiere das mal aus. Danke!hde hat geschrieben: Übrigends bei Zeos reicht es meist, im BeforePost-Event einen Reconnect zu machen
EleLa - Elektronik Lagerverwaltung - www.elela.de