MYSQL: ein reconnect nach "Server is gone away" durchführen

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
hubblec4
Beiträge: 347
Registriert: Sa 25. Jan 2014, 17:50

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hubblec4 »

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

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hde »

hubblec4 hat geschrieben:auch ein abziehen des netzwerksteckers könnte man mit Quellcode nicht aufhalten
genausowenig wie einen Totalabsturz des Progs oder Rechners oder der Netzverbindung.
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

hubblec4
Beiträge: 347
Registriert: Sa 25. Jan 2014, 17:50

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hubblec4 »

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
mir sagt Zeos leider noch gar nichts. Aber schön zu lesen das damit ein reconnect funktioniert.

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?)

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hde »

hubblec4 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.
Gott erhalte dir deinen jugendlichen Optimismus :wink:
Aber fangen wir jetzt keine Diskussion an über Datenbanksicherheit und Konsistenz.
NB: Zeos ist Ersatz für die SQLdb-Module

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von Michl »

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?)
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).

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

hubblec4
Beiträge: 347
Registriert: Sa 25. Jan 2014, 17:50

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hubblec4 »

hde hat geschrieben:
hubblec4 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.
Gott erhalte dir deinen jugendlichen Optimismus :wink:
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).

hubblec4
Beiträge: 347
Registriert: Sa 25. Jan 2014, 17:50

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hubblec4 »

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).
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).
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.

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hde »

hubblec4 hat geschrieben:dann würde mein prog jetzt 100.000 mal die SQL-Komponenten neu erzeugen.
Glückwunsch :wink:
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.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von Michl »

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:

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;
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!):

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
begin
  ZConnection1.Connected:=False;
  ZConnection1.Reconnect;
  ZQuery1.Open;
  ZQuery2.Open;
end;
Weiss gar nicht, ob man das als Bug sehen könnte?!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

hubblec4
Beiträge: 347
Registriert: Sa 25. Jan 2014, 17:50

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hubblec4 »

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 :-)

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hde »

@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

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von Michl »

@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:

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;  
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:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
begin
  try
    MySQL56Connection1.Connected:=False;
    MySQL56Connection1.Connected:=True;
...   
eigentlich ohne weitere Exceptions/Hacks möglich!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hde »

@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.

hubblec4
Beiträge: 347
Registriert: Sa 25. Jan 2014, 17:50

Re: MYSQL: ein reconnect nach "Server is gone away" durchfüh

Beitrag von hubblec4 »

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)

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; 
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.

MmVisual
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

Beitrag von MmVisual »

hde hat geschrieben: Übrigends bei Zeos reicht es meist, im BeforePost-Event einen Reconnect zu machen
Das ist ein guter Tipp, ich probiere das mal aus. Danke!
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten