[gelöst] MySql auto-reconnect

Alles rund um die Programmierung mit Qt
Antworten
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

[gelöst] MySql auto-reconnect

Beitrag von pfid »

Hallo,

ich wollte fragen ob es irgendeine Patentlösung gibt, um die Verbindung zu einer MySql Datenbank automatisch wiederherzustellen wenn man eine QSqlQuery ausführen möchte und die Verbindung unterbrochen wurde.
Ich habe nur beschränkt Möglichkeiten, das Timeout serverseitig hochzusetzen (vom Provider aus steht das irgendwo um eine Minute). Ich will nicht zwangsläufig eine stundenlange Verbindung, ich möchte aber keine Fehler bekommen bzw. nicht das Programm neu starten müssen wenn die Verbindung weg ist. Ein Timer-Event dass einmal pro Minute eine Abfrage ausführt möchte ich auch nicht unbedingt machen, wäre am Ende aber vielleicht eine Notlösung. Dann aber im eigenen Thread, da ich nicht will dass mir der Timer irgendwie im Gui Thread umpfuscht.

Am liebsten wärs mir, wenn direkt beim QSqlQuery::exec festgestellt werden könnte, ob die Verbindung weg ist, und diese dann direkt neu aufgebaut wird. Also vielleicht so:

Code: Alles auswählen

if (!query.exec())
   maybe_reconnect_and_repeat_query(query);
Hatte sowas ähnliches schonmal versucht, und nach einem QSqlDatabase::close() und QSqlDatabase::open() war die Verbindung immer noch nicht wieder da. Wie macht man das richtig?

Richtig nervig wirds dann allerdings, wenn ich so einen Mechanismus auch für die QSqlTableModels implementieren muss. Da müsste ich dann beim auto-Submit bzw. beim select mitbekommen, dass die Verbindung weg ist. Dann die Verbindung neu aufbauen und die Abfrage erneut ausführen.

Qt bringt da meines Wissens noch nichts mit (nicht für MySql, für die anderen iirc schon). Hat da jemand eine gute Idee?


[edit] gelöst, ähnlich wie hier:

http://qtforum.de/forum/viewtopic.php?t ... 51738fd333

qt quellen/qmysqldriver::open() angepasst und manuell ein mysql_options mit MYSQL_OPT_RECONNECT eingefügt. funktioniert tadellos.
Zuletzt geändert von pfid am 10. August 2008 20:07, insgesamt 2-mal geändert.
patrikD
Beiträge: 22
Registriert: 21. Mai 2007 14:01

Beitrag von patrikD »

Hi pfid,

bin mir nicht ganz sicher aber versuch mal unter QSqlDatabase::setConnectOptions:
MYSQL_OPT_RECONNECT=1

Dann dürfte das der Server für dich übernehmen.

lg
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Cool, werde ich mal probieren. Wäre schön wenn das klappt :)

[edit] trotzdem noch die frage, wie man die datenbank ordentlich neu verbindet. auch wenn o. g. feature funktioniert, möchte ich die möglichkeit, die datenbank neu zu verbinden, in form von buttons anbieten, für den fall dass jemand das programm nutzt, und seine mysql version das reconnect feature noch nicht unterstützt (<5.0.1.3?)
patrikD
Beiträge: 22
Registriert: 21. Mai 2007 14:01

Beitrag von patrikD »

open() und close() werden da nicht helfen. denke du musst die connection wegwerfen über "removeDatabase".
Aber:
Warning: There should be no open queries on the database connection when this function is called, otherwise a resource leak will occur.
Haben damit aber schlechte Erfahrung gemacht. Musst sehr genau darauf achten das alle Queries freigegeben werden, sonst gibts meker, nicht nur ein Speicherleck!
Andere Möglichkeit ist einfach ne neue Connection mit addDataBase zu machen(am besten mit anderem Namen), das dürfte funktionieren und die alte wird serverseitig ja zurückgesetzt und das Qt-Modul kümmert sich um den Speicher der alten.

lg
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Scheint nicht zu klappen. Bekomme immer noch
MySQL server has gone away QMYSQL: Unable to execute query
Der Code:

Code: Alles auswählen

db->setConnectOptions("MYSQL_OPT_RECONNECT=1");
patrikD
Beiträge: 22
Registriert: 21. Mai 2007 14:01

Beitrag von patrikD »

Schade :(
Aber wenn Patrik08 recht hat, dann ist es wohl leider wirklich so, dass QT nur die paar Connection-Parameter unterstützt die in der Doku angegeben sind. Aber vielleicht hilft dir ja der Verbindungs-Check aus dem Thread "Shard mem und MySql".
Aber wenn du ne Lösung finden solltest wäre es toll wenn du sie posten könntest, würde mich auch interessieren.

Lg
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Noch ne Idee. "MYSQL_OPT_RECONNECT=1" gibt es faktisch ja bei MySQL (Link), und wird per
mysql_options()
der MySQL API gesetzt, sofern man direkt die MySQL API verwendet.

Könnte man dann nicht in den Qt Quellen schauen, wo die DB-Verbindung geöffnet wird, und an dieser Stelle hardcoded ein mysql_options() Statement absetzen?
Bleibt nur die Frage ob das QSqlDatabase::setConnectionOptions() nicht bereits selbst macht. Jedenfalls kriege ich bei
QSqlDatabase::setConnectionOptions(MYSQL_OPT_RECONNECT=1)
auf der Konsole den Fehler, dass MYSQL_OPT_RECONNECT keine gültige Option sei, was ja laut Google und Mysql Doku nicht stimmt. D.h. Qt hat ne eigene Liste an gültigen Parametern, und MYSQL_OPT_RECONNECT ist wohl nicht dabei.

Werde mir das heute abend mal anschauen, muss Qt eh nochmal durchkompilieren weil ich demnächst statisch linken möchte.
patrikD
Beiträge: 22
Registriert: 21. Mai 2007 14:01

Beitrag von patrikD »

Hi pfid,

ist tatsächlich so, dass QT die Parameter selbst mapped und das dieser nicht unterstützt wird (siehe "setOptionFlag" in qsql_mysql.cpp).
Das gleiche Problem hab ich gerade auch mit shared-mem connection. Bin gerade bei es einzubauen und wenn es funzt poste ich es.

lg
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

patrikD hat geschrieben: ist tatsächlich so, dass QT die Parameter selbst mapped und das dieser nicht unterstützt wird
Das finde ich aber ziemlich schräg. Wieso wird nicht einfach alles 1:1 durchgereicht und bei Fehler entsprechend reagiert?
Return Values

Zero for success. Non-zero if you specify an unknown option.
Nun denn, vielleicht ist das tatsächlich eine Option. Würde mich freuen wenn das klappt.
patrikD
Beiträge: 22
Registriert: 21. Mai 2007 14:01

Beitrag von patrikD »

fürs autoreconnect ist es relativ simpel:

in der qsql_mysql.cpp:(~zeile 1045)

Code: Alles auswählen

static void setOptionFlag(uint &optionFlags, const QString &opt)
.....
    else if (opt == QLatin1String("MYSQL_OPT_RECONNECT"))
        optionFlags |= MYSQL_OPT_RECONNECT;
    else
        qWarning("QMYSQLDriver::open: Unknown connect option '%s'", opt.toLocal8Bit().constData());
einbauen. Und den mysql plugin neu kompilieren. Den Rest übernimmt das Plugin schon, wenn ich den Code richtig deute. Kanns gerade leider nicht austesten aber feedback wäre toll.

lg
Antworten