Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

SQLAlchemyの OperationalError: MySQL Connection not available エラー

Python3.4 && mysql-connector-python2.0.2で起きたこのエラー。

表題の通り、コネクションプールをしているオブジェクトが利用できないと申される。接続は死んでないっぽいのが謎。活きているのに死んでいるみたいな、そんな感じのエラー。MySQL Server has gone awayではないメッセージが返ってきているのが気になる。SQLAlchemyでは活きている(Valid)なコネクションを利用しようとしたら死んでいた可能性もあるから、mysqlのwait_timeout、interactive_timeout系の時間を長くして、flask-sqlalchemyのSQLALCHEMY_POOL_RECYCLEの時間をタイムアウトより小さくしたんだけど、1日おいてもまだこのエラーが消えなかった。

MySQLのコネクション自体は活きているのにSQLAlchemy側でinvalidって判断されるってことは、ドライバの問題じゃねーのと責任転嫁。使ってるドライバがあやC可能性も微レ存ではある。

よって、mysql-connector-python2.0.2からPyMySQLに切り替えてみた。

github.com

このドライバに変えても残念ながらエラーは出るんだけど、エラーのメッセージが変わった。あれ、ドライバ変えたらhas gone awayになっちゃった。死んでるじゃん、MySQLのコネクション。なんでや。

sqlalchemy.exc.OperationalError: (OperationalError) (2006, "MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))")

初心に戻りwait_timoeout系のパラメータを確認した。

mysql> show global variables like '%timeout%';
+----------------------------+----------+
| Variable_name              | Value    |
+----------------------------+----------+
| connect_timeout            | 10       |
| delayed_insert_timeout     | 300      |
| innodb_lock_wait_timeout   | 50       |
| innodb_rollback_on_timeout | OFF      |
| interactive_timeout        | 28800    |
| lock_wait_timeout          | 30       |
| net_read_timeout           | 30       |
| net_write_timeout          | 60       |
| slave_net_timeout          | 3600     |
| wait_timeout               | 28800    |
+----------------------------+----------+

connect_timeoutってのがあるぞ... これっぽいな。デフォルトは10秒。wait_timeoutは最後に接続したコネクションの生き残ることができる秒数っぽい。だんだん良く分からなくなってきたので、connect_timeout,interactive_timeout,wait_timeoutを1日設定(86400秒)に設定し、pool_recycleを3600秒に変更した。

ゴールデンウィーク中に答えが出ると思います。