aobako.net
aiomysql のコネクションプールで古いコネクションを削除する
July 14, 2020
responder などの ASGI アプリケーションからデータベースを参照するのに必要なノンブロッキング IO を持つ aiomysql だが,コネクションプールを使用して少々ハマった箇所があったのでメモしておく.
コネクションのリサイクル
特に指定がない (wait_timeout=28800) 場合,MySQL サーバーの設定によって,プールされた無通信 (sleep) 状態のコネクションは,8 時間待機したあとに切断される.スパイク後の大量のコネクションを抱えとくのも嫌だが,サーバー主導でコネクションを切られて,タイミング悪く切断されたコネクションを掴まされるのも困る.
ということで,クライアント主導でコネクションを切れないものかと調べていたら,create_pool
の引数に pool_recycle
なるオプションがあることに気付いた.ここで指定した期間利用されなかったコネクションはクライアント側でクローズしてくれるようだ (デフォルトの -1 は何もしない).クローズのタイミングは acquire
を呼んだタイミングで,コネクションを払い出す前に消している模様.このとき,利用可能なコネクション数が minsize 未満になるときは,新しく補充してくれる.
このオプション,ドキュメントに書いてないんだよね...
暗黙トランザクション
これは aiomysql というか MySQL の話だが,単なる SELECT でもトランザクションが開始されるので,データの更新を行わない場合でも,しっかりと commit / rollback をしておく必要がある.でないとトランザクションが開いたままプーリングされてしまい,別トランザクションで更新したデータが反映されなくなってしまう.
autocommit=True
とするのも手だが,個人的には自分でトランザクションの面倒をみた方が安心感がある.