Wenn wir den MySQL-Dienst verwenden, beträgt die Timeout-Einstellung von MySQL unter normalen Umständen 8 Stunden (28800 Sekunden). Das heißt, wenn eine Verbindung 8 Stunden lang nicht ausgeführt wird, trennt MySQL die Verbindung aktiv. Wenn die Verbindung erneut versucht, eine Abfrage durchzuführen, wird der Fehler „MySQL-Server ist nicht mehr verfügbar“ gemeldet. Aufgrund einiger Einstellungen auf dem MySQL-Server wird das Verbindungstimeout jedoch in vielen Fällen verkürzt, um sicherzustellen, dass mehr Verbindungen verfügbar sind. Manchmal ist die Einstellung abnormal, sehr kurz, 30 Sekunden, sodass der Client einige Vorgänge ausführen muss, um sicherzustellen, dass MySQL die Verbindung nicht aktiv trennt. MySQL-Timeout anzeigen Verwenden Sie das Client-Tool oder das Mysql-Befehlszeilentool, um globale Variablen wie „%timeout%“ einzugeben. Die mit dem Timeout verbundenen Eigenschaften werden dann angezeigt. Hier verwende ich Docker, um eine Testumgebung zu simulieren. mysql> Variablen wie „%timeout%“ anzeigen; +-----------------------------+----------+ | Variablenname | Wert | +-----------------------------+----------+ | Verbindungstimeout | 10 | | verzögertes_Einfügetimeout | 300 | | habe_anweisung_timeout | JA | | innodb_flush_log_at_timeout | 1 | | innodb_lock_wait_timeout | 50 | | innodb_rollback_on_timeout | AUS | | interaktives_Timeout | 30 | | Wartezeit_für_Sperre | 31536000 | | Zeitüberschreitung beim Lesen des Netzes | 30 | | Zeitüberschreitung beim Schreiben von Nachrichten | 60 | | rpl_stop_slave_timeout | 31536000 | | Slave_Net_Timeout | 60 | | Wartezeitüberschreitung | 30 | +-----------------------------+----------+ 13 Reihen im Set wait_timeout: Die Anzahl der Sekunden, die der Server auf Aktivität wartet, bevor eine nicht interaktive Verbindung geschlossen wird. Dies ist die Zeit, in der Sie das Programm in Ihrem Projekt aufrufen. interactive_timeout: Die Anzahl der Sekunden, die der Server auf Aktivität wartet, bevor eine interaktive Verbindung geschlossen wird. Dies ist die Zeit, die Sie für das Öffnen des MySQL-Clients auf Ihrem lokalen Computer benötigen, z. B. cmd. Abfragen mit pymysql Ich habe eine zufällige Tabelle in der Datenbank erstellt und zwei Daten eingefügt mysql> wähle * von Person; +----+------+-----+ | ID | Name | Alter | +----+------+-----+ | 1 | Yang | 18 | | 2 | Ventilator | 16 | +----+------+-----+ 2 Reihen im Set Ich verwende die pymysql-Bibliothek, um es abzufragen, es ist sehr einfach #Kodierung:utf-8 pymysql importieren def mytest(): Verbindung = pymysql.connect( Host = "lokaler Host", Port=3306, Benutzer='root', Passwort='123456', db='meintest', Zeichensatz = "utf8") Cursor = Verbindung.Cursor() cursor.execute("wähle * aus Person aus") Daten = Cursor.fetchall() cursor.schließen() für i in Daten: drucken(i) cursor.schließen() Verbindung.schließen() wenn __name__ == '__main__': meintest() Das richtige Ergebnis erhält man
Abfrage nach Verbindungstimeout Die obigen Ergebnisse können normalerweise erzielt werden, da nach dem Erstellen eines Links sofort eine Abfrage ausgeführt wird und deren Zeitüberschreitungszeitraum nicht überschritten wurde. Wenn ich eine Weile schlafe, werde ich sehen, was die Wirkung ist. #Kodierung:utf-8 pymysql importieren Importzeit def mytest(): Verbindung = pymysql.connect( Host = "lokaler Host", Port=3306, Benutzer='root', Passwort='123456', db='meintest', Zeichensatz = "utf8") Cursor = Verbindung.Cursor() cursor.execute("wähle * aus Person aus") Daten = Cursor.fetchall() für i in Daten: drucken(i) cursor.schließen() Zeit.Schlaf(31) Cursor = Verbindung.Cursor() cursor.execute("wähle * aus Person aus") Daten2 = Cursor.fetchall() für i in data2: drucken(i) cursor.schließen() Verbindung.schließen() wenn __name__ == '__main__': meintest() Hier wurden zwei Abfragen durchgeführt. Da ich das wait_timeout von mysql auf 30 Sekunden eingestellt hatte, hielt ich nach der ersten Abfrage 31 Sekunden an, damit der mysql-Dienst die gerade erstellte Verbindung aktiv trennen konnte. Das Ergebnis war (1, 'Yang', 18) (2, 'Fächer', 16) Traceback (letzter Anruf zuletzt): Datei "F:/python/python3Test/mysqltest.py", Zeile 29, in <module> meintest() Datei "F:/python/python3Test/mysqltest.py", Zeile 22, in mytest cursor.execute("wähle * aus Person aus") ... ... Datei "C:\Python35\lib\site-packages\pymysql\connections.py", Zeile 702, in _read_bytes CR.CR_SERVER_LOST, „Verbindung zum MySQL-Server während der Abfrage verloren“) pymysql.err.OperationalError: (2013, „Verbindung zum MySQL-Server während der Abfrage verloren“) Prozess mit Exitcode 1 beendet Sie können sehen, dass nach einer Pause von 31 Sekunden bei erneuter Verwendung der Verbindung zur Abfrage der Fehler 2013 „Verbindung zum MySQL-Server während der Abfrage verloren“ ausgegeben wird. Lösung Es gibt zwei Lösungen. Da das Timeout hier auf keine Operation innerhalb der angegebenen Zeit zurückzuführen ist, schließt MySQL die Verbindung aktiv. Das pymysql-Verbindungsobjekt verfügt über eine Ping()-Methode, um zu prüfen, ob die Verbindung gültig ist. Führen Sie die Ping()-Methode vor jeder Abfrageoperation aus. Diese Methode verfügt standardmäßig über einen Reconnect-Parameter, der standardmäßig True ist. Wenn die Verbindung verloren geht, wird sie wiederhergestellt. #Kodierung:utf-8 pymysql importieren Importzeit def mytest(): Verbindung = pymysql.connect( Host = "lokaler Host", Port=3306, Benutzer='root', Passwort='123456', db='meintest', Zeichensatz = "utf8") Verbindung.ping() Cursor = Verbindung.Cursor() cursor.execute("wähle * aus Person aus") Daten = Cursor.fetchall() für i in Daten: drucken(i) cursor.schließen() Zeit.Schlaf(31) Verbindung.ping() Cursor = Verbindung.Cursor() cursor.execute("wähle * aus Person aus") Daten2 = Cursor.fetchall() für i in data2: drucken(i) cursor.schließen() Verbindung.schließen() wenn __name__ == '__main__': meintest() Ich habe versucht, den Ping()-Vorgang mithilfe eines anderen Threads kontinuierlich auszuführen, dabei geht jedoch die Verbindung verloren und nachfolgende Vorgänge können nicht ausgeführt werden. Ich werde dieses Problem weiter untersuchen. #Kodierung:utf-8 pymysql importieren Importzeit Threading importieren Traceback importieren def ping(Verbindung): während True: versuchen: conn.ping() außer: drucken(traceback.format_exc()) Endlich: Zeit.Schlaf(1) def mytest(): Verbindung = pymysql.connect( Host = "lokaler Host", Port=3306, Benutzer='root', Passwort='123456', db='meintest', Zeichensatz = "utf8") Cursor = Verbindung.Cursor() # Das funktioniert hier nicht. Sie müssen warten, bis der Cursor ausgeführt wird, bevor Sie es ausführen können. # th = threading.Thread(target=ping, args=(connection,)) # th.setDaemon(True) # th.start() cursor.execute("wähle * aus Person aus") Daten = Cursor.fetchall() für i in Daten: drucken(i) cursor.schließen() # Der Thread kann hier gestartet werden th = threading.Thread(target=ping, args=(connection,)) th.setDaemon(True) th.start() Zeit.Schlaf(31) Cursor = Verbindung.Cursor() cursor.execute("wähle * aus Person aus") Daten2 = Cursor.fetchall() für i in data2: drucken(i) cursor.schließen() Verbindung.schließen() wenn __name__ == '__main__': meintest() Eine andere Methode besteht darin, einen Verbindungspool zu verwenden, der eine bestimmte Anzahl verfügbarer Verbindungen beibehält und bei jeder Abfrage eine gültige Verbindung erneut abruft. Pymysql selbst verfügt nicht über eine Verbindungspoolfunktion, daher müssen Sie DBUtils verwenden. #Kodierung:utf-8 pymysql importieren Importzeit von DBUtils.PooledDB importiere PooledDB, SharedDBConnection def mytest(): Pool = GepoolterDB( Ersteller=pymysql, # Beim Initialisieren erstellt der Verbindungspool mindestens Leerlaufverbindungen, 0 bedeutet keine Erstellung maxconnections=3, # Die maximale Anzahl inaktiver Verbindungen im Verbindungspool. 0 und Keine bedeuten keine Begrenzung. mincached=2, # Die maximale Anzahl gemeinsam genutzter Verbindungen im Verbindungspool. 0 und Keine bedeuten, dass alle gemeinsam genutzt werden (was eigentlich nutzlos ist). maxcached=5, maxshared=3, Host = "lokaler Host", Port=3306, Benutzer='root', Passwort='123456', db='meintest', Zeichensatz = "utf8" ) Verbindung = Pool.Verbindung() Cursor = Verbindung.Cursor() cursor.execute("wähle * aus Person aus") Daten = Cursor.fetchall() für i in Daten: drucken(i) Zeit.Schlaf(40) cursor.execute("wähle * aus Person aus") Daten2 = Cursor.fetchall() für i in data2: drucken(i) cursor.schließen() Verbindung.schließen() wenn __name__ == '__main__': meintest() Obwohl diese Methode die Ergebnisse korrekt abrufen kann, wird sie in tatsächlichen Projekten nicht verwendet. Stattdessen sollte die Verbindung geschlossen werden, nachdem die Abfrageanweisung ausgeführt wurde. Beachten Sie, dass das Schließen hier kein echtes Schließen ist, sondern nur die Verbindung an den Verbindungspool zurückgibt, damit andere sie verwenden können. #Kodierung:utf-8 pymysql importieren Importzeit von DBUtils.PooledDB importiere PooledDB, SharedDBConnection def mytest(): Pool = GepoolterDB( Ersteller=pymysql, maxVerbindungen=3, # Beim Initialisieren erstellt der Verbindungspool mindestens Leerlaufverbindungen, 0 bedeutet kein mincached=2, # Die maximale Anzahl inaktiver Verbindungen im Verbindungspool. 0 und Keine bedeuten keine Begrenzung. maxcached=5, # Die maximale Anzahl gemeinsam genutzter Verbindungen im Verbindungspool. 0 und Keine bedeuten, dass alle gemeinsam genutzt werden (was eigentlich nutzlos ist). maxshared=3, Host = "lokaler Host", Port=3306, Benutzer='root', Passwort='123456', db='meintest', Zeichensatz = "utf8" ) Verbindung = Pool.Verbindung() Cursor = Verbindung.Cursor() cursor.execute("wähle * aus Person aus") Daten = Cursor.fetchall() für i in Daten: drucken(i) cursor.schließen() # Durch das Schließen der Verbindung wird diese nicht wirklich geschlossen, sondern nur die Verbindung wird an den Verbindungspool zurückgegeben connection.close() Zeit.Schlaf(40) Verbindung = Pool.Verbindung() Cursor = Verbindung.Cursor() cursor.execute("wähle * aus Person aus") Daten2 = Cursor.fetchall() für i in data2: drucken(i) cursor.schließen() Verbindung.schließen() wenn __name__ == '__main__': meintest() Der obige Artikel zur Lösung des Problems, dass der MySQL-Server aktiv getrennt wird, wenn kein Betriebstimeout vorliegt, ist der gesamte Inhalt, den der Herausgeber mit Ihnen teilt. Ich hoffe, er kann Ihnen als Referenz dienen, und ich hoffe auch, dass Sie 123WORDPRESS.COM unterstützen. Das könnte Sie auch interessieren:
|
<<: Eine kurze Diskussion über die Lösung für übermäßige Daten in ElementUI el-select
html Code kopieren Der Code lautet wie folgt: <...
Inhaltsverzeichnis Was sind flaches und tiefes Kl...
1. Einleitung Ich möchte Selenium verwenden, um D...
Vorwort In diesem Artikel verwenden wir Docker, u...
In diesem Artikelbeispiel wird der spezifische Co...
Normalerweise besteht das Ziel beim Erstellen ein...
Schauen Sie sich zuerst den Code und die Wirkung ...
Inhaltsverzeichnis Einführung in den Samba-Server...
Grundlegende Einführung in robots.txt Robots.txt i...
Inhaltsverzeichnis Grundlegende Datenbankvorgänge...
Bei der tatsächlichen Arbeit oder bei Interviews ...
Die Wiederverwendung von Code in Vue liefert uns ...
Bibliotheksverwaltung Erstellen einer Bibliothek ...
Inhaltsverzeichnis 1. Komponenteneinführung 2. Qu...
Inhaltsverzeichnis Einführung Warum die Mühe? Com...