web-dev-qa-db-fra.com

Pourquoi le connecteur mysql est-il endommagé (erreur "Connexion perdue au serveur MySQL lors de l'interrogation")

Lorsque j'exécute des requêtes volumineuses (des requêtes renvoyant plusieurs lignes), l'erreur Lost connection to MySQL server during query s'affiche et je ne vois pas ce que je fais mal. J'utilise le "nouveau" pilote mysql de mysql.com (pas le "vieux" MySQLdb), ainsi que la version de mysql fournie avec MAMP. Python 2.7. La table n'est pas corrompue, analyze table nrk2013b_tbl; renvoie le statut ok. Voici un exemple qui casse:

#!/usr/bin/python2.7
# coding: utf-8

import sys
import mysql.connector # version 2.0.1

connection = mysql.connector.connect(
                    unix_socket="/Applications/MAMP/tmp/mysql/mysql.sock",
                     user="dbUsernam",
                      passwd="dbUserPassword",
                      db="nrk",
                      charset = "utf8",
                      use_unicode = True)
cur = connection.cursor()
cur.execute("USE nrk;")


sql = """SELECT id FROM nrk2013b_tbl WHERE main_news_category = 'Sport'"""
cur.execute(sql)
rows = cur.fetchall()

print rows

sys.exit(0)

Cela entraîne l'erreur que je reçois la plupart du temps:

Traceback (most recent call last):
  File "train_trainer_test.py", line 20, in <module>
    remaining_rows = cur.fetchall()
  File "/Library/Python/2.7/site-packages/mysql/connector/cursor.py", line 823, in fetchall
    (rows, eof) = self._connection.get_rows()
  File "/Library/Python/2.7/site-packages/mysql/connector/connection.py", line 669, in get_rows
    rows = self._protocol.read_text_result(self._socket, count)
  File "/Library/Python/2.7/site-packages/mysql/connector/protocol.py", line 309, in read_text_result
    packet = sock.recv()
  File "/Library/Python/2.7/site-packages/mysql/connector/network.py", line 226, in recv_plain
    raise errors.InterfaceError(errno=2013)
mysql.connector.errors.InterfaceError: 2013: Lost connection to MySQL server during query

La ligne 20 est la rows = cur.fetchall()

Si je limite la requête à moins de résultat, SELECT id FROM nrk2013b_tbl WHERE main_news_category = 'Sport' LIMIT 10, tout va bien. Mais je veux travailler avec des ensembles de résultats plus importants. Pour résoudre un problème ad-hoc, j'ai déplacé la limite et décomposé les données que je voulais en lots plus petits, mais cela continue à apparaître comme un problème. 

Afin de prendre en compte connect-timeout, max_allowed_packet, etc., j'ai ce fichier my.cnf: File: /Applications/MAMP/conf/my.cnf 

[mysqld]
max_allowed_packet = 64M
wait_timeout = 28800
interactive_timeout = 28800
connect-timeout=31536000

Cela ne semble pas faire de différence (je ne suis même pas sûr que mysql reconnaisse ces paramètres). Lorsque j'exécute des requêtes à partir du terminal ou de Sequel Pro, cela fonctionne correctement. Ce n'est que via le mysql.connector de python que je reçois ces erreurs. 

Des idées? 

PS: J'ai temporairement abandonné cela et changé pour PyMySQL au lieu de Oracle mysql.connector. En changeant cela, les problèmes semblent disparaître (et je conclus moi-même que le problème réside dans le connecteur Oracle mysql). 

import pymysql
conn = pymysql.connect(
                    unix_socket="/Applications/MAMP/tmp/mysql/mysql.sock",
                     user="dbUsernam",
                      passwd="dbUserPassword",
                      db="nrk",
                      charset = "utf8",
                      use_unicode = True)
conn.autocommit(True) # this I 
cur = conn.cursor()
12
Eiriks

J'ai également dû passer à PyMySQL. J'exécute le pip 1.5.6, Python 2.7.8 et j'ai essayé mysql-connector 2.0.1

J'ai pu exécuter la requête à partir de Sequel Pro sans aucun problème, mais ma requête Python échouait avec l'erreur décrite dans la question après le renvoi d'un sous-ensemble de résultats.

Basculé vers PyMySQL et tout fonctionne comme prévu.

https://github.com/PyMySQL/PyMySQL

Dans le virtuel:

pip install pymysql

Dans le code: 

import pymysql

connection = pymysql.connect(user='x', passwd='x',
                                 Host='x',
                                 database='x')

cursor = connection.cursor()

query = ("MYQUERY")

cursor.execute(query)

for item in cursor:
    print item

Certainement un bug dans mysql-connector-python.

12
sheldonkreger

Essayez d'augmenter votre net_read_timeout (probablement une valeur par défaut de 30 secondes est trop petite dans votre scénario)

Ref:

net_read_timeout

et en général:

B.5.2.3 Perte de connexion au serveur MySQL

3
Cristian Porta

J'ai rencontré des problèmes similaires aussi. Dans mon cas, cela a été résolu en plaçant le curseur de la manière suivante:

cur = connection.cursor(buffered=True)
1
user6938211

Ressemble à un bogue dans MySQL Connector/Python: http://bugs.mysql.com/bug.php?id=74483

Devrait être corrigé dans 2.0.3 , qui n'est pas encore publié.

1
Che

Développer la réponse de Christian. Le délai d'expiration des requêtes de lecture (select) est défini par net_write_timeout . C'est une "écriture" du point de vue du serveur.

0
codebard