課題
研究のデータ収集用に、Slackのアプリを作ったのですが、一定時間経つと使用しているMySQLへの接続が切れてしまい、再起動が必要になったため、原因を調査しました。
- 使用言語・DB・ライブラリ:
- Python3.11.1
- mysql8.0
- SQLAlchemy2.0.15
- 環境:Dockerコンテナ
エラーメッセージ:
Failed to start: (mysql.connector.errors.OperationalError) MySQL Connection not available
[SQL: <SQLクエリ>]
[parameters: [{}]]
(Background on this error at: https://sqlalche.me/e/20/e3q8)
原因
原因は、MySQLが一定時間経つと自動的に接続を切ってしまうことが原因であったようです。
デフォルトでは、28800秒(8時間)のようです。
mysql> SHOW VARIABLES LIKE 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |
+---------------+-------+
1 row in set (0.01 sec)
改善方法
そこで、3600秒(1時間)毎に接続をリサイクルするように変更(pool_recycle=3600
を追加)しました。この変更により、接続が自動的に切断される前に、新しい接続が作られ、常にアクティブな接続が保たれるようになります。
def __init__(self):
db_url = f"mysql+mysqlconnector://{setting.MYSQL_USER}:{setting.MYSQL_PASSWORD}@{setting.MYSQL_HOST}/{setting.MYSQL_DATABASE}"
self.engine = create_engine(db_url, pool_recycle=3600)
self.session_factory = sessionmaker(bind=self.engine, expire_on_commit=False)
self.Session = scoped_session(self.session_factory)
self.create_table()