J'exécute une application Python Pyramid sur un serveur CentOS en utilisant uWSGI et nginx. J'utilise SQLAlchemy comme ORM, MySQLdb comme API et MySQL comme base de données. Le site n'est pas encore en ligne, donc le seul trafic est moi et quelques autres employés de l'entreprise. Nous avons acheté des données pour remplir la base de données, de sorte que la table la plus grande (et la plus fréquemment interrogée) est d'environ 150 000 lignes.
Hier, j'ai ouvert quatre nouveaux onglets du site Web en succession rapide et j'ai récupéré quelques erreurs 502 Bad Gateway. J'ai regardé dans le journal uWSGI et j'ai trouvé ce qui suit:
sqlalchemy.exc.OperationalError: (OperationalError) (2006, 'MySQL server has gone away') 'SELECT ge...
Remarque importante: cette erreur n'est pas due au délai d'attente de MySQL. J'y suis allé, j'ai fait ça.
Je me demandais si le problème était dû à des demandes simultanées traitées simultanément. Je me suis fait un testeur de charge de pauvre:
for i in {1..10}; do (curl -o /dev/null http://domain.com &); done;
Effectivement, dans ces dix demandes, au moins une entraînerait une erreur de 2006, souvent plus. Parfois, les erreurs devenaient encore plus étranges, par exemple:
sqlalchemy.exc.NoSuchColumnError: "Could not locate column in row for column 'table.id'"
Quand la colonne existe très certainement et a bien fonctionné sur toutes les autres demandes identiques. Ou, celui-ci:
sqlalchemy.exc.ResourceClosedError: This result object does not return rows. It has been closed automatically.
Quand, encore une fois, cela a bien fonctionné pour toutes les autres demandes.
Pour vérifier davantage que le problème provient de connexions de base de données simultanées, j'ai défini uWSGI sur un seul travailleur et le multithreading désactivé, forçant les demandes à être traitées une par une. Effectivement, les problèmes ont disparu.
Pour tenter de trouver le problème, j'ai configuré un journal des erreurs pour MySQL. À l'exception de certains avis lors du démarrage de MySQL, il reste vide.
Voici ma configuration MySQL:
[mysqld]
default-storage-engine = myisam
key_buffer = 1M
query_cache_size = 1M
query_cache_limit = 128k
max_connections=25
thread_cache=1
skip-innodb
query_cache_min_res_unit=0
tmp_table_size = 1M
max_heap_table_size = 1M
table_cache=256
concurrent_insert=2
max_allowed_packet = 1M
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 64K
innodb_file_per_table=1
log-error=/var/log/mysql/error.log
Une recherche intensive sur l'erreur a révélé peu, mais a suggéré que j'augmente max_allowed_packet. Je l'ai augmenté à 100M et redémarré MySQL, mais cela n'a pas aidé du tout.
Pour résumer: les connexions simultanées à la cause MySQL 2006, 'MySQL server has gone away'
et quelques autres erreurs étranges. Il n'y a rien de pertinent dans le journal des erreurs de MySQL.
J'y travaille depuis des heures et je n'ai fait aucun progrès. Quelqu'un peut-il m'aider?