(2006, 'MySQL server has gone away') in WS

2019-04-07 08:34发布

问题:

I have a MySQL gone away with Django under WSGI. I found entries for this problem on stackoverflow, but nothing with Django specifically. Google does not help, except for workarounds (like polling the website every once in a while, or increasing the database timeout). Nothing definitive. Technically, Django and/or MySQLdb (I'm using the latest 1.2.3c1) should attempt a reconnect if the server hanged the connection, but this does not happen. How can I solve this issue without workarounds ?

回答1:

show variables like 'wait_timeout';

this is the setting will throw back the "mysql gone away" error
set it to a very large value to prevent it "gone away"
or simple re-ping the mysql connection after certain period



回答2:

  • You could create middleware to ping() the MySQL connection (which will reconnect if it timed out) before processing the view

  • You could also add middleware to catch the exception, reconnect, and retry the view (I think I would prefer the above solution as simpler, but it should technically work and be performant assuming timeouts are rare. This also assumes a failed view has no side effects, which is a desirable property but can be difficult to do, especially if you write to a filesystem as well as a db in your view.)



回答3:

Django developers gave one short answer for all questions like this in https://code.djangoproject.com/ticket/21597#comment:29

  • Resolution set to wontfix

Actually this is the intended behavior after #15119. See that ticket for the rationale.

If you hit this problem and don't want to understand what's going on, don't reopen this ticket, just do this:

  • RECOMMENDED SOLUTION: close the connection with from django.db import connection; connection.close() when you know that your program is going to be idle for a long time.

  • CRAPPY SOLUTION: increase wait_timeout so it's longer than the maximum idle time of your program.

In this context, idle time is the time between two successive database queries.