Ich führe eine Python Pyramid-App auf einem CentOS-Server mit uWSGI und nginx aus. Ich verwende SQLAlchemy als ORM, MySQLdb als API und MySQL als Datenbank. Die Website ist noch nicht online gegangen, daher sind nur ich und einige andere Mitarbeiter des Unternehmens betroffen. Wir haben einige Daten gekauft, um die Datenbank zu füllen, sodass die größte (und am häufigsten abgefragte) Tabelle ~ 150.000 Zeilen umfasst.
Gestern habe ich schnell hintereinander vier neue Registerkarten der Website geöffnet und ein paar 502 Bad Gateway-Fehler erhalten. Ich habe im uWSGI-Protokoll nachgesehen und Folgendes festgestellt:
sqlalchemy.exc.OperationalError: (OperationalError) (2006, 'MySQL server has gone away') 'SELECT ge...
Wichtiger Hinweis: Dieser Fehler ist nicht auf das wait_timeout von MySQL zurückzuführen. Kenne ich schon.
Ich fragte mich, ob das Problem durch gleichzeitige Anfragen verursacht wurde, die gleichzeitig bearbeitet wurden. Ich habe mich zum Lasttester eines armen Mannes gemacht:
for i in {1..10}; do (curl -o /dev/null http://domain.com &); done;
Sicher genug, innerhalb dieser zehn Anfragen würde mindestens eine einen Fehler von 2006 auslösen, oft mehr. Manchmal wurden die Fehler sogar noch seltsamer, zum Beispiel:
sqlalchemy.exc.NoSuchColumnError: "Could not locate column in row for column 'table.id'"
Wenn die Spalte definitiv existiert und bei allen anderen identischen Anforderungen einwandfrei funktioniert hat. Oder dieses:
sqlalchemy.exc.ResourceClosedError: This result object does not return rows. It has been closed automatically.
Als es wieder einmal für alle anderen Anfragen gut funktionierte.
Um weiter zu überprüfen, ob das Problem auf gleichzeitige Datenbankverbindungen zurückzuführen ist, habe ich uWSGI auf einen einzelnen Worker festgelegt und Multithreading deaktiviert, sodass die Anforderungen einzeln verarbeitet werden müssen. Sicher genug, die Probleme verschwanden.
Um das Problem zu finden, habe ich ein Fehlerprotokoll für MySQL eingerichtet. Mit Ausnahme einiger Hinweise beim Start von MySQL bleibt es leer.
Hier ist meine MySQL-Konfiguration:
[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
Starkes Googeln über den Fehler ergab wenig, schlug aber vor, dass ich max_allowed_packet erhöhe. Ich habe es auf 100 Millionen erhöht und MySQL neu gestartet, aber das hat überhaupt nicht geholfen.
Zusammenfassend: Gleichzeitige Verbindungen zu MySQL verursachen 2006, 'MySQL server has gone away'
und einige andere seltsame Fehler. Das MySQL-Fehlerprotokoll enthält keine relevanten Informationen.
Ich habe stundenlang daran gearbeitet und keine Fortschritte gemacht. Kann mir jemand helfen?