LoginSignup
3
2

More than 5 years have passed since last update.

GAE/py + SQLAlchemyで "2062, Cloud SQL socket open failed"

Posted at

エラー遭遇

Google AppEngine Standard Environmentにデプロイしている、
pythonのサーバからCloud SQLへSQLAlchemyを用いて接続していましたが、
単発での接続では問題がなかったのに、連続稼働していると、以下のようなエラーが起きました。

OperationalError: (_mysql_exceptions.OperationalError) (2062, 'Cloud SQL socket open failed with error: Transport endpoint is not connected')

SQLAlchemyのエラーはSQLAlchemyのエラー回避備忘録などが大変参考になりましたが、該当するエラーはありませんでした。
というか、Cloud SQLと言っているのでGCP上でのエラーと思われます。

発生箇所はConnectionを貼るところでした。
taskを分割して別スレッドで連続して作業していると、突然コネクションが貼れなくなるようです。

スクリーンショット 2018-02-27 12.00.57.png

こんな感じでした。

解決方法

検索するとすぐに出てくるのですが、とても簡単な話で、SQLサーバへの接続がスレッドごとにきちんとcloseされていないためでした。

コメントが違うエラーでしたが中身は同じで、12個以上のコネクションを同時に張ってはいけないようです。
FAQにもちゃんと記載がありました。

スタンダード環境で動作する各 App Engine インスタンスは、Google Cloud SQL インスタンスに対する同時接続数が最大 12 個に制限されます。

SQLAlchemyでの切断

SQLAlchemyで、query等にSessionを使っていました。
sessionオブジェクトにもcloseがあるのですが、これは厳密にはConnectionと対応していないようで、
sessionをcloseしてるにもかかわらず、相変わらずエラーが起きていました。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine(url, encoding='utf8', echo=False)
Session = sessionmaker(bind=engine)
session = Session()
...
# ちゃんとcloseしていてもエラーが起きる
session.close()

SQLAlchemyではConnectionのPoolが使用されていて、connectionを再利用するため?にpool内で接続が維持されるようです。

上のスレッドで紹介されていましたが、単発で使って、別スレッド等でコネクションを共有されないような場合ではpoolをdisableにすれば、毎回connectionがcloseされるようです。
disableにする最も簡単な方法はengineを作るときにNullPoolを指定することです。

from sqlalchemy.pool import NullPool
# poolclassにNullPoolを指定するとpoolがdisableになる
engine = create_engine(url, poolclass=NullPool)
Session = sessionmaker(bind=engine)
session = Session()
...
# エラーが起きなくなった!
session.close()

他にも方法があるかと思いますが、今回はこのような対処をしました。
SQLAlchemyを使っていれば常識なのかもしれませんね、、以上です。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2