- Запросы с "INNER JOIN" без проблем отрабатываются.
Выполняются десятки тысяч точно таких запросов, а потом чик, один раз
2013: Lost connection to MySQL
А потом опять все работает как ни в чем не бывало.
- Ошибка происходит во многих роутах. Но объединяет их одно: во всех их используется "INNER JOIN".
- Если это был бы один или два роута, то можно было бы обернуть в try, но в кучу роутов лезть совершенно не хочется.
- Был у меня еще один проект давно. Но он был мало нагружен и я там просто в жесткую засунул соединение с базой в before_request. А в teardown_request соединение с базой разрывал.
sim3x: Сделал тест - все ок.
Но сайт и так достаточно нагружен, одних только зареганных юзеров 60к.
И там очень много в memcahed и в redis закешированно.
Семь дней продержалось. Семь дней "ни единого обрыва", а сегодня опять двадцать пять.
Все тоже самое в логах. Хотя 7 дней, конечно, прогресс. Раньше 2-3 дня было.
В 2015-05-17 06:48:52 зафиксирована ошибка:
sqlalchemy.exc.InterfaceError: (InterfaceError) 2013: Lost connection
И в это же самое время в логах майсквеля:
150517 6:48:47 [Warning] Aborted connection 65 to db: 'db_name' user: 'db_user' host: 'localhost' (Unknown error)
sim3x: Спасибо.
Установил уровень логирования в дебаг.
Было:
MariaDB [(none)]> show global variables like '%warn%' ;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_warnings | 1 |
| sql_warnings | OFF |
+---------------+-------+
2 rows in set (0.00 sec)
Стало:
MariaDB [(none)]> show global variables like '%warn%' ;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_warnings | 2 |
| sql_warnings | OFF |
+---------------+-------+
2 rows in set (0.00 sec)
===============================
После того как установил новый левел, пришлось сделать рестарт mariadb.
За эти доли секунды пока рестартился mysql нападало тьма сообщений от flask.
sqlalchemy.exc.InterfaceError: (InterfaceError) 2003: Can't connect to MySQL
Но, что интересно код ошибки и сама ошибка немного другая.
Mikhail: Тут все просто. Можно каждый раз при каждом запросе выполнять соединение с базой.
Соединились с базой, забрали через select что-нужно и закрыли соединение. Так в большинстве случаев работает PHP. Ясное дело такой ошибки в этом случае не будет.
В Python и sqlalchemy считают, что это накладно каждый раз соединятся и закрывать. И держат соединение до победного конца. А потом например mysql рестартанул. Соединение во flask перестало работать. Через какие-то секунды flask установил новое соединение.
Но именно в эти секунды и происходит та ошибка, которую я привел.
https://pythonhosted.org/Flask-SQLAlchemy/quicksta...
Name: mysql-connector-python
Version: 2.0.2
Но обновить не дает:
Could not find any downloads that satisfy the requirement mysql-connector-python
Конфиг алхимии всего несколько строк:
app.config['SQLALCHEMY_DATABASE_URI'] \
= 'mysql+mysqlconnector://user:pass@localhost/db?charset=utf8'
app.config['SQLALCHEMY_ECHO'] = True # Показывает sql запросы в дебаге
app.config['SQLALCHEMY_POOL_TIMEOUT'] = 20
app.config['SQLALCHEMY_POOL_SIZE'] = 20
app.config['SQLALCHEMY_POOL_RECYCLE'] = 300
Конфиги марии дефолтные. Я туда не лазил.
Замерил длительность запроса на котором было последнее падение:
1000 rows in set (0.02 sec)
Я уже добавлял строку в my.cnf
net_read_timeout= 180
Может имеет смысл еще увеличить этот параметр?